summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-02-16 09:30:23 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-02-16 09:30:23 +0000
commitf25ddd991a5601d0101602c4c263a58c7af4b8a2 (patch)
tree4cfca640904d1896e25032757a61f8959c066919
parent3fd58f91dd318518f7daa4ba64c0aaf31799d89b (diff)
downloadFreeBSD-src-f25ddd991a5601d0101602c4c263a58c7af4b8a2.zip
FreeBSD-src-f25ddd991a5601d0101602c4c263a58c7af4b8a2.tar.gz
Update LLVM to r96341.
-rw-r--r--Makefile.rules27
-rw-r--r--README.txt1
-rw-r--r--autoconf/configure.ac31
-rw-r--r--autoconf/m4/path_tclsh.m44
-rw-r--r--bindings/ocaml/llvm/llvm.ml3
-rw-r--r--bindings/ocaml/llvm/llvm.mli9
-rw-r--r--bindings/ocaml/llvm/llvm_ocaml.c11
-rwxr-xr-xconfigure15776
-rw-r--r--docs/CommandGuide/lit.pod8
-rw-r--r--docs/CommandGuide/llvm-extract.pod8
-rw-r--r--docs/ExceptionHandling.html21
-rw-r--r--docs/GettingStarted.html14
-rw-r--r--docs/LangRef.html153
-rw-r--r--docs/ProgrammersManual.html41
-rw-r--r--docs/ReleaseNotes.html518
-rw-r--r--docs/WritingAnLLVMBackend.html10
-rw-r--r--docs/index.html10
-rw-r--r--docs/tutorial/LangImpl1.html2
-rw-r--r--docs/tutorial/LangImpl2.html2
-rw-r--r--docs/tutorial/LangImpl3.html2
-rw-r--r--docs/tutorial/LangImpl4.html49
-rw-r--r--docs/tutorial/LangImpl5.html18
-rw-r--r--docs/tutorial/LangImpl6.html18
-rw-r--r--docs/tutorial/LangImpl7.html18
-rw-r--r--docs/tutorial/LangImpl8.html2
-rw-r--r--docs/tutorial/OCamlLangImpl1.html2
-rw-r--r--docs/tutorial/OCamlLangImpl2.html2
-rw-r--r--docs/tutorial/OCamlLangImpl3.html2
-rw-r--r--docs/tutorial/OCamlLangImpl4.html2
-rw-r--r--docs/tutorial/OCamlLangImpl5.html2
-rw-r--r--docs/tutorial/OCamlLangImpl6.html2
-rw-r--r--docs/tutorial/OCamlLangImpl7.html2
-rw-r--r--examples/BrainF/BrainFDriver.cpp1
-rw-r--r--examples/CMakeLists.txt4
-rw-r--r--examples/ExceptionDemo/CMakeLists.txt5
-rw-r--r--examples/ExceptionDemo/ExceptionDemo.cpp2028
-rw-r--r--examples/ExceptionDemo/Makefile17
-rw-r--r--examples/Fibonacci/fibonacci.cpp1
-rw-r--r--examples/HowToUseJIT/HowToUseJIT.cpp3
-rw-r--r--examples/Kaleidoscope/Chapter4/Makefile2
-rw-r--r--examples/Kaleidoscope/Chapter4/toy.cpp16
-rw-r--r--examples/Kaleidoscope/Chapter5/Makefile2
-rw-r--r--examples/Kaleidoscope/Chapter5/toy.cpp16
-rw-r--r--examples/Kaleidoscope/Chapter6/Makefile2
-rw-r--r--examples/Kaleidoscope/Chapter6/toy.cpp16
-rw-r--r--examples/Kaleidoscope/Chapter7/Makefile3
-rw-r--r--examples/Kaleidoscope/Chapter7/toy.cpp16
-rw-r--r--examples/Makefile4
-rw-r--r--examples/ParallelJIT/ParallelJIT.cpp1
-rw-r--r--include/llvm-c/Core.h151
-rw-r--r--include/llvm-c/EnhancedDisassembly.h515
-rw-r--r--include/llvm/ADT/BitVector.h10
-rw-r--r--include/llvm/ADT/DenseMap.h2
-rw-r--r--include/llvm/ADT/DenseSet.h4
-rw-r--r--include/llvm/ADT/ImmutableIntervalMap.h238
-rw-r--r--include/llvm/ADT/ImmutableMap.h5
-rw-r--r--include/llvm/ADT/ImmutableSet.h21
-rw-r--r--include/llvm/ADT/SmallBitVector.h42
-rw-r--r--include/llvm/ADT/SmallPtrSet.h2
-rw-r--r--include/llvm/ADT/Triple.h1
-rw-r--r--include/llvm/Analysis/ConstantFolding.h2
-rw-r--r--include/llvm/Analysis/DebugInfo.h20
-rw-r--r--include/llvm/Analysis/IVUsers.h101
-rw-r--r--include/llvm/Analysis/InlineCost.h25
-rw-r--r--include/llvm/Analysis/LoopInfo.h4
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h2
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h20
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h15
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h112
-rw-r--r--include/llvm/Assembly/AsmAnnotationWriter.h21
-rw-r--r--include/llvm/Attributes.h31
-rw-r--r--include/llvm/Bitcode/Archive.h21
-rw-r--r--include/llvm/Bitcode/BitstreamWriter.h2
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h3
-rw-r--r--include/llvm/Bitcode/ReaderWriter.h9
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h114
-rw-r--r--include/llvm/CodeGen/DAGISelHeader.h279
-rw-r--r--include/llvm/CodeGen/DwarfWriter.h4
-rw-r--r--include/llvm/CodeGen/FileWriters.h37
-rw-r--r--include/llvm/CodeGen/JITCodeEmitter.h2
-rw-r--r--include/llvm/CodeGen/LiveInterval.h2
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h9
-rw-r--r--include/llvm/CodeGen/MachineCodeEmitter.h2
-rw-r--r--include/llvm/CodeGen/MachineConstantPool.h2
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h16
-rw-r--r--include/llvm/CodeGen/MachineFunction.h43
-rw-r--r--include/llvm/CodeGen/MachineFunctionAnalysis.h3
-rw-r--r--include/llvm/CodeGen/MachineInstr.h49
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h4
-rw-r--r--include/llvm/CodeGen/MachineJumpTableInfo.h53
-rw-r--r--include/llvm/CodeGen/MachineMemOperand.h11
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h41
-rw-r--r--include/llvm/CodeGen/MachineModuleInfoImpls.h48
-rw-r--r--include/llvm/CodeGen/MachineOperand.h18
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h32
-rw-r--r--include/llvm/CodeGen/MachineRelocation.h5
-rw-r--r--include/llvm/CodeGen/ObjectCodeEmitter.h2
-rw-r--r--include/llvm/CodeGen/Passes.h4
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h23
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h31
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h5
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h20
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h202
-rw-r--r--include/llvm/CodeGen/ValueTypes.h5
-rw-r--r--include/llvm/Config/config.h.in38
-rw-r--r--include/llvm/Constant.h3
-rw-r--r--include/llvm/Constants.h63
-rw-r--r--include/llvm/DerivedTypes.h62
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h98
-rw-r--r--include/llvm/GVMaterializer.h66
-rw-r--r--include/llvm/GlobalValue.h37
-rw-r--r--include/llvm/InlineAsm.h2
-rw-r--r--include/llvm/InstrTypes.h79
-rw-r--r--include/llvm/Instruction.h2
-rw-r--r--include/llvm/Instructions.h12
-rw-r--r--include/llvm/Intrinsics.h6
-rw-r--r--include/llvm/Intrinsics.td1
-rw-r--r--include/llvm/Linker.h2
-rw-r--r--include/llvm/MC/MCAsmInfo.h56
-rw-r--r--include/llvm/MC/MCAssembler.h211
-rw-r--r--include/llvm/MC/MCCodeEmitter.h41
-rw-r--r--include/llvm/MC/MCDirectives.h36
-rw-r--r--include/llvm/MC/MCExpr.h51
-rw-r--r--include/llvm/MC/MCFixup.h108
-rw-r--r--include/llvm/MC/MCInstPrinter.h18
-rw-r--r--include/llvm/MC/MCParser/AsmParser.h4
-rw-r--r--include/llvm/MC/MCStreamer.h42
-rw-r--r--include/llvm/MC/MCSymbol.h2
-rw-r--r--include/llvm/Metadata.h5
-rw-r--r--include/llvm/Module.h55
-rw-r--r--include/llvm/ModuleProvider.h88
-rw-r--r--include/llvm/Pass.h10
-rw-r--r--include/llvm/PassManager.h13
-rw-r--r--include/llvm/PassManagers.h4
-rw-r--r--include/llvm/Support/Casting.h5
-rw-r--r--include/llvm/Support/CommandLine.h2
-rw-r--r--include/llvm/Support/ConstantFolder.h12
-rw-r--r--include/llvm/Support/Dwarf.h1
-rw-r--r--include/llvm/Support/FormattedStream.h4
-rw-r--r--include/llvm/Support/IRBuilder.h25
-rw-r--r--include/llvm/Support/IRReader.h39
-rw-r--r--include/llvm/Support/MachO.h56
-rw-r--r--include/llvm/Support/NoFolder.h12
-rw-r--r--include/llvm/Support/PatternMatch.h16
-rw-r--r--include/llvm/Support/SourceMgr.h42
-rw-r--r--include/llvm/Support/TargetFolder.h12
-rw-r--r--include/llvm/Support/TypeBuilder.h6
-rw-r--r--include/llvm/System/DynamicLibrary.h2
-rw-r--r--include/llvm/System/Path.h2
-rw-r--r--include/llvm/System/Program.h6
-rw-r--r--include/llvm/Target/Mangler.h2
-rw-r--r--include/llvm/Target/Target.td30
-rw-r--r--include/llvm/Target/TargetAsmLexer.h10
-rw-r--r--include/llvm/Target/TargetData.h5
-rw-r--r--include/llvm/Target/TargetInstrInfo.h57
-rw-r--r--include/llvm/Target/TargetLowering.h65
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h182
-rw-r--r--include/llvm/Target/TargetMachOWriterInfo.h112
-rw-r--r--include/llvm/Target/TargetMachine.h212
-rw-r--r--include/llvm/Target/TargetOpcodes.h72
-rw-r--r--include/llvm/Target/TargetOptions.h11
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h6
-rw-r--r--include/llvm/Target/TargetRegistry.h36
-rw-r--r--include/llvm/Transforms/IPO/InlinerPass.h7
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h3
-rw-r--r--include/llvm/Transforms/Utils/Local.h5
-rw-r--r--include/llvm/Type.h58
-rw-r--r--include/llvm/Value.h10
-rw-r--r--include/llvm/ValueSymbolTable.h11
-rw-r--r--lib/Analysis/ConstantFolding.cpp46
-rw-r--r--lib/Analysis/DebugInfo.cpp59
-rw-r--r--lib/Analysis/IPA/GlobalsModRef.cpp2
-rw-r--r--lib/Analysis/IPA/Makefile1
-rw-r--r--lib/Analysis/IVUsers.cpp176
-rw-r--r--lib/Analysis/InlineCost.cpp80
-rw-r--r--lib/Analysis/LiveValues.cpp2
-rw-r--r--lib/Analysis/Makefile1
-rw-r--r--lib/Analysis/MemoryBuiltins.cpp4
-rw-r--r--lib/Analysis/ScalarEvolution.cpp480
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp152
-rw-r--r--lib/Analysis/ValueTracking.cpp41
-rw-r--r--lib/Archive/Archive.cpp43
-rw-r--r--lib/Archive/ArchiveInternals.h10
-rw-r--r--lib/Archive/ArchiveReader.cpp41
-rw-r--r--lib/Archive/ArchiveWriter.cpp12
-rw-r--r--lib/Archive/Makefile1
-rw-r--r--lib/AsmParser/LLLexer.cpp2
-rw-r--r--lib/AsmParser/LLParser.cpp146
-rw-r--r--lib/AsmParser/LLParser.h5
-rw-r--r--lib/AsmParser/LLToken.h2
-rw-r--r--lib/AsmParser/Makefile1
-rw-r--r--lib/Bitcode/Reader/BitReader.cpp31
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp160
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h37
-rw-r--r--lib/Bitcode/Reader/Makefile1
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp66
-rw-r--r--lib/Bitcode/Writer/Makefile1
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp14
-rw-r--r--lib/CodeGen/AggressiveAntiDepBreaker.cpp7
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp730
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp1
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp104
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h8
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp195
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h9
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.cpp70
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.h17
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfWriter.cpp4
-rw-r--r--lib/CodeGen/AsmPrinter/Makefile1
-rw-r--r--lib/CodeGen/BranchFolding.cpp97
-rw-r--r--lib/CodeGen/CMakeLists.txt3
-rw-r--r--lib/CodeGen/CalcSpillWeights.cpp7
-rw-r--r--lib/CodeGen/CodePlacementOpt.cpp4
-rw-r--r--lib/CodeGen/DeadMachineInstructionElim.cpp33
-rw-r--r--lib/CodeGen/ELFCodeEmitter.cpp7
-rw-r--r--lib/CodeGen/ELFWriter.cpp10
-rw-r--r--lib/CodeGen/ExactHazardRecognizer.cpp2
-rw-r--r--lib/CodeGen/GCStrategy.cpp2
-rw-r--r--lib/CodeGen/IntrinsicLowering.cpp4
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp210
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp59
-rw-r--r--lib/CodeGen/LiveVariables.cpp9
-rw-r--r--lib/CodeGen/LowerSubregs.cpp12
-rw-r--r--lib/CodeGen/MachOWriter.cpp125
-rw-r--r--lib/CodeGen/MachOWriter.h88
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp22
-rw-r--r--lib/CodeGen/MachineFunction.cpp112
-rw-r--r--lib/CodeGen/MachineFunctionAnalysis.cpp2
-rw-r--r--lib/CodeGen/MachineInstr.cpp31
-rw-r--r--lib/CodeGen/MachineLICM.cpp4
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp2
-rw-r--r--lib/CodeGen/MachineModuleInfoImpls.cpp15
-rw-r--r--lib/CodeGen/MachineSSAUpdater.cpp17
-rw-r--r--lib/CodeGen/MachineSink.cpp5
-rw-r--r--lib/CodeGen/MachineVerifier.cpp10
-rw-r--r--lib/CodeGen/Makefile1
-rw-r--r--lib/CodeGen/OptimizeExts.cpp6
-rw-r--r--lib/CodeGen/OptimizePHIs.cpp189
-rw-r--r--lib/CodeGen/PBQP/AnnotatedGraph.h184
-rw-r--r--lib/CodeGen/PBQP/ExhaustiveSolver.h110
-rw-r--r--lib/CodeGen/PBQP/Graph.h425
-rw-r--r--lib/CodeGen/PBQP/GraphBase.h582
-rw-r--r--lib/CodeGen/PBQP/HeuristicBase.h242
-rw-r--r--lib/CodeGen/PBQP/HeuristicSolver.h1118
-rw-r--r--lib/CodeGen/PBQP/Heuristics/Briggs.h682
-rw-r--r--lib/CodeGen/PBQP/Math.h (renamed from lib/CodeGen/PBQP/PBQPMath.h)10
-rw-r--r--lib/CodeGen/PBQP/SimpleGraph.h100
-rw-r--r--lib/CodeGen/PBQP/Solution.h102
-rw-r--r--lib/CodeGen/PBQP/Solver.h31
-rw-r--r--lib/CodeGen/PHIElimination.cpp20
-rw-r--r--lib/CodeGen/PHIElimination.h25
-rw-r--r--lib/CodeGen/PreAllocSplitting.cpp3
-rw-r--r--lib/CodeGen/ProcessImplicitDefs.cpp21
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp17
-rw-r--r--lib/CodeGen/RegAllocLocal.cpp67
-rw-r--r--lib/CodeGen/RegAllocPBQP.cpp64
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp117
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp9
-rw-r--r--lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp28
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp183
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp17
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp35
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.cpp5
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.h55
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp19
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp751
-rw-r--r--lib/CodeGen/SelectionDAG/Makefile1
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp26
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp102
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp1025
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h5
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp57
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp57
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp131
-rw-r--r--lib/CodeGen/SjLjEHPrepare.cpp11
-rw-r--r--lib/CodeGen/SlotIndexes.cpp6
-rw-r--r--lib/CodeGen/StackProtector.cpp2
-rw-r--r--lib/CodeGen/StackSlotColoring.cpp9
-rw-r--r--lib/CodeGen/StrongPHIElimination.cpp15
-rw-r--r--lib/CodeGen/TailDuplication.cpp43
-rw-r--r--lib/CodeGen/TargetLoweringObjectFileImpl.cpp874
-rw-r--r--lib/CodeGen/TwoAddressInstructionPass.cpp28
-rw-r--r--lib/CodeGen/UnreachableBlockElim.cpp6
-rw-r--r--lib/CodeGen/VirtRegMap.cpp2
-rw-r--r--lib/CodeGen/VirtRegRewriter.cpp42
-rw-r--r--lib/CompilerDriver/CompilationGraph.cpp6
-rw-r--r--lib/CompilerDriver/Makefile1
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp98
-rw-r--r--lib/ExecutionEngine/ExecutionEngineBindings.cpp14
-rw-r--r--lib/ExecutionEngine/Interpreter/Execution.cpp18
-rw-r--r--lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp7
-rw-r--r--lib/ExecutionEngine/Interpreter/Interpreter.cpp13
-rw-r--r--lib/ExecutionEngine/Interpreter/Interpreter.h4
-rw-r--r--lib/ExecutionEngine/Interpreter/Makefile1
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp181
-rw-r--r--lib/ExecutionEngine/JIT/JIT.h52
-rw-r--r--lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp6
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp189
-rw-r--r--lib/ExecutionEngine/JIT/Makefile1
-rw-r--r--lib/ExecutionEngine/JIT/TargetSelect.cpp27
-rw-r--r--lib/ExecutionEngine/Makefile1
-rw-r--r--lib/Linker/LinkArchives.cpp21
-rw-r--r--lib/Linker/LinkModules.cpp17
-rw-r--r--lib/Linker/Makefile1
-rw-r--r--lib/MC/MCAsmInfo.cpp10
-rw-r--r--lib/MC/MCAsmInfoCOFF.cpp6
-rw-r--r--lib/MC/MCAsmInfoDarwin.cpp3
-rw-r--r--lib/MC/MCAsmStreamer.cpp296
-rw-r--r--lib/MC/MCAssembler.cpp339
-rw-r--r--lib/MC/MCCodeEmitter.cpp12
-rw-r--r--lib/MC/MCExpr.cpp10
-rw-r--r--lib/MC/MCInstPrinter.cpp7
-rw-r--r--lib/MC/MCMachOStreamer.cpp66
-rw-r--r--lib/MC/MCNullStreamer.cpp6
-rw-r--r--lib/MC/MCParser/AsmParser.cpp29
-rw-r--r--lib/MC/MCParser/Makefile1
-rw-r--r--lib/MC/Makefile1
-rw-r--r--lib/Support/APInt.cpp28
-rw-r--r--lib/Support/CommandLine.cpp5
-rw-r--r--lib/Support/ConstantRange.cpp12
-rw-r--r--lib/Support/FileUtilities.cpp14
-rw-r--r--lib/Support/FormattedStream.cpp3
-rw-r--r--lib/Support/SourceMgr.cpp40
-rw-r--r--lib/Support/Triple.cpp6
-rw-r--r--lib/Support/raw_ostream.cpp22
-rw-r--r--lib/System/Makefile2
-rw-r--r--lib/System/Unix/Program.inc7
-rw-r--r--lib/System/Unix/Signals.inc11
-rw-r--r--lib/System/Win32/Program.inc5
-rw-r--r--lib/Target/ARM/ARM.h6
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp13
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp17
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.h4
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp194
-rw-r--r--lib/Target/ARM/ARMConstantIslandPass.cpp16
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp10
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp100
-rw-r--r--lib/Target/ARM/ARMISelLowering.h5
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td91
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td358
-rw-r--r--lib/Target/ARM/ARMInstrNEON.td20
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td29
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td28
-rw-r--r--lib/Target/ARM/ARMInstrVFP.td352
-rw-r--r--lib/Target/ARM/ARMLoadStoreOptimizer.cpp3
-rw-r--r--lib/Target/ARM/ARMMCAsmInfo.cpp8
-rw-r--r--lib/Target/ARM/ARMMachineFunctionInfo.h10
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.td4
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp6
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp49
-rw-r--r--lib/Target/ARM/ARMTargetMachine.h13
-rw-r--r--lib/Target/ARM/ARMTargetObjectFile.h4
-rw-r--r--lib/Target/ARM/AsmParser/Makefile1
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp237
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp4
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp2
-rw-r--r--lib/Target/ARM/AsmPrinter/Makefile1
-rw-r--r--lib/Target/ARM/Makefile1
-rw-r--r--lib/Target/ARM/README.txt20
-rw-r--r--lib/Target/ARM/TargetInfo/Makefile1
-rw-r--r--lib/Target/ARM/Thumb2InstrInfo.cpp21
-rw-r--r--lib/Target/ARM/Thumb2SizeReduction.cpp2
-rw-r--r--lib/Target/Alpha/Alpha.h6
-rw-r--r--lib/Target/Alpha/AlphaCodeEmitter.cpp63
-rw-r--r--lib/Target/Alpha/AlphaISelDAGToDAG.cpp2
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.cpp51
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.h2
-rw-r--r--lib/Target/Alpha/AlphaMCAsmInfo.cpp3
-rw-r--r--lib/Target/Alpha/AlphaRegisterInfo.cpp7
-rw-r--r--lib/Target/Alpha/AlphaTargetMachine.cpp28
-rw-r--r--lib/Target/Alpha/AlphaTargetMachine.h13
-rw-r--r--lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp88
-rw-r--r--lib/Target/Alpha/AsmPrinter/Makefile1
-rw-r--r--lib/Target/Alpha/Makefile1
-rw-r--r--lib/Target/Alpha/TargetInfo/Makefile1
-rw-r--r--lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp86
-rw-r--r--lib/Target/Blackfin/AsmPrinter/Makefile1
-rw-r--r--lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp2
-rw-r--r--lib/Target/Blackfin/BlackfinISelLowering.cpp11
-rw-r--r--lib/Target/Blackfin/BlackfinISelLowering.h2
-rw-r--r--lib/Target/Blackfin/BlackfinMCAsmInfo.cpp1
-rw-r--r--lib/Target/Blackfin/Makefile1
-rw-r--r--lib/Target/Blackfin/TargetInfo/Makefile1
-rw-r--r--lib/Target/CBackend/CBackend.cpp25
-rw-r--r--lib/Target/CBackend/Makefile2
-rw-r--r--lib/Target/CBackend/TargetInfo/Makefile1
-rw-r--r--lib/Target/CMakeLists.txt1
-rw-r--r--lib/Target/CellSPU/AsmPrinter/Makefile1
-rw-r--r--lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp130
-rw-r--r--lib/Target/CellSPU/Makefile2
-rw-r--r--lib/Target/CellSPU/SPUISelDAGToDAG.cpp2
-rw-r--r--lib/Target/CellSPU/SPUISelLowering.cpp27
-rw-r--r--lib/Target/CellSPU/SPUISelLowering.h2
-rw-r--r--lib/Target/CellSPU/SPUMCAsmInfo.cpp2
-rw-r--r--lib/Target/CellSPU/TargetInfo/Makefile1
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp11
-rw-r--r--lib/Target/CppBackend/Makefile2
-rw-r--r--lib/Target/CppBackend/TargetInfo/Makefile1
-rw-r--r--lib/Target/MSIL/MSILWriter.cpp10
-rw-r--r--lib/Target/MSIL/Makefile2
-rw-r--r--lib/Target/MSIL/TargetInfo/Makefile1
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp151
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp1
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp2
-rw-r--r--lib/Target/MSP430/AsmPrinter/Makefile1
-rw-r--r--lib/Target/MSP430/MSP430ISelDAGToDAG.cpp13
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp22
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.h2
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.cpp10
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td2
-rw-r--r--lib/Target/MSP430/MSP430MCAsmInfo.cpp1
-rw-r--r--lib/Target/MSP430/Makefile1
-rw-r--r--lib/Target/MSP430/TargetInfo/Makefile1
-rw-r--r--lib/Target/Makefile1
-rw-r--r--lib/Target/Mips/AsmPrinter/Makefile1
-rw-r--r--lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp134
-rw-r--r--lib/Target/Mips/Makefile1
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp7
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp210
-rw-r--r--lib/Target/Mips/MipsISelLowering.h5
-rw-r--r--lib/Target/Mips/MipsInstrFPU.td6
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td2
-rw-r--r--lib/Target/Mips/MipsMCAsmInfo.cpp4
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.cpp28
-rw-r--r--lib/Target/Mips/MipsTargetObjectFile.h2
-rw-r--r--lib/Target/Mips/TargetInfo/Makefile1
-rw-r--r--lib/Target/PIC16/AsmPrinter/Makefile1
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp25
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h5
-rw-r--r--lib/Target/PIC16/Makefile1
-rw-r--r--lib/Target/PIC16/PIC16.h3
-rw-r--r--lib/Target/PIC16/PIC16ABINames.h13
-rw-r--r--lib/Target/PIC16/PIC16DebugInfo.cpp2
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.cpp11
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.h2
-rw-r--r--lib/Target/PIC16/PIC16MCAsmInfo.cpp2
-rw-r--r--lib/Target/PIC16/PIC16MemSelOpt.cpp105
-rw-r--r--lib/Target/PIC16/PIC16Passes/Makefile1
-rw-r--r--lib/Target/PIC16/PIC16TargetObjectFile.cpp6
-rw-r--r--lib/Target/PIC16/PIC16TargetObjectFile.h3
-rw-r--r--lib/Target/PIC16/TargetInfo/Makefile1
-rw-r--r--lib/Target/PowerPC/AsmPrinter/Makefile1
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp273
-rw-r--r--lib/Target/PowerPC/CMakeLists.txt1
-rw-r--r--lib/Target/PowerPC/Makefile1
-rw-r--r--lib/Target/PowerPC/PPC.h6
-rw-r--r--lib/Target/PowerPC/PPCCallingConv.td17
-rw-r--r--lib/Target/PowerPC/PPCCodeEmitter.cpp77
-rw-r--r--lib/Target/PowerPC/PPCHazardRecognizers.cpp2
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp2
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp147
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.h16
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.cpp44
-rw-r--r--lib/Target/PowerPC/PPCMCAsmInfo.cpp5
-rw-r--r--lib/Target/PowerPC/PPCMachOWriterInfo.cpp152
-rw-r--r--lib/Target/PowerPC/PPCMachOWriterInfo.h55
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp28
-rw-r--r--lib/Target/PowerPC/PPCSubtarget.cpp2
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.cpp109
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.h30
-rw-r--r--lib/Target/PowerPC/README.txt72
-rw-r--r--lib/Target/PowerPC/TargetInfo/Makefile1
-rw-r--r--lib/Target/README.txt157
-rw-r--r--lib/Target/Sparc/AsmPrinter/Makefile2
-rw-r--r--lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp131
-rw-r--r--lib/Target/Sparc/Makefile1
-rw-r--r--lib/Target/Sparc/Sparc.h1
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp55
-rw-r--r--lib/Target/Sparc/SparcISelLowering.h2
-rw-r--r--lib/Target/Sparc/SparcMCAsmInfo.cpp2
-rw-r--r--lib/Target/Sparc/SparcSubtarget.cpp31
-rw-r--r--lib/Target/Sparc/SparcSubtarget.h16
-rw-r--r--lib/Target/Sparc/SparcTargetMachine.cpp26
-rw-r--r--lib/Target/Sparc/SparcTargetMachine.h20
-rw-r--r--lib/Target/Sparc/TargetInfo/Makefile1
-rw-r--r--lib/Target/Sparc/TargetInfo/SparcTargetInfo.cpp2
-rw-r--r--lib/Target/SubtargetFeature.cpp2
-rw-r--r--lib/Target/SystemZ/AsmPrinter/Makefile1
-rw-r--r--lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp93
-rw-r--r--lib/Target/SystemZ/Makefile1
-rw-r--r--lib/Target/SystemZ/SystemZISelDAGToDAG.cpp19
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.cpp14
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.h2
-rw-r--r--lib/Target/SystemZ/SystemZMCAsmInfo.cpp3
-rw-r--r--lib/Target/SystemZ/SystemZRegisterInfo.cpp7
-rw-r--r--lib/Target/SystemZ/SystemZRegisterInfo.h2
-rw-r--r--lib/Target/SystemZ/TargetInfo/Makefile1
-rw-r--r--lib/Target/TargetAsmLexer.cpp2
-rw-r--r--lib/Target/TargetData.cpp7
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp844
-rw-r--r--lib/Target/TargetMachOWriterInfo.cpp25
-rw-r--r--lib/Target/TargetMachine.cpp8
-rw-r--r--lib/Target/TargetRegisterInfo.cpp7
-rw-r--r--lib/Target/X86/AsmParser/Makefile1
-rw-r--r--lib/Target/X86/AsmParser/X86AsmLexer.cpp118
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp119
-rw-r--r--lib/Target/X86/AsmPrinter/Makefile1
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp11
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h5
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp288
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.h27
-rw-r--r--lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp5
-rw-r--r--lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h2
-rw-r--r--lib/Target/X86/AsmPrinter/X86MCInstLower.cpp409
-rw-r--r--lib/Target/X86/AsmPrinter/X86MCInstLower.h6
-rw-r--r--lib/Target/X86/CMakeLists.txt2
-rw-r--r--lib/Target/X86/Disassembler/Makefile1
-rw-r--r--lib/Target/X86/Makefile2
-rw-r--r--lib/Target/X86/README-SSE.txt53
-rw-r--r--lib/Target/X86/README-UNIMPLEMENTED.txt2
-rw-r--r--lib/Target/X86/README.txt66
-rw-r--r--lib/Target/X86/TargetInfo/Makefile1
-rw-r--r--lib/Target/X86/X86.h11
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.cpp97
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.h27
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp526
-rw-r--r--lib/Target/X86/X86FastISel.cpp80
-rw-r--r--lib/Target/X86/X86FixupKinds.h25
-rw-r--r--lib/Target/X86/X86FloatingPoint.cpp4
-rw-r--r--lib/Target/X86/X86FloatingPointRegKill.cpp2
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp47
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp627
-rw-r--r--lib/Target/X86/X86ISelLowering.h54
-rw-r--r--lib/Target/X86/X86Instr64bit.td58
-rw-r--r--lib/Target/X86/X86InstrFPStack.td1
-rw-r--r--lib/Target/X86/X86InstrFormats.td36
-rw-r--r--lib/Target/X86/X86InstrFragmentsSIMD.td62
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp150
-rw-r--r--lib/Target/X86/X86InstrInfo.h86
-rw-r--r--lib/Target/X86/X86InstrInfo.td335
-rw-r--r--lib/Target/X86/X86InstrMMX.td71
-rw-r--r--lib/Target/X86/X86InstrSSE.td33
-rw-r--r--lib/Target/X86/X86JITInfo.cpp1
-rw-r--r--lib/Target/X86/X86MCAsmInfo.cpp29
-rw-r--r--lib/Target/X86/X86MCAsmInfo.h5
-rw-r--r--lib/Target/X86/X86MCCodeEmitter.cpp645
-rw-r--r--lib/Target/X86/X86MCTargetExpr.cpp48
-rw-r--r--lib/Target/X86/X86MCTargetExpr.h49
-rw-r--r--lib/Target/X86/X86MachineFunctionInfo.h20
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp26
-rw-r--r--lib/Target/X86/X86RegisterInfo.h2
-rw-r--r--lib/Target/X86/X86RegisterInfo.td25
-rw-r--r--lib/Target/X86/X86Subtarget.cpp4
-rw-r--r--lib/Target/X86/X86Subtarget.h2
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp86
-rw-r--r--lib/Target/X86/X86TargetMachine.h25
-rw-r--r--lib/Target/X86/X86TargetObjectFile.cpp192
-rw-r--r--lib/Target/X86/X86TargetObjectFile.h46
-rw-r--r--lib/Target/XCore/AsmPrinter/Makefile1
-rw-r--r--lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp80
-rw-r--r--lib/Target/XCore/Makefile1
-rw-r--r--lib/Target/XCore/TargetInfo/Makefile1
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp42
-rw-r--r--lib/Target/XCore/XCoreISelLowering.h4
-rw-r--r--lib/Target/XCore/XCoreInstrInfo.td4
-rw-r--r--lib/Target/XCore/XCoreMCAsmInfo.cpp1
-rw-r--r--lib/Target/XCore/XCoreTargetObjectFile.h3
-rw-r--r--lib/Transforms/Hello/Makefile1
-rw-r--r--lib/Transforms/IPO/ArgumentPromotion.cpp2
-rw-r--r--lib/Transforms/IPO/ConstantMerge.cpp41
-rw-r--r--lib/Transforms/IPO/DeadTypeElimination.cpp4
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp8
-rw-r--r--lib/Transforms/IPO/Inliner.cpp34
-rw-r--r--lib/Transforms/IPO/Makefile1
-rw-r--r--lib/Transforms/IPO/MergeFunctions.cpp1
-rw-r--r--lib/Transforms/IPO/PartialInlining.cpp2
-rw-r--r--lib/Transforms/IPO/StripSymbols.cpp9
-rw-r--r--lib/Transforms/InstCombine/InstCombine.h11
-rw-r--r--lib/Transforms/InstCombine/InstCombineAddSub.cpp73
-rw-r--r--lib/Transforms/InstCombine/InstCombineAndOrXor.cpp158
-rw-r--r--lib/Transforms/InstCombine/InstCombineCalls.cpp86
-rw-r--r--lib/Transforms/InstCombine/InstCombineCasts.cpp110
-rw-r--r--lib/Transforms/InstCombine/InstCombineCompares.cpp10
-rw-r--r--lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp28
-rw-r--r--lib/Transforms/InstCombine/InstCombineMulDivRem.cpp12
-rw-r--r--lib/Transforms/InstCombine/InstCombineSelect.cpp70
-rw-r--r--lib/Transforms/InstCombine/InstCombineShifts.cpp32
-rw-r--r--lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp177
-rw-r--r--lib/Transforms/InstCombine/InstCombineVectorOps.cpp3
-rw-r--r--lib/Transforms/InstCombine/InstructionCombining.cpp8
-rw-r--r--lib/Transforms/InstCombine/Makefile1
-rw-r--r--lib/Transforms/Instrumentation/Makefile1
-rw-r--r--lib/Transforms/Instrumentation/ProfilingUtils.cpp2
-rw-r--r--lib/Transforms/Scalar/CodeGenPrepare.cpp167
-rw-r--r--lib/Transforms/Scalar/DeadStoreElimination.cpp8
-rw-r--r--lib/Transforms/Scalar/GVN.cpp197
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp136
-rw-r--r--lib/Transforms/Scalar/JumpThreading.cpp48
-rw-r--r--lib/Transforms/Scalar/LoopStrengthReduce.cpp5046
-rw-r--r--lib/Transforms/Scalar/LoopUnrollPass.cpp10
-rw-r--r--lib/Transforms/Scalar/LoopUnswitch.cpp16
-rw-r--r--lib/Transforms/Scalar/Makefile1
-rw-r--r--lib/Transforms/Scalar/MemCpyOptimizer.cpp2
-rw-r--r--lib/Transforms/Scalar/Reassociate.cpp17
-rw-r--r--lib/Transforms/Scalar/ScalarReplAggregates.cpp66
-rw-r--r--lib/Transforms/Scalar/SimplifyCFGPass.cpp16
-rw-r--r--lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp2
-rw-r--r--lib/Transforms/Scalar/SimplifyLibCalls.cpp69
-rw-r--r--lib/Transforms/Scalar/TailRecursionElimination.cpp3
-rw-r--r--lib/Transforms/Utils/BreakCriticalEdges.cpp86
-rw-r--r--lib/Transforms/Utils/CloneFunction.cpp2
-rw-r--r--lib/Transforms/Utils/Local.cpp89
-rw-r--r--lib/Transforms/Utils/LoopSimplify.cpp5
-rw-r--r--lib/Transforms/Utils/LoopUnroll.cpp6
-rw-r--r--lib/Transforms/Utils/Makefile1
-rw-r--r--lib/Transforms/Utils/PromoteMemoryToRegister.cpp87
-rw-r--r--lib/Transforms/Utils/SSAUpdater.cpp116
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp146
-rw-r--r--lib/Transforms/Utils/ValueMapper.cpp2
-rw-r--r--lib/VMCore/AsmWriter.cpp45
-rw-r--r--lib/VMCore/Attributes.cpp9
-rw-r--r--lib/VMCore/CMakeLists.txt4
-rw-r--r--lib/VMCore/ConstantFold.cpp637
-rw-r--r--lib/VMCore/ConstantFold.h33
-rw-r--r--lib/VMCore/Constants.cpp243
-rw-r--r--lib/VMCore/ConstantsContext.h15
-rw-r--r--lib/VMCore/Core.cpp43
-rw-r--r--lib/VMCore/GVMaterializer.cpp18
-rw-r--r--lib/VMCore/Globals.cpp13
-rw-r--r--lib/VMCore/IRBuilder.cpp2
-rw-r--r--lib/VMCore/Instructions.cpp174
-rw-r--r--lib/VMCore/LLVMContextImpl.h18
-rw-r--r--lib/VMCore/Makefile2
-rw-r--r--lib/VMCore/Metadata.cpp68
-rw-r--r--lib/VMCore/Module.cpp49
-rw-r--r--lib/VMCore/ModuleProvider.cpp26
-rw-r--r--lib/VMCore/Pass.cpp10
-rw-r--r--lib/VMCore/PassManager.cpp17
-rw-r--r--lib/VMCore/Type.cpp187
-rw-r--r--lib/VMCore/TypesContext.h31
-rw-r--r--lib/VMCore/Value.cpp7
-rw-r--r--lib/VMCore/ValueTypes.cpp4
-rw-r--r--lib/VMCore/Verifier.cpp103
-rw-r--r--projects/CMakeLists.txt2
-rw-r--r--projects/sample/autoconf/configure.ac7
-rw-r--r--test/Analysis/LoopDependenceAnalysis/alias.ll2
-rw-r--r--test/Analysis/LoopDependenceAnalysis/siv-strong.ll2
-rw-r--r--test/Analysis/LoopDependenceAnalysis/siv-weak-crossing.ll2
-rw-r--r--test/Analysis/LoopDependenceAnalysis/siv-weak-zero.ll2
-rw-r--r--test/Analysis/LoopDependenceAnalysis/ziv.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2007-07-15-NegativeStride.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2007-08-06-Unsigned.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2007-09-27-LargeStepping.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-02-11-ReversedCondition.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-02-12-SMAXTripCount.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-02-15-UMax.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-05-25-NegativeStepToZero.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-07-12-UnneededSelect1.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-07-12-UnneededSelect2.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-07-19-InfiniteLoop.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-07-19-WrappingIV.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-07-29-SMinExpr.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-08-04-IVOverflow.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-08-04-LongAddRec.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-11-02-QuadraticCrash.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-11-15-CubicOOM.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-12-08-FiniteSGE.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-12-11-SMaxOverflow.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-12-14-StrideAndSigned.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2008-12-15-DontUseSDiv.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2009-01-02-SignedNegativeStride.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2009-04-22-TruncCast.ll2
-rw-r--r--test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll2
-rw-r--r--test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll2
-rw-r--r--test/Analysis/ScalarEvolution/and-xor.ll2
-rw-r--r--test/Analysis/ScalarEvolution/avoid-infinite-recursion-0.ll2
-rw-r--r--test/Analysis/ScalarEvolution/avoid-smax-0.ll2
-rw-r--r--test/Analysis/ScalarEvolution/div-overflow.ll2
-rw-r--r--test/Analysis/ScalarEvolution/do-loop.ll2
-rw-r--r--test/Analysis/ScalarEvolution/max-trip-count.ll2
-rw-r--r--test/Analysis/ScalarEvolution/nsw-offset.ll7
-rw-r--r--test/Analysis/ScalarEvolution/nsw.ll2
-rw-r--r--test/Analysis/ScalarEvolution/pointer-sign-bits.ll2
-rw-r--r--test/Analysis/ScalarEvolution/sext-inreg.ll2
-rw-r--r--test/Analysis/ScalarEvolution/sext-iv-0.ll2
-rw-r--r--test/Analysis/ScalarEvolution/sext-iv-1.ll2
-rw-r--r--test/Analysis/ScalarEvolution/sext-iv-2.ll2
-rw-r--r--test/Analysis/ScalarEvolution/smax.ll4
-rw-r--r--test/Analysis/ScalarEvolution/trip-count.ll2
-rw-r--r--test/Analysis/ScalarEvolution/trip-count2.ll2
-rw-r--r--test/Analysis/ScalarEvolution/trip-count3.ll2
-rw-r--r--test/Analysis/ScalarEvolution/trip-count4.ll2
-rw-r--r--test/Analysis/ScalarEvolution/trip-count5.ll2
-rw-r--r--test/Analysis/ScalarEvolution/trip-count6.ll2
-rw-r--r--test/Analysis/ScalarEvolution/trip-count7.ll2
-rw-r--r--test/Analysis/ScalarEvolution/trip-count8.ll2
-rw-r--r--test/Analysis/ScalarEvolution/trip-count9.ll408
-rw-r--r--test/Analysis/ScalarEvolution/xor-and.ll2
-rw-r--r--test/Analysis/ScalarEvolution/zext-wrap.ll2
-rw-r--r--test/Archive/MacOSX.abin4176 -> 4166 bytes
-rw-r--r--test/Archive/MacOSX.tocbin97 -> 72 bytes
-rw-r--r--test/Assembler/2010-01-06-UnionType.ll3
-rw-r--r--test/Assembler/2010-02-05-FunctionLocalMetadataBecomesNull.ll25
-rw-r--r--test/Assembler/functionlocal-metadata.ll2
-rw-r--r--test/Bitcode/flags.ll27
-rw-r--r--test/CodeGen/ARM/2009-10-30.ll4
-rw-r--r--test/CodeGen/ARM/aliases.ll2
-rw-r--r--test/CodeGen/ARM/align.ll41
-rw-r--r--test/CodeGen/ARM/arm-negative-stride.ll26
-rw-r--r--test/CodeGen/ARM/iabs.ll7
-rw-r--r--test/CodeGen/ARM/long_shift.ll8
-rw-r--r--test/CodeGen/ARM/lsr-code-insertion.ll4
-rw-r--r--test/CodeGen/ARM/remat-2.ll65
-rw-r--r--test/CodeGen/ARM/remat.ll178
-rw-r--r--test/CodeGen/ARM/unaligned_load_store.ll5
-rw-r--r--test/CodeGen/Generic/2006-04-11-vecload.ll12
-rw-r--r--test/CodeGen/Generic/2006-11-06-MemIntrinsicExpand.ll11
-rw-r--r--test/CodeGen/Generic/2007-04-14-BitTestsBadMask.ll160
-rw-r--r--test/CodeGen/Generic/2007-04-27-BitTestsBadMask.ll18
-rw-r--r--test/CodeGen/Generic/2007-05-03-EHTypeInfo.ll2
-rw-r--r--test/CodeGen/Generic/2007-05-05-Personality.ll2
-rw-r--r--test/CodeGen/Generic/2007-06-06-CriticalEdgeLandingPad.ll2870
-rw-r--r--test/CodeGen/Generic/addc-fold2.ll10
-rw-r--r--test/CodeGen/Generic/fpowi-promote.ll1
-rw-r--r--test/CodeGen/Generic/switch-lower-feature-2.ll50
-rw-r--r--test/CodeGen/Generic/switch-lower-feature.ll46
-rw-r--r--test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll4
-rw-r--r--test/CodeGen/PowerPC/2008-01-25-EmptyFunction.ll2
-rw-r--r--test/CodeGen/PowerPC/2010-02-04-EmptyGlobal.ll11
-rw-r--r--test/CodeGen/PowerPC/2010-02-12-saveCR.ll30
-rw-r--r--test/CodeGen/PowerPC/align.ll49
-rw-r--r--test/CodeGen/SPARC/ctpop.ll6
-rw-r--r--test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll76
-rw-r--r--test/CodeGen/Thumb2/cross-rc-coalescing-2.ll2
-rw-r--r--test/CodeGen/Thumb2/lsr-deficiency.ll18
-rw-r--r--test/CodeGen/Thumb2/thumb2-ifcvt1.ll12
-rw-r--r--test/CodeGen/Thumb2/thumb2-spill-q.ll4
-rw-r--r--test/CodeGen/X86/2006-05-11-InstrSched.ll4
-rw-r--r--test/CodeGen/X86/2006-12-16-InlineAsmCrash.ll (renamed from test/CodeGen/Generic/2006-12-16-InlineAsmCrash.ll)0
-rw-r--r--test/CodeGen/X86/2007-02-23-DAGCombine-Miscompile.ll (renamed from test/CodeGen/Generic/2007-02-23-DAGCombine-Miscompile.ll)0
-rw-r--r--test/CodeGen/X86/2007-03-15-GEP-Idx-Sink.ll2
-rw-r--r--test/CodeGen/X86/2007-10-05-3AddrConvert.ll4
-rw-r--r--test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll2
-rw-r--r--test/CodeGen/X86/2007-11-30-TestLoadFolding.ll58
-rw-r--r--test/CodeGen/X86/2008-01-25-EmptyFunction.ll2
-rw-r--r--test/CodeGen/X86/2008-07-11-SpillerBug.ll6
-rw-r--r--test/CodeGen/X86/2009-02-07-CoalescerBug.ll491
-rw-r--r--test/CodeGen/X86/2009-04-21-NoReloadImpDef.ll2
-rw-r--r--test/CodeGen/X86/2009-09-07-CoalescerBug.ll2
-rw-r--r--test/CodeGen/X86/2009-09-10-LoadFoldingBug.ll1
-rw-r--r--test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll2
-rw-r--r--test/CodeGen/X86/2010-02-01-TaillCallCrash.ll12
-rw-r--r--test/CodeGen/X86/2010-02-03-DualUndef.ll27
-rw-r--r--test/CodeGen/X86/2010-02-04-SchedulerBug.ll28
-rw-r--r--test/CodeGen/X86/2010-02-12-CoalescerBug-Impdef.ll260
-rw-r--r--test/CodeGen/X86/2010-02-15-ImplicitDefBug.ll80
-rw-r--r--test/CodeGen/X86/SwitchLowering.ll (renamed from test/CodeGen/Generic/SwitchLowering.ll)0
-rw-r--r--test/CodeGen/X86/add-trick32.ll11
-rw-r--r--test/CodeGen/X86/add-trick64.ll15
-rw-r--r--test/CodeGen/X86/add-with-overflow.ll75
-rw-r--r--test/CodeGen/X86/add.ll94
-rw-r--r--test/CodeGen/X86/addr-label-difference.ll10
-rw-r--r--test/CodeGen/X86/aliases.ll3
-rw-r--r--test/CodeGen/X86/aligned-comm.ll4
-rw-r--r--test/CodeGen/X86/call-push.ll9
-rw-r--r--test/CodeGen/X86/codegen-dce.ll (renamed from test/CodeGen/X86/twoaddr-delete.ll)2
-rw-r--r--test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll9
-rw-r--r--test/CodeGen/X86/dllexport.ll12
-rw-r--r--test/CodeGen/X86/fastcall-correct-mangling.ll4
-rw-r--r--test/CodeGen/X86/full-lsr.ll9
-rw-r--r--test/CodeGen/X86/ins_subreg_coalesce-3.ll2
-rw-r--r--test/CodeGen/X86/iv-users-in-other-loops.ll8
-rw-r--r--test/CodeGen/X86/loop-strength-reduce-2.ll19
-rw-r--r--test/CodeGen/X86/loop-strength-reduce-3.ll13
-rw-r--r--test/CodeGen/X86/loop-strength-reduce.ll13
-rw-r--r--test/CodeGen/X86/loop-strength-reduce4.ll18
-rw-r--r--test/CodeGen/X86/loop-strength-reduce8.ll8
-rw-r--r--test/CodeGen/X86/lsr-reuse-trunc.ll59
-rw-r--r--test/CodeGen/X86/lsr-reuse.ll386
-rw-r--r--test/CodeGen/X86/masked-iv-safe.ll6
-rw-r--r--test/CodeGen/X86/nancvt.ll14
-rw-r--r--test/CodeGen/X86/personality.ll2
-rw-r--r--test/CodeGen/X86/phi-immediate-factoring.ll (renamed from test/CodeGen/Generic/phi-immediate-factoring.ll)0
-rw-r--r--test/CodeGen/X86/phys-reg-local-regalloc.ll2
-rw-r--r--test/CodeGen/X86/pic.ll2
-rw-r--r--test/CodeGen/X86/pr1505b.ll4
-rw-r--r--test/CodeGen/X86/pr3495.ll3
-rw-r--r--test/CodeGen/X86/pre-split8.ll2
-rw-r--r--test/CodeGen/X86/pre-split9.ll2
-rw-r--r--test/CodeGen/X86/ptrtoint-constexpr.ll6
-rw-r--r--test/CodeGen/X86/scalar_widen_div.ll29
-rw-r--r--test/CodeGen/X86/sext-i1.ll63
-rw-r--r--test/CodeGen/X86/sse3.ll6
-rw-r--r--test/CodeGen/X86/stack-color-with-reg.ll2
-rw-r--r--test/CodeGen/X86/stdcall.ll16
-rw-r--r--test/CodeGen/X86/switch-crit-edge-constant.ll (renamed from test/CodeGen/Generic/switch-crit-edge-constant.ll)0
-rw-r--r--test/CodeGen/X86/tailcall1.ll7
-rw-r--r--test/CodeGen/X86/tailcall2.ll197
-rw-r--r--test/CodeGen/X86/tailcallfp2.ll6
-rw-r--r--test/CodeGen/X86/twoaddr-coalesce.ll2
-rw-r--r--test/CodeGen/X86/vsplit-and.ll22
-rw-r--r--test/CodeGen/X86/widen_cast-2.ll6
-rw-r--r--test/CodeGen/X86/widen_load-1.ll2
-rw-r--r--test/CodeGen/X86/widen_load-2.ll155
-rw-r--r--test/CodeGen/X86/zext-trunc.ll13
-rw-r--r--test/CodeGen/XCore/ashr.ll2
-rw-r--r--test/DebugInfo/2010-01-18-DbgValue.ll55
-rw-r--r--test/DebugInfo/2010-02-01-DbgValueCrash.ll34
-rw-r--r--test/Feature/alignment.ll4
-rw-r--r--test/Feature/unions.ll12
-rw-r--r--test/FrontendC++/2006-11-06-StackTrace.cpp10
-rw-r--r--test/FrontendC++/2006-11-30-Pubnames.cpp4
-rw-r--r--test/FrontendC++/2010-02-08-NamespaceVar.cpp16
-rw-r--r--test/FrontendC/2003-12-14-ExternInlineSupport.c2
-rw-r--r--test/FrontendC/2007-02-16-WritableStrings.c2
-rw-r--r--test/FrontendC/2009-02-17-BitField-dbg.c3
-rw-r--r--test/FrontendC/2010-01-13-MemBarrier.c2
-rw-r--r--test/FrontendC/2010-02-10-PointerName.c7
-rw-r--r--test/FrontendObjC/2010-02-01-utf16-with-null.m5
-rw-r--r--test/FrontendObjC/2010-02-11-fwritable-stringsBug.m17
-rw-r--r--test/LLVMC/MultiplePluginPriorities.td3
-rw-r--r--test/MC/AsmParser/X86/dg.exp2
-rw-r--r--test/MC/AsmParser/X86/x86_32-bit.s1630
-rw-r--r--test/MC/AsmParser/X86/x86_32-bit_cat.s7809
-rw-r--r--test/MC/AsmParser/X86/x86_32-encoding.s9861
-rw-r--r--test/MC/AsmParser/X86/x86_32-new-encoder.s41
-rw-r--r--test/MC/AsmParser/X86/x86_64-new-encoder.s26
-rw-r--r--test/MC/AsmParser/X86/x86_instructions.s89
-rw-r--r--test/MC/AsmParser/X86/x86_operands.s20
-rw-r--r--test/MC/AsmParser/conditional_asm.s2
-rw-r--r--test/MC/AsmParser/directive_file.s7
-rw-r--r--test/MC/AsmParser/exprs.s1
-rw-r--r--test/MC/AsmParser/labels.s2
-rw-r--r--test/MC/Disassembler/simple-tests.txt29
-rw-r--r--test/MC/MachO/Darwin/dg.exp5
-rw-r--r--test/MC/MachO/Darwin/x86_32_diff_as.s550
-rw-r--r--test/MC/MachO/section-flags.s14
-rw-r--r--test/Other/2007-06-05-PassID.ll2
-rw-r--r--test/Other/2007-06-28-PassManager.ll4
-rw-r--r--test/Other/constant-fold-gep.ll428
-rw-r--r--test/Transforms/ConstProp/basictest.ll12
-rw-r--r--test/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll16
-rw-r--r--test/Transforms/ConstantMerge/dont-merge.ll30
-rw-r--r--test/Transforms/DeadStoreElimination/crash.ll14
-rw-r--r--test/Transforms/GVN/crash.ll22
-rw-r--r--test/Transforms/GVN/load-pre-align.ll44
-rw-r--r--test/Transforms/GVN/rle-nonlocal.ll9
-rw-r--r--test/Transforms/IndVarSimplify/addrec-gep.ll2
-rw-r--r--test/Transforms/IndVarSimplify/shrunk-constant.ll2
-rw-r--r--test/Transforms/InstCombine/2007-03-27-PR1280.ll15
-rw-r--r--test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll19
-rw-r--r--test/Transforms/InstCombine/and2.ll6
-rw-r--r--test/Transforms/InstCombine/call.ll22
-rw-r--r--test/Transforms/InstCombine/crash.ll33
-rw-r--r--test/Transforms/InstCombine/getelementptr.ll2
-rw-r--r--test/Transforms/InstCombine/icmp.ll9
-rw-r--r--test/Transforms/InstCombine/intrinsics.ll15
-rw-r--r--test/Transforms/InstCombine/load-select.ll16
-rw-r--r--test/Transforms/InstCombine/logical-select.ll22
-rw-r--r--test/Transforms/InstCombine/objsize.ll75
-rw-r--r--test/Transforms/InstCombine/or.ll14
-rw-r--r--test/Transforms/InstCombine/signext.ll23
-rw-r--r--test/Transforms/InstCombine/sub.ll8
-rw-r--r--test/Transforms/InstCombine/vector-casts.ll16
-rw-r--r--test/Transforms/JumpThreading/crash.ll90
-rw-r--r--test/Transforms/JumpThreading/or-undef.ll69
-rw-r--r--test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll5
-rw-r--r--test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll13
-rw-r--r--test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll4
-rw-r--r--test/Transforms/LoopStrengthReduce/count-to-zero.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/invariant_value_first.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/ops_after_indvar.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/pr3086.ll4
-rw-r--r--test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/remove_indvar.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll2
-rw-r--r--test/Transforms/LoopUnswitch/2006-02-14-LoopSimplifyCrash.ll1697
-rw-r--r--test/Transforms/LoopUnswitch/crash.ll (renamed from test/Transforms/LoopUnswitch/2006-02-22-UnswitchCrash.ll)17
-rw-r--r--test/Transforms/Mem2Reg/ConvertDebugInfo.ll5
-rw-r--r--test/Transforms/Reassociate/basictest.ll10
-rw-r--r--test/Transforms/SimplifyCFG/MagicPointer.ll76
-rw-r--r--test/Transforms/SimplifyLibCalls/strcpy_chk.ll12
-rw-r--r--test/lib/llvm.exp10
-rw-r--r--test/lit.cfg8
-rw-r--r--tools/Makefile3
-rw-r--r--tools/bugpoint/ExtractFunction.cpp8
-rw-r--r--tools/edis/EDDisassembler.cpp386
-rw-r--r--tools/edis/EDDisassembler.h248
-rw-r--r--tools/edis/EDInst.cpp205
-rw-r--r--tools/edis/EDInst.h171
-rw-r--r--tools/edis/EDMain.cpp293
-rw-r--r--tools/edis/EDOperand.cpp168
-rw-r--r--tools/edis/EDOperand.h78
-rw-r--r--tools/edis/EDToken.cpp208
-rw-r--r--tools/edis/EDToken.h135
-rw-r--r--tools/edis/EnhancedDisassembly.exports36
-rw-r--r--tools/edis/Makefile55
-rw-r--r--tools/gold/Makefile1
-rw-r--r--tools/llc/Makefile1
-rw-r--r--tools/llc/llc.cpp50
-rw-r--r--tools/lli/Makefile1
-rw-r--r--tools/lli/lli.cpp44
-rw-r--r--tools/llvm-ar/Makefile1
-rw-r--r--tools/llvm-as/Makefile1
-rw-r--r--tools/llvm-config/Makefile40
-rwxr-xr-xtools/llvm-config/find-cycles.pl5
-rw-r--r--tools/llvm-dis/Makefile1
-rw-r--r--tools/llvm-extract/Makefile1
-rw-r--r--tools/llvm-extract/llvm-extract.cpp52
-rw-r--r--tools/llvm-ld/Makefile1
-rw-r--r--tools/llvm-ld/llvm-ld.cpp5
-rw-r--r--tools/llvm-link/Makefile1
-rw-r--r--tools/llvm-mc/AsmCond.h40
-rw-r--r--tools/llvm-mc/AsmLexer.cpp311
-rw-r--r--tools/llvm-mc/AsmLexer.h72
-rw-r--r--tools/llvm-mc/AsmParser.cpp1782
-rw-r--r--tools/llvm-mc/AsmParser.h178
-rw-r--r--tools/llvm-mc/Disassembler.cpp48
-rw-r--r--tools/llvm-mc/HexDisassembler.cpp169
-rw-r--r--tools/llvm-mc/HexDisassembler.h34
-rw-r--r--tools/llvm-mc/Makefile1
-rw-r--r--tools/llvm-mc/llvm-mc.cpp10
-rw-r--r--tools/llvm-nm/Makefile1
-rw-r--r--tools/llvm-prof/Makefile1
-rw-r--r--tools/llvmc/Makefile1
-rw-r--r--tools/llvmc/example/mcc16/driver/Main.cpp10
-rw-r--r--tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td69
-rw-r--r--tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp39
-rw-r--r--tools/llvmc/plugins/Base/Base.td.in40
-rw-r--r--tools/lto/LTOCodeGenerator.cpp32
-rw-r--r--tools/lto/LTOModule.cpp10
-rw-r--r--tools/lto/Makefile1
-rw-r--r--tools/opt/Makefile1
-rw-r--r--tools/opt/opt.cpp3
-rw-r--r--unittests/ADT/APFloatTest.cpp2
-rw-r--r--unittests/ADT/BitVectorTest.cpp42
-rw-r--r--unittests/ADT/Makefile8
-rw-r--r--unittests/ADT/SmallBitVectorTest.cpp39
-rw-r--r--unittests/ADT/StringMapTest.cpp1
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp3
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp88
-rw-r--r--unittests/ExecutionEngine/JIT/MultiJITTest.cpp164
-rw-r--r--unittests/Makefile.unittest6
-rw-r--r--unittests/Support/TypeBuilderTest.cpp9
-rw-r--r--unittests/VMCore/DerivedTypesTest.cpp10
-rw-r--r--unittests/VMCore/PassManagerTest.cpp5
-rw-r--r--unittests/VMCore/VerifierTest.cpp44
-rw-r--r--utils/FileCheck/FileCheck.cpp22
-rwxr-xr-xutils/GenLibDeps.pl143
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp144
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp394
-rw-r--r--utils/TableGen/AsmWriterEmitter.h1
-rw-r--r--utils/TableGen/AsmWriterInst.cpp264
-rw-r--r--utils/TableGen/AsmWriterInst.h113
-rw-r--r--utils/TableGen/CMakeLists.txt5
-rw-r--r--utils/TableGen/CodeEmitterGen.cpp6
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp57
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h29
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp25
-rw-r--r--utils/TableGen/CodeGenInstruction.h32
-rw-r--r--utils/TableGen/CodeGenTarget.cpp10
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp1847
-rw-r--r--utils/TableGen/DAGISelMatcher.cpp118
-rw-r--r--utils/TableGen/DAGISelMatcher.h391
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp278
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp328
-rw-r--r--utils/TableGen/EDEmitter.cpp665
-rw-r--r--utils/TableGen/EDEmitter.h37
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp17
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp19
-rw-r--r--utils/TableGen/TableGen.cpp12
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp111
-rwxr-xr-xutils/UpdateCMakeLists.pl3
-rw-r--r--utils/lit/lit/ShUtil.py2
-rw-r--r--utils/lit/lit/TestFormats.py27
-rw-r--r--utils/lit/lit/Util.py5
-rw-r--r--utils/llvm.grm1
-rw-r--r--utils/unittest/UnitTestMain/Makefile1
-rw-r--r--utils/unittest/googletest/Makefile1
-rw-r--r--utils/vim/llvm.vim2
977 files changed, 53481 insertions, 42889 deletions
diff --git a/Makefile.rules b/Makefile.rules
index 3d436c4..761cc81 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -365,9 +365,18 @@ endif
# CXX.Flags += -fvisibility-inlines-hidden
#endif
+ifdef ENABLE_EXPENSIVE_CHECKS
+ # GNU libstdc++ uses RTTI if you define _GLIBCXX_DEBUG, which we did above.
+ # See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40160
+ REQUIRES_RTTI := 1
+endif
+
# IF REQUIRES_EH=1 is specified then don't disable exceptions
ifndef REQUIRES_EH
CXX.Flags += -fno-exceptions
+else
+ # If the library requires EH, it also requires RTTI.
+ REQUIRES_RTTI := 1
endif
ifdef REQUIRES_FRAME_POINTER
@@ -377,9 +386,9 @@ ifdef REQUIRES_FRAME_POINTER
endif
# If REQUIRES_RTTI=1 is specified then don't disable run-time type id.
-ifeq ($(REQUIRES_RTTI), 1)
- CXX.Flags := $(filter-out -fno-rtti,$(CXX.Flags))
- CXXFLAGS := $(filter-out -fno-rtti,$(CXXFLAGS))
+ifneq ($(REQUIRES_RTTI), 1)
+ CXX.Flags += -fno-rtti
+ CXXFLAGS += -fno-rtti
endif
ifdef ENABLE_COVERAGE
@@ -468,13 +477,6 @@ ifeq ($(ARCH),Alpha)
LD.Flags += -Wl,--no-relax
endif
-ifdef ENABLE_EXPENSIVE_CHECKS
- # GNU libstdc++ uses RTTI if you define _GLIBCXX_DEBUG, which we did above.
- # See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40160
- CXX.Flags := $(filter-out -fno-rtti,$(CXX.Flags))
- CXXFLAGS := $(filter-out -fno-rtti,$(CXXFLAGS))
-endif
-
#--------------------------------------------------------------------
# Directory locations
#--------------------------------------------------------------------
@@ -1572,6 +1574,11 @@ $(ObjDir)/%GenDisassemblerTables.inc.tmp : %.td $(ObjDir)/.dir
$(Echo) "Building $(<F) disassembly tables with tblgen"
$(Verb) $(TableGen) -gen-disassembler -o $(call SYSPATH, $@) $<
+$(TARGET:%=$(ObjDir)/%GenEDInfo.inc.tmp): \
+$(ObjDir)/%GenEDInfo.inc.tmp : %.td $(ObjDir)/.dir
+ $(Echo) "Building $(<F) enhanced disassembly information with tblgen"
+ $(Verb) $(TableGen) -gen-enhanced-disassembly-info -o $(call SYSPATH, $@) $<
+
$(TARGET:%=$(ObjDir)/%GenFastISel.inc.tmp): \
$(ObjDir)/%GenFastISel.inc.tmp : %.td $(ObjDir)/.dir
$(Echo) "Building $(<F) \"fast\" instruction selector implementation with tblgen"
diff --git a/README.txt b/README.txt
index c78a9ee..7388752 100644
--- a/README.txt
+++ b/README.txt
@@ -10,4 +10,3 @@ the license agreement found in LICENSE.txt.
Please see the HTML documentation provided in docs/index.html for further
assistance with LLVM.
-
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
index 7915593..40f77d8 100644
--- a/autoconf/configure.ac
+++ b/autoconf/configure.ac
@@ -727,13 +727,13 @@ fi
dnl --enable-libffi : check whether the user wants to turn off libffi:
AC_ARG_ENABLE(libffi,AS_HELP_STRING(
- --enable-libffi,[Check for the presence of libffi (default is YES)]),,
- enableval=yes)
-case "$enableval" in
- yes) llvm_cv_enable_libffi="yes" ;;
- no) llvm_cv_enable_libffi="no" ;;
- *) AC_MSG_ERROR([Invalid setting for --enable-libffi. Use "yes" or "no"]) ;;
-esac
+ --enable-libffi,[Check for the presence of libffi (default is NO)]),
+ [case "$enableval" in
+ yes) llvm_cv_enable_libffi="yes" ;;
+ no) llvm_cv_enable_libffi="no" ;;
+ *) AC_MSG_ERROR([Invalid setting for --enable-libffi. Use "yes" or "no"]) ;;
+ esac],
+ llvm_cv_enable_libffi=no)
dnl Only Windows needs dynamic libCompilerDriver to support plugins.
if test "$llvm_cv_os_type" = "Win32" ; then
@@ -789,6 +789,7 @@ AC_PATH_PROG(GREP, [grep], [grep])
AC_PATH_PROG(MKDIR,[mkdir],[mkdir])
AC_PATH_PROG(MV, [mv], [mv])
AC_PROG_RANLIB
+AC_CHECK_TOOL(AR, ar, false)
AC_PATH_PROG(RM, [rm], [rm])
AC_PATH_PROG(SED, [sed], [sed])
AC_PATH_PROG(TAR, [tar], [gtar])
@@ -919,13 +920,6 @@ dnl before the AC_PROG_LIBTOOL check in order to enable dlopening libraries with
dnl libtool).
AC_LIBTOOL_DLOPEN
AC_LIB_LTDL
-AC_PROG_LIBTOOL
-
-if test "$lt_cv_dlopen_self" = "yes" ; then
- AC_DEFINE([CAN_DLOPEN_SELF],[1],
- [Define if dlopen(0) will open the symbols of the program])
-fi
-
if test "$WITH_LLVMGCCDIR" = "default" ; then
LLVMGCC="llvm-gcc${EXEEXT}"
@@ -1027,7 +1021,7 @@ dnl libffi is optional; used to call external functions from the interpreter
if test "$llvm_cv_enable_libffi" = "yes" ; then
AC_SEARCH_LIBS(ffi_call,ffi,AC_DEFINE([HAVE_FFI_CALL],[1],
[Define if libffi is available on this platform.]),
- AC_MSG_WARN([libffi not found - disabling external calls from interpreter]))
+ AC_MSG_ERROR([libffi not found - configure without --enable-libffi to compile without it]))
fi
dnl mallinfo is optional; the code can compile (minus features) without it
@@ -1148,7 +1142,7 @@ dnl===-----------------------------------------------------------------------===
AC_HUGE_VAL_CHECK
AC_TYPE_PID_T
AC_TYPE_SIZE_T
-AC_TYPE_SIGNAL
+AC_DEFINE_UNQUOTED([RETSIGTYPE],[void],[Define as the return type of signal handlers (`int' or `void').])
AC_STRUCT_TM
AC_CHECK_TYPES([int64_t],,AC_MSG_ERROR([Type int64_t required but not found]))
AC_CHECK_TYPES([uint64_t],,
@@ -1170,15 +1164,10 @@ AC_CHECK_FUNCS([strerror strerror_r strerror_s setenv ])
AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ])
AC_CHECK_FUNCS([setjmp longjmp sigsetjmp siglongjmp])
AC_C_PRINTF_A
-dnl FIXME: This is no longer used, please remove (but test)!!!
-AC_FUNC_ALLOCA
AC_FUNC_RAND48
dnl Check for variations in the Standard C++ library and STL. These macros are
dnl provided by LLVM in the autoconf/m4 directory.
-AC_CXX_HAVE_STD_ITERATOR
-AC_CXX_HAVE_BI_ITERATOR
-AC_CXX_HAVE_FWD_ITERATOR
AC_FUNC_ISNAN
AC_FUNC_ISINF
diff --git a/autoconf/m4/path_tclsh.m4 b/autoconf/m4/path_tclsh.m4
index e0a9d06..85433de 100644
--- a/autoconf/m4/path_tclsh.m4
+++ b/autoconf/m4/path_tclsh.m4
@@ -19,7 +19,7 @@ if test x"${with_tclinclude}" != x ; then
else
AC_MSG_ERROR([${with_tclinclude} directory doesn't contain tclsh])
fi
-fi
+fi])
dnl see if one is installed
if test x"${ac_cv_path_tclsh}" = x ; then
@@ -35,5 +35,5 @@ else
TCLSH="${ac_cv_path_tclsh}"
AC_SUBST(TCLSH)
fi
-])])
+])
diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml
index 25e47ab..7e4acbf 100644
--- a/bindings/ocaml/llvm/llvm.ml
+++ b/bindings/ocaml/llvm/llvm.ml
@@ -93,6 +93,7 @@ module Attribute = struct
| Noredzone
| Noimplicitfloat
| Naked
+ | Inlinehint
end
module Icmp = struct
@@ -144,7 +145,7 @@ type ('a, 'b) llrev_pos =
(*===-- Contexts ----------------------------------------------------------===*)
external create_context : unit -> llcontext = "llvm_create_context"
-external dispose_context : unit -> llcontext = "llvm_dispose_context"
+external dispose_context : llcontext -> unit = "llvm_dispose_context"
external global_context : unit -> llcontext = "llvm_global_context"
(*===-- Modules -----------------------------------------------------------===*)
diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli
index c703ef7..4f28ae6 100644
--- a/bindings/ocaml/llvm/llvm.mli
+++ b/bindings/ocaml/llvm/llvm.mli
@@ -143,6 +143,7 @@ module Attribute : sig
| Noredzone
| Noimplicitfloat
| Naked
+ | Inlinehint
end
(** The predicate for an integer comparison ([icmp]) instruction.
@@ -214,7 +215,7 @@ external create_context : unit -> llcontext = "llvm_create_context"
(** [destroy_context ()] destroys a context. See the destructor
[llvm::LLVMContext::~LLVMContext]. *)
-external dispose_context : unit -> llcontext = "llvm_dispose_context"
+external dispose_context : llcontext -> unit = "llvm_dispose_context"
(** See the function [llvm::getGlobalContext]. *)
external global_context : unit -> llcontext = "llvm_global_context"
@@ -1419,13 +1420,13 @@ external build_aggregate_ret : llvalue array -> llbuilder -> llvalue
= "llvm_build_aggregate_ret"
(** [build_br bb b] creates a
- [b %bb]
+ [br %bb]
instruction at the position specified by the instruction builder [b].
See the method [llvm::LLVMBuilder::CreateBr]. *)
external build_br : llbasicblock -> llbuilder -> llvalue = "llvm_build_br"
(** [build_cond_br cond tbb fbb b] creates a
- [b %cond, %tbb, %fbb]
+ [br %cond, %tbb, %fbb]
instruction at the position specified by the instruction builder [b].
See the method [llvm::LLVMBuilder::CreateCondBr]. *)
external build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder ->
@@ -1475,7 +1476,7 @@ external build_unreachable : llbuilder -> llvalue = "llvm_build_unreachable"
external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
= "llvm_build_add"
-(** [build_nswadd x y name b] creates a
+(** [build_nsw_add x y name b] creates a
[%name = nsw add %x, %y]
instruction at the position specified by the instruction builder [b].
See the method [llvm::LLVMBuilder::CreateNSWAdd]. *)
diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c
index 6cc475d..86492d7 100644
--- a/bindings/ocaml/llvm/llvm_ocaml.c
+++ b/bindings/ocaml/llvm/llvm_ocaml.c
@@ -1031,8 +1031,8 @@ CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of,
return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
}
-CAMLprim value llvm_add_case(LLVMValueRef Switch,
- LLVMValueRef OnVal,
+/* llvalue -> llvalue -> llbasicblock -> unit */
+CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
LLVMBasicBlockRef Dest) {
LLVMAddCase(Switch, OnVal, Dest);
return Val_unit;
@@ -1263,11 +1263,10 @@ CAMLprim LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer,
/* llvalue -> int -> string -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer,
- value Indices, value Name,
+ value Index, value Name,
value B) {
- return LLVMBuildInBoundsGEP(Builder_val(B), Pointer,
- (LLVMValueRef *) Op_val(Indices),
- Wosize_val(Indices), String_val(Name));
+ return LLVMBuildStructGEP(Builder_val(B), Pointer,
+ Int_val(Index), String_val(Name));
}
/* string -> string -> llbuilder -> llvalue */
diff --git a/configure b/configure
index fc30999..88050f3 100755
--- a/configure
+++ b/configure
@@ -538,160 +538,6 @@ as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$ECHO in
-X*--fallback-echo)
- # Remove one level of quotation (which was required for Make).
- ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
- ;;
-esac
-
-echo=${ECHO-echo}
-if test "X$1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X$1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
- # Yippee, $echo works!
- :
-else
- # Restart under the correct shell.
- exec $SHELL "$0" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<EOF
-$*
-EOF
- exit 0
-fi
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$ECHO"; then
-if test "X${echo_test_string+set}" != Xset; then
-# find a string as large as possible, as long as the shell can cope with it
- for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if (echo_test_string=`eval $cmd`) 2>/dev/null &&
- echo_test_string=`eval $cmd` &&
- (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
- then
- break
- fi
- done
-fi
-
-if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- :
-else
- # The Solaris, AIX, and Digital Unix default echo programs unquote
- # backslashes. This makes it impossible to quote backslashes using
- # echo "$something" | sed 's/\\/\\\\/g'
- #
- # So, first we look for a working echo in the user's PATH.
-
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for dir in $PATH /usr/ucb; do
- IFS="$lt_save_ifs"
- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- echo="$dir/echo"
- break
- fi
- done
- IFS="$lt_save_ifs"
-
- if test "X$echo" = Xecho; then
- # We didn't find a better echo, so look for alternatives.
- if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # This shell has a builtin print -r that does the trick.
- echo='print -r'
- elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
- test "X$CONFIG_SHELL" != X/bin/ksh; then
- # If we have ksh, try running configure again with it.
- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
- export ORIGINAL_CONFIG_SHELL
- CONFIG_SHELL=/bin/ksh
- export CONFIG_SHELL
- exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
- else
- # Try using printf.
- echo='printf %s\n'
- if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # Cool, printf works
- :
- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
- export CONFIG_SHELL
- SHELL="$CONFIG_SHELL"
- export SHELL
- echo="$CONFIG_SHELL $0 --fallback-echo"
- elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- echo="$CONFIG_SHELL $0 --fallback-echo"
- else
- # maybe with a smaller string...
- prev=:
-
- for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
- if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
- then
- break
- fi
- prev="$cmd"
- done
-
- if test "$prev" != 'sed 50q "$0"'; then
- echo_test_string=`eval $prev`
- export echo_test_string
- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
- else
- # Oops. We lost completely, so just stick with echo.
- echo=echo
- fi
- fi
- fi
- fi
-fi
-fi
-
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-ECHO=$echo
-if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
- ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
-fi
-
-
-
-
-tagnames=${tagnames+${tagnames},}CXX
-
-tagnames=${tagnames+${tagnames},}F77
-
exec 7<&0 </dev/null 6>&1
# Name of the host.
@@ -867,6 +713,7 @@ FIND
MKDIR
MV
RANLIB
+AR
RM
SED
TAR
@@ -903,14 +750,6 @@ INSTALL_LTDL_FALSE
CONVENIENCE_LTDL_TRUE
CONVENIENCE_LTDL_FALSE
LIBADD_DL
-ECHO
-AR
-STRIP
-CXXCPP
-F77
-FFLAGS
-ac_ct_F77
-LIBTOOL
LLVMGCCCOMMAND
LLVMGXXCOMMAND
LLVMGCC
@@ -921,7 +760,6 @@ USE_UDIS86
USE_OPROFILE
HAVE_PTHREAD
HUGE_VAL_SANITY
-ALLOCA
MMAP_FILE
LLVMCC1
LLVMCC1PLUS
@@ -960,10 +798,7 @@ CPPFLAGS
CPP
CXX
CXXFLAGS
-CCC
-CXXCPP
-F77
-FFLAGS'
+CCC'
ac_subdirs_all='projects/sample
projects/privbracket
projects/llvm-stacker
@@ -1575,20 +1410,12 @@ Optional Features:
%a (default is YES)
--enable-bindings Build specific language bindings:
all,auto,none,{binding-name} (default=auto)
- --enable-libffi Check for the presence of libffi (default is YES)
+ --enable-libffi Check for the presence of libffi (default is NO)
--enable-llvmc-dynamic Link LLVMC dynamically (default is NO, unless on
Win32)
--enable-llvmc-dynamic-plugins
Enable dynamic LLVMC plugins (default is YES)
--enable-ltdl-install install libltdl
- --enable-shared[=PKGS] build shared libraries
- [default=yes]
- --enable-static[=PKGS] build static libraries
- [default=yes]
- --enable-fast-install[=PKGS]
- optimize for fast installation
- [default=yes]
- --disable-libtool-lock avoid locking (might break parallel builds)
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1615,10 +1442,6 @@ Optional Packages:
--with-binutils-include Specify path to binutils/include/ containing
plugin-api.h file for gold plugin.
--with-tclinclude directory where tcl headers are
- --with-gnu-ld assume the C compiler uses GNU ld [default=no]
- --with-pic try to use only PIC/non-PIC objects [default=use
- both]
- --with-tags[=TAGS] include additional configurations [automatic]
--with-udis86=<path> Use udis86 external x86 disassembler library
--with-oprofile=<prefix>
Tell OProfile >= 0.9.4 how to symbolize JIT output
@@ -1633,9 +1456,6 @@ Some influential environment variables:
CPP C preprocessor
CXX C++ compiler command
CXXFLAGS C++ compiler flags
- CXXCPP C++ preprocessor
- F77 Fortran 77 compiler command
- FFLAGS Fortran 77 compiler flags
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
@@ -5383,18 +5203,17 @@ fi
# Check whether --enable-libffi was given.
if test "${enable_libffi+set}" = set; then
- enableval=$enable_libffi;
+ enableval=$enable_libffi; case "$enableval" in
+ yes) llvm_cv_enable_libffi="yes" ;;
+ no) llvm_cv_enable_libffi="no" ;;
+ *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-libffi. Use \"yes\" or \"no\"" >&5
+echo "$as_me: error: Invalid setting for --enable-libffi. Use \"yes\" or \"no\"" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
else
- enableval=yes
+ llvm_cv_enable_libffi=no
fi
-case "$enableval" in
- yes) llvm_cv_enable_libffi="yes" ;;
- no) llvm_cv_enable_libffi="no" ;;
- *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-libffi. Use \"yes\" or \"no\"" >&5
-echo "$as_me: error: Invalid setting for --enable-libffi. Use \"yes\" or \"no\"" >&2;}
- { (exit 1); exit 1; }; } ;;
-esac
if test "$llvm_cv_os_type" = "Win32" ; then
llvmc_dynamic="yes"
@@ -7164,6 +6983,102 @@ else
RANLIB="$ac_cv_prog_RANLIB"
fi
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_AR="ar"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
# Extract the first word of "rm", so it can be a program name with args.
set dummy rm; ac_word=$2
{ echo "$as_me:$LINENO: checking for $ac_word" >&5
@@ -8238,6 +8153,8 @@ echo "$as_me: error: ${with_tclinclude} directory doesn't contain tclsh" >&2;}
{ (exit 1); exit 1; }; }
fi
fi
+fi
+
if test x"${ac_cv_path_tclsh}" = x ; then
{ echo "$as_me:$LINENO: result: none" >&5
@@ -8299,8 +8216,6 @@ echo "${ECHO_T}${ac_cv_path_tclsh}" >&6; }
fi
-fi
-
# Extract the first word of "zip", so it can be a program name with args.
set dummy zip; ac_word=$2
{ echo "$as_me:$LINENO: checking for $ac_word" >&5
@@ -11120,7 +11035,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 11123 "configure"
+#line 11038 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12779,14594 +12694,6 @@ fi
done
-# Check whether --enable-shared was given.
-if test "${enable_shared+set}" = set; then
- enableval=$enable_shared; p=${PACKAGE-default}
- case $enableval in
- yes) enable_shared=yes ;;
- no) enable_shared=no ;;
- *)
- enable_shared=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_shared=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_shared=yes
-fi
-
-
-# Check whether --enable-static was given.
-if test "${enable_static+set}" = set; then
- enableval=$enable_static; p=${PACKAGE-default}
- case $enableval in
- yes) enable_static=yes ;;
- no) enable_static=no ;;
- *)
- enable_static=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_static=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_static=yes
-fi
-
-
-# Check whether --enable-fast-install was given.
-if test "${enable_fast_install+set}" = set; then
- enableval=$enable_fast_install; p=${PACKAGE-default}
- case $enableval in
- yes) enable_fast_install=yes ;;
- no) enable_fast_install=no ;;
- *)
- enable_fast_install=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_fast_install=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_fast_install=yes
-fi
-
-
-{ echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
-echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; }
-if test "${lt_cv_path_SED+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Loop through the user's path and test for sed and gsed.
-# Then use that list of sed's as ones to test for truncation.
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for lt_ac_prog in sed gsed; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
- lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
- fi
- done
- done
-done
-lt_ac_max=0
-lt_ac_count=0
-# Add /usr/xpg4/bin/sed as it is typically found on Solaris
-# along with /bin/sed that truncates output.
-for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
- test ! -f $lt_ac_sed && continue
- cat /dev/null > conftest.in
- lt_ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >conftest.in
- # Check for GNU sed and select it if it is found.
- if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
- lt_cv_path_SED=$lt_ac_sed
- break
- fi
- while true; do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo >>conftest.nl
- $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
- cmp -s conftest.out conftest.nl || break
- # 10000 chars as input seems more than enough
- test $lt_ac_count -gt 10 && break
- lt_ac_count=`expr $lt_ac_count + 1`
- if test $lt_ac_count -gt $lt_ac_max; then
- lt_ac_max=$lt_ac_count
- lt_cv_path_SED=$lt_ac_sed
- fi
- done
-done
-
-fi
-
-SED=$lt_cv_path_SED
-{ echo "$as_me:$LINENO: result: $SED" >&5
-echo "${ECHO_T}$SED" >&6; }
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then
- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
- with_gnu_ld=no
-fi
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
-echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [\\/]* | ?:[\\/]*)
- re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- { echo "$as_me:$LINENO: checking for GNU ld" >&5
-echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
-else
- { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
-echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
-fi
-if test "${lt_cv_path_LD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- { echo "$as_me:$LINENO: result: $LD" >&5
-echo "${ECHO_T}$LD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
-echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
- { (exit 1); exit 1; }; }
-{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
-echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
-echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$lt_cv_prog_gnu_ld
-
-
-{ echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
-echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; }
-if test "${lt_cv_ld_reload_flag+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_ld_reload_flag='-r'
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
-echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; }
-reload_flag=$lt_cv_ld_reload_flag
-case $reload_flag in
-"" | " "*) ;;
-*) reload_flag=" $reload_flag" ;;
-esac
-reload_cmds='$LD$reload_flag -o $output$reload_objs'
-case $host_os in
- darwin*)
- if test "$GCC" = yes; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r $compiler_flags -o $output$reload_objs'
- else
- reload_cmds='$LD$reload_flag -o $output$reload_objs'
- fi
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5
-echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6; }
-if test "${lt_cv_deplibs_check_method+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_file_magic_cmd='$MAGIC_CMD'
-lt_cv_file_magic_test_file=
-lt_cv_deplibs_check_method='unknown'
-# Need to set the preceding variable on all platforms that support
-# interlibrary dependencies.
-# 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
-# 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
-# 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
-
-case $host_os in
-aix4* | aix5*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-beos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-bsdi[45]*)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- lt_cv_file_magic_test_file=/shlib/libc.so
- ;;
-
-cygwin*)
- # func_win32_libid is a shell function defined in ltmain.sh
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- ;;
-
-mingw* | pw32*)
- # Base MSYS/MinGW do not provide the 'file' command needed by
- # func_win32_libid shell function, so use a weaker test based on 'objdump'.
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- ;;
-
-darwin* | rhapsody*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-freebsd* | kfreebsd*-gnu | dragonfly*)
- if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
- case $host_cpu in
- i*86 )
- # Not sure whether the presence of OpenBSD here was a mistake.
- # Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
- ;;
- esac
- else
- lt_cv_deplibs_check_method=pass_all
- fi
- ;;
-
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-hpux10.20* | hpux11*)
- lt_cv_file_magic_cmd=/usr/bin/file
- case $host_cpu in
- ia64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
- lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
- ;;
- hppa*64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
- lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
- ;;
- *)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
- lt_cv_file_magic_test_file=/usr/lib/libc.sl
- ;;
- esac
- ;;
-
-interix3*)
- # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-# This must be Linux ELF.
-linux*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
- fi
- ;;
-
-newos6*)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=/usr/lib/libnls.so
- ;;
-
-nto-qnx*)
- lt_cv_deplibs_check_method=unknown
- ;;
-
-openbsd*)
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
- fi
- ;;
-
-osf3* | osf4* | osf5*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-solaris*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv4 | sysv4.3*)
- case $host_vendor in
- motorola)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
- ;;
- ncr)
- lt_cv_deplibs_check_method=pass_all
- ;;
- sequent)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
- ;;
- sni)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
- lt_cv_file_magic_test_file=/lib/libc.so
- ;;
- siemens)
- lt_cv_deplibs_check_method=pass_all
- ;;
- pc)
- lt_cv_deplibs_check_method=pass_all
- ;;
- esac
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-esac
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
-echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; }
-file_magic_cmd=$lt_cv_file_magic_cmd
-deplibs_check_method=$lt_cv_deplibs_check_method
-test -z "$deplibs_check_method" && deplibs_check_method=unknown
-
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-# Check whether --enable-libtool-lock was given.
-if test "${enable_libtool_lock+set}" = set; then
- enableval=$enable_libtool_lock;
-fi
-
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-# Some flags need to be propagated to the compiler or linker for good
-# libtool support.
-case $host in
-ia64-*-hpux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- case `/usr/bin/file conftest.$ac_objext` in
- *ELF-32*)
- HPUX_IA64_MODE="32"
- ;;
- *ELF-64*)
- HPUX_IA64_MODE="64"
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-*-*-irix6*)
- # Find out which ABI we are using.
- echo '#line 13267 "configure"' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- if test "$lt_cv_prog_gnu_ld" = yes; then
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -melf32bsmip"
- ;;
- *N32*)
- LD="${LD-ld} -melf32bmipn32"
- ;;
- *64-bit*)
- LD="${LD-ld} -melf64bmip"
- ;;
- esac
- else
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -32"
- ;;
- *N32*)
- LD="${LD-ld} -n32"
- ;;
- *64-bit*)
- LD="${LD-ld} -64"
- ;;
- esac
- fi
- fi
- rm -rf conftest*
- ;;
-
-x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- case `/usr/bin/file conftest.o` in
- *32-bit*)
- case $host in
- x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
- ;;
- ppc64-*linux*|powerpc64-*linux*)
- LD="${LD-ld} -m elf32ppclinux"
- ;;
- s390x-*linux*)
- LD="${LD-ld} -m elf_s390"
- ;;
- sparc64-*linux*)
- LD="${LD-ld} -m elf32_sparc"
- ;;
- esac
- ;;
- *64-bit*)
- case $host in
- x86_64-*linux*)
- LD="${LD-ld} -m elf_x86_64"
- ;;
- ppc*-*linux*|powerpc*-*linux*)
- LD="${LD-ld} -m elf64ppc"
- ;;
- s390*-*linux*)
- LD="${LD-ld} -m elf64_s390"
- ;;
- sparc*-*linux*)
- LD="${LD-ld} -m elf64_sparc"
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-*-*-sco3.2v5*)
- # On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -belf"
- { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
-echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; }
-if test "${lt_cv_cc_needs_belf+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- lt_cv_cc_needs_belf=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- lt_cv_cc_needs_belf=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
-echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; }
- if test x"$lt_cv_cc_needs_belf" != x"yes"; then
- # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
- CFLAGS="$SAVE_CFLAGS"
- fi
- ;;
-sparc*-*solaris*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- case `/usr/bin/file conftest.o` in
- *64-bit*)
- case $lt_cv_prog_gnu_ld in
- yes*) LD="${LD-ld} -m elf64_sparc" ;;
- *) LD="${LD-ld} -64" ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-
-esac
-
-need_locks="$enable_libtool_lock"
-
-
-
-
-if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
-echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; }
-if test -z "$CXXCPP"; then
- if test "${ac_cv_prog_CXXCPP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Double quotes because CXXCPP needs to be expanded
- for CXXCPP in "$CXX -E" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_cxx_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_cxx_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- break
-fi
-
- done
- ac_cv_prog_CXXCPP=$CXXCPP
-
-fi
- CXXCPP=$ac_cv_prog_CXXCPP
-else
- ac_cv_prog_CXXCPP=$CXXCPP
-fi
-{ echo "$as_me:$LINENO: result: $CXXCPP" >&5
-echo "${ECHO_T}$CXXCPP" >&6; }
-ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_cxx_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_cxx_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
-else
- { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-fi
-
-
-ac_ext=f
-ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
-ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_f77_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- for ac_prog in g77 f77 xlf frt pgf77 cf77 fort77 fl32 af77 f90 xlf90 pgf90 pghpf epcf90 gfortran g95 f95 fort xlf95 ifort ifc efc pgf95 lf95 ftn
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_F77+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$F77"; then
- ac_cv_prog_F77="$F77" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-F77=$ac_cv_prog_F77
-if test -n "$F77"; then
- { echo "$as_me:$LINENO: result: $F77" >&5
-echo "${ECHO_T}$F77" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$F77" && break
- done
-fi
-if test -z "$F77"; then
- ac_ct_F77=$F77
- for ac_prog in g77 f77 xlf frt pgf77 cf77 fort77 fl32 af77 f90 xlf90 pgf90 pghpf epcf90 gfortran g95 f95 fort xlf95 ifort ifc efc pgf95 lf95 ftn
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_F77+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_F77"; then
- ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_F77="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_F77=$ac_cv_prog_ac_ct_F77
-if test -n "$ac_ct_F77"; then
- { echo "$as_me:$LINENO: result: $ac_ct_F77" >&5
-echo "${ECHO_T}$ac_ct_F77" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$ac_ct_F77" && break
-done
-
- if test "x$ac_ct_F77" = x; then
- F77=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- F77=$ac_ct_F77
- fi
-fi
-
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for Fortran 77 compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler --version >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -v >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -V >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-rm -f a.out
-
-# If we don't use `.F' as extension, the preprocessor is not run on the
-# input file. (Note that this only needs to work for GNU compilers.)
-ac_save_ext=$ac_ext
-ac_ext=F
-{ echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6; }
-if test "${ac_cv_f77_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
- program main
-#ifndef __GNUC__
- choke me
-#endif
-
- end
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_compiler_gnu=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_f77_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6; }
-ac_ext=$ac_save_ext
-ac_test_FFLAGS=${FFLAGS+set}
-ac_save_FFLAGS=$FFLAGS
-FFLAGS=
-{ echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5
-echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_f77_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- FFLAGS=-g
-cat >conftest.$ac_ext <<_ACEOF
- program main
-
- end
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_f77_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_prog_f77_g=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
-echo "${ECHO_T}$ac_cv_prog_f77_g" >&6; }
-if test "$ac_test_FFLAGS" = set; then
- FFLAGS=$ac_save_FFLAGS
-elif test $ac_cv_prog_f77_g = yes; then
- if test "x$ac_cv_f77_compiler_gnu" = xyes; then
- FFLAGS="-g -O2"
- else
- FFLAGS="-g"
- fi
-else
- if test "x$ac_cv_f77_compiler_gnu" = xyes; then
- FFLAGS="-O2"
- else
- FFLAGS=
- fi
-fi
-
-G77=`test $ac_compiler_gnu = yes && echo yes`
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
-
-# find the maximum length of command line arguments
-{ echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
-echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6; }
-if test "${lt_cv_sys_max_cmd_len+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- i=0
- teststring="ABCD"
-
- case $build_os in
- msdosdjgpp*)
- # On DJGPP, this test can blow up pretty badly due to problems in libc
- # (any single argument exceeding 2000 bytes causes a buffer overrun
- # during glob expansion). Even if it were fixed, the result of this
- # check would be larger than it should be.
- lt_cv_sys_max_cmd_len=12288; # 12K is about right
- ;;
-
- gnu*)
- # Under GNU Hurd, this test is not required because there is
- # no limit to the length of command line arguments.
- # Libtool will interpret -1 as no limit whatsoever
- lt_cv_sys_max_cmd_len=-1;
- ;;
-
- cygwin* | mingw*)
- # On Win9x/ME, this test blows up -- it succeeds, but takes
- # about 5 minutes as the teststring grows exponentially.
- # Worse, since 9x/ME are not pre-emptively multitasking,
- # you end up with a "frozen" computer, even though with patience
- # the test eventually succeeds (with a max line length of 256k).
- # Instead, let's just punt: use the minimum linelength reported by
- # all of the supported platforms: 8192 (on NT/2K/XP).
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- amigaos*)
- # On AmigaOS with pdksh, this test takes hours, literally.
- # So we just punt and use a minimum line length of 8192.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
- # This has been around since 386BSD, at least. Likely further.
- if test -x /sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
- elif test -x /usr/sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
- else
- lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
- fi
- # And add a safety zone
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- ;;
-
- interix*)
- # We know the value 262144 and hardcode it with a safety zone (like BSD)
- lt_cv_sys_max_cmd_len=196608
- ;;
-
- osf*)
- # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
- # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
- # nice to cause kernel panics so lets avoid the loop below.
- # First set a reasonable default.
- lt_cv_sys_max_cmd_len=16384
- #
- if test -x /sbin/sysconfig; then
- case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
- *1*) lt_cv_sys_max_cmd_len=-1 ;;
- esac
- fi
- ;;
- sco3.2v5*)
- lt_cv_sys_max_cmd_len=102400
- ;;
- sysv5* | sco5v6* | sysv4.2uw2*)
- kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
- if test -n "$kargmax"; then
- lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
- else
- lt_cv_sys_max_cmd_len=32768
- fi
- ;;
- *)
- # If test is not a shell built-in, we'll probably end up computing a
- # maximum length that is only half of the actual maximum length, but
- # we can't tell.
- SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
- while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \
- = "XX$teststring") >/dev/null 2>&1 &&
- new_result=`expr "X$teststring" : ".*" 2>&1` &&
- lt_cv_sys_max_cmd_len=$new_result &&
- test $i != 17 # 1/2 MB should be enough
- do
- i=`expr $i + 1`
- teststring=$teststring$teststring
- done
- teststring=
- # Add a significant safety factor because C++ compilers can tack on massive
- # amounts of additional arguments before passing them to the linker.
- # It appears as though 1/2 is a usable value.
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
- ;;
- esac
-
-fi
-
-if test -n $lt_cv_sys_max_cmd_len ; then
- { echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
-echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6; }
-else
- { echo "$as_me:$LINENO: result: none" >&5
-echo "${ECHO_T}none" >&6; }
-fi
-
-
-
-
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-{ echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5
-echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6; }
-if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-# These are sane defaults that work on at least a few old systems.
-# [They come from Ultrix. What could be older than Ultrix?!! ;)]
-
-# Character class describing NM global symbol codes.
-symcode='[BCDEGRST]'
-
-# Regexp to match symbols that can be accessed directly from C.
-sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
-
-# Transform an extracted symbol line into a proper C declaration
-lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
-
-# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
-
-# Define system-specific variables.
-case $host_os in
-aix*)
- symcode='[BCDT]'
- ;;
-cygwin* | mingw* | pw32*)
- symcode='[ABCDGISTW]'
- ;;
-hpux*) # Its linker distinguishes data from code symbols
- if test "$host_cpu" = ia64; then
- symcode='[ABCDEGRST]'
- fi
- lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
- lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
- ;;
-linux*)
- if test "$host_cpu" = ia64; then
- symcode='[ABCDGIRSTW]'
- lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
- lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
- fi
- ;;
-irix* | nonstopux*)
- symcode='[BCDEGRST]'
- ;;
-osf*)
- symcode='[BCDEGQRST]'
- ;;
-solaris*)
- symcode='[BDRT]'
- ;;
-sco3.2v5*)
- symcode='[DT]'
- ;;
-sysv4.2uw2*)
- symcode='[DT]'
- ;;
-sysv5* | sco5v6* | unixware* | OpenUNIX*)
- symcode='[ABDT]'
- ;;
-sysv4)
- symcode='[DFNSTU]'
- ;;
-esac
-
-# Handle CRLF in mingw tool chain
-opt_cr=
-case $build_os in
-mingw*)
- opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-case `$NM -V 2>&1` in
-*GNU* | *'with BFD'*)
- symcode='[ABCDGIRSTW]' ;;
-esac
-
-# Try without a prefix undercore, then with it.
-for ac_symprfx in "" "_"; do
-
- # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
- symxfrm="\\1 $ac_symprfx\\2 \\2"
-
- # Write the raw and C identifiers.
- lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
-
- # Check to see that the pipe works correctly.
- pipe_works=no
-
- rm -f conftest*
- cat > conftest.$ac_ext <<EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func();return(0);}
-EOF
-
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # Now try to grab the symbols.
- nlist=conftest.nm
- if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
- (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && test -s "$nlist"; then
- # Try sorting and uniquifying the output.
- if sort "$nlist" | uniq > "$nlist"T; then
- mv -f "$nlist"T "$nlist"
- else
- rm -f "$nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if grep ' nm_test_var$' "$nlist" >/dev/null; then
- if grep ' nm_test_func$' "$nlist" >/dev/null; then
- cat <<EOF > conftest.$ac_ext
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-EOF
- # Now generate the symbol file.
- eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
-
- cat <<EOF >> conftest.$ac_ext
-#if defined (__STDC__) && __STDC__
-# define lt_ptr_t void *
-#else
-# define lt_ptr_t char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- lt_ptr_t address;
-}
-lt_preloaded_symbols[] =
-{
-EOF
- $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
- cat <<\EOF >> conftest.$ac_ext
- {0, (lt_ptr_t) 0}
-};
-
-#ifdef __cplusplus
-}
-#endif
-EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- lt_save_LIBS="$LIBS"
- lt_save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && test -s conftest${ac_exeext}; then
- pipe_works=yes
- fi
- LIBS="$lt_save_LIBS"
- CFLAGS="$lt_save_CFLAGS"
- else
- echo "cannot find nm_test_func in $nlist" >&5
- fi
- else
- echo "cannot find nm_test_var in $nlist" >&5
- fi
- else
- echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
- fi
- else
- echo "$progname: failed program was:" >&5
- cat conftest.$ac_ext >&5
- fi
- rm -f conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$pipe_works" = yes; then
- break
- else
- lt_cv_sys_global_symbol_pipe=
- fi
-done
-
-fi
-
-if test -z "$lt_cv_sys_global_symbol_pipe"; then
- lt_cv_sys_global_symbol_to_cdecl=
-fi
-if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
- { echo "$as_me:$LINENO: result: failed" >&5
-echo "${ECHO_T}failed" >&6; }
-else
- { echo "$as_me:$LINENO: result: ok" >&5
-echo "${ECHO_T}ok" >&6; }
-fi
-
-{ echo "$as_me:$LINENO: checking for objdir" >&5
-echo $ECHO_N "checking for objdir... $ECHO_C" >&6; }
-if test "${lt_cv_objdir+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- rm -f .libs 2>/dev/null
-mkdir .libs 2>/dev/null
-if test -d .libs; then
- lt_cv_objdir=.libs
-else
- # MS-DOS does not allow filenames that begin with a dot.
- lt_cv_objdir=_libs
-fi
-rmdir .libs 2>/dev/null
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5
-echo "${ECHO_T}$lt_cv_objdir" >&6; }
-objdir=$lt_cv_objdir
-
-
-
-
-
-case $host_os in
-aix3*)
- # AIX sometimes has problems with the GCC collect2 program. For some
- # reason, if we set the COLLECT_NAMES environment variable, the problems
- # vanish in a puff of smoke.
- if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
- fi
- ;;
-esac
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e 1s/^X//'
-sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
-# Constants:
-rm="rm -f"
-
-# Global variables:
-default_ofile=mklib
-can_build_shared=yes
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-ltmain="$ac_aux_dir/ltmain.sh"
-ofile="$default_ofile"
-with_gnu_ld="$lt_cv_prog_gnu_ld"
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ar; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$AR"; then
- ac_cv_prog_AR="$AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AR="${ac_tool_prefix}ar"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-AR=$ac_cv_prog_AR
-if test -n "$AR"; then
- { echo "$as_me:$LINENO: result: $AR" >&5
-echo "${ECHO_T}$AR" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_AR"; then
- ac_ct_AR=$AR
- # Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_AR"; then
- ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_AR="ar"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_AR=$ac_cv_prog_ac_ct_AR
-if test -n "$ac_ct_AR"; then
- { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
-echo "${ECHO_T}$ac_ct_AR" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_AR" = x; then
- AR="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- AR=$ac_ct_AR
- fi
-else
- AR="$ac_cv_prog_AR"
-fi
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- { echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_RANLIB" = x; then
- RANLIB=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- RANLIB=$ac_ct_RANLIB
- fi
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
-set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$STRIP"; then
- ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_STRIP="${ac_tool_prefix}strip"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-STRIP=$ac_cv_prog_STRIP
-if test -n "$STRIP"; then
- { echo "$as_me:$LINENO: result: $STRIP" >&5
-echo "${ECHO_T}$STRIP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_STRIP"; then
- ac_ct_STRIP=$STRIP
- # Extract the first word of "strip", so it can be a program name with args.
-set dummy strip; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_STRIP"; then
- ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_STRIP="strip"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
-if test -n "$ac_ct_STRIP"; then
- { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
-echo "${ECHO_T}$ac_ct_STRIP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_STRIP" = x; then
- STRIP=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet. If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
- STRIP=$ac_ct_STRIP
- fi
-else
- STRIP="$ac_cv_prog_STRIP"
-fi
-
-
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
-
-# Set sane defaults for various variables
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-test -z "$AS" && AS=as
-test -z "$CC" && CC=cc
-test -z "$LTCC" && LTCC=$CC
-test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
-test -z "$DLLTOOL" && DLLTOOL=dlltool
-test -z "$LD" && LD=ld
-test -z "$LN_S" && LN_S="ln -s"
-test -z "$MAGIC_CMD" && MAGIC_CMD=file
-test -z "$NM" && NM=nm
-test -z "$SED" && SED=sed
-test -z "$OBJDUMP" && OBJDUMP=objdump
-test -z "$RANLIB" && RANLIB=:
-test -z "$STRIP" && STRIP=:
-test -z "$ac_objext" && ac_objext=o
-
-# Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
-old_postinstall_cmds='chmod 644 $oldlib'
-old_postuninstall_cmds=
-
-if test -n "$RANLIB"; then
- case $host_os in
- openbsd*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
- ;;
- *)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
- ;;
- esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
-fi
-
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-
-# Only perform the check for file, if the check method requires it
-case $deplibs_check_method in
-file_magic*)
- if test "$file_magic_cmd" = '$MAGIC_CMD'; then
- { echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
-echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $MAGIC_CMD in
-[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/${ac_tool_prefix}file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
-echo "${ECHO_T}$MAGIC_CMD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-if test -z "$lt_cv_path_MAGIC_CMD"; then
- if test -n "$ac_tool_prefix"; then
- { echo "$as_me:$LINENO: checking for file" >&5
-echo $ECHO_N "checking for file... $ECHO_C" >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $MAGIC_CMD in
-[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
-echo "${ECHO_T}$MAGIC_CMD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- else
- MAGIC_CMD=:
- fi
-fi
-
- fi
- ;;
-esac
-
-enable_dlopen=yes
-enable_win32_dll=no
-
-# Check whether --enable-libtool-lock was given.
-if test "${enable_libtool_lock+set}" = set; then
- enableval=$enable_libtool_lock;
-fi
-
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-
-# Check whether --with-pic was given.
-if test "${with_pic+set}" = set; then
- withval=$with_pic; pic_mode="$withval"
-else
- pic_mode=default
-fi
-
-test -z "$pic_mode" && pic_mode=default
-
-# Use C for the default configuration in the libtool script
-tagname=
-lt_save_CC="$CC"
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# Source file extension for C test sources.
-ac_ext=c
-
-# Object file extension for compiled C test sources.
-objext=o
-objext=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;\n"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}\n'
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-
-ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm conftest*
-
-
-
-lt_prog_compiler_no_builtin_flag=
-
-if test "$GCC" = yes; then
- lt_prog_compiler_no_builtin_flag=' -fno-builtin'
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
-echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_rtti_exceptions=no
- ac_outfile=conftest.$ac_objext
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="-fno-rtti -fno-exceptions"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14985: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:14989: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_rtti_exceptions=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; }
-
-if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
- lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
-else
- :
-fi
-
-fi
-
-lt_prog_compiler_wl=
-lt_prog_compiler_pic=
-lt_prog_compiler_static=
-
-{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
-
- if test "$GCC" = yes; then
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_static='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- fi
- ;;
-
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
- ;;
-
- beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic='-DDLL_EXPORT'
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic='-fno-common'
- ;;
-
- interix3*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- lt_prog_compiler_can_build_shared=no
- enable_shared=no
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic=-Kconform_pic
- fi
- ;;
-
- hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic='-fPIC'
- ;;
- esac
- ;;
-
- *)
- lt_prog_compiler_pic='-fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- lt_prog_compiler_wl='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- else
- lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- case $cc_basename in
- xlc*)
- lt_prog_compiler_pic='-qnocommon'
- lt_prog_compiler_wl='-Wl,'
- ;;
- esac
- ;;
-
- mingw* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic='-DDLL_EXPORT'
- ;;
-
- hpux9* | hpux10* | hpux11*)
- lt_prog_compiler_wl='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- lt_prog_compiler_static='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- lt_prog_compiler_wl='-Wl,'
- # PIC (with -KPIC) is the default.
- lt_prog_compiler_static='-non_shared'
- ;;
-
- newsos6)
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- linux*)
- case $cc_basename in
- icc* | ecc*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-fpic'
- lt_prog_compiler_static='-Bstatic'
- ;;
- ccc*)
- lt_prog_compiler_wl='-Wl,'
- # All Alpha code is PIC.
- lt_prog_compiler_static='-non_shared'
- ;;
- esac
- ;;
-
- osf3* | osf4* | osf5*)
- lt_prog_compiler_wl='-Wl,'
- # All OSF/1 code is PIC.
- lt_prog_compiler_static='-non_shared'
- ;;
-
- solaris*)
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- lt_prog_compiler_wl='-Qoption ld ';;
- *)
- lt_prog_compiler_wl='-Wl,';;
- esac
- ;;
-
- sunos4*)
- lt_prog_compiler_wl='-Qoption ld '
- lt_prog_compiler_pic='-PIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- lt_prog_compiler_pic='-Kconform_pic'
- lt_prog_compiler_static='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- unicos*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_can_build_shared=no
- ;;
-
- uts4*)
- lt_prog_compiler_pic='-pic'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- *)
- lt_prog_compiler_can_build_shared=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic" >&6; }
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic"; then
-
-{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6; }
-if test "${lt_prog_compiler_pic_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_prog_compiler_pic_works=no
- ac_outfile=conftest.$ac_objext
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15253: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:15257: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_prog_compiler_pic_works=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6; }
-
-if test x"$lt_prog_compiler_pic_works" = xyes; then
- case $lt_prog_compiler_pic in
- "" | " "*) ;;
- *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
- esac
-else
- lt_prog_compiler_pic=
- lt_prog_compiler_can_build_shared=no
-fi
-
-fi
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic=
- ;;
- *)
- lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
- ;;
-esac
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
-{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
-if test "${lt_prog_compiler_static_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_prog_compiler_static_works=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- printf "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_prog_compiler_static_works=yes
- fi
- else
- lt_prog_compiler_static_works=yes
- fi
- fi
- $rm conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5
-echo "${ECHO_T}$lt_prog_compiler_static_works" >&6; }
-
-if test x"$lt_prog_compiler_static_works" = xyes; then
- :
-else
- lt_prog_compiler_static=
-fi
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_c_o=no
- $rm -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15357: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:15361: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o=yes
- fi
- fi
- chmod u+w . 2>&5
- $rm conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
- $rm out/* && rmdir out
- cd ..
- rmdir conftest
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6; }
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
- hard_links=yes
- $rm conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6; }
- if test "$hard_links" = no; then
- { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
-
- runpath_var=
- allow_undefined_flag=
- enable_shared_with_static_runtimes=no
- archive_cmds=
- archive_expsym_cmds=
- old_archive_From_new_cmds=
- old_archive_from_expsyms_cmds=
- export_dynamic_flag_spec=
- whole_archive_flag_spec=
- thread_safe_flag_spec=
- hardcode_libdir_flag_spec=
- hardcode_libdir_flag_spec_ld=
- hardcode_libdir_separator=
- hardcode_direct=no
- hardcode_minus_L=no
- hardcode_shlibpath_var=unsupported
- link_all_deplibs=unknown
- hardcode_automatic=no
- module_cmds=
- module_expsym_cmds=
- always_export_symbols=no
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- include_expsyms=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- extract_expsyms_cmds=
- # Just being paranoid about ensuring that cc_basename is set.
- for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
- case $host_os in
- cygwin* | mingw* | pw32*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- esac
-
- ld_shlibs=yes
- if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix3* | aix4* | aix5*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs=no
- cat <<EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-EOF
- fi
- ;;
-
- amigaos*)
- archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
-
- # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we can't use
- # them.
- ld_shlibs=no
- ;;
-
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- cygwin* | mingw* | pw32*)
- # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec='-L$libdir'
- allow_undefined_flag=unsupported
- always_export_symbols=no
- enable_shared_with_static_runtimes=yes
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- interix3*)
- hardcode_direct=no
- hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- linux*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- tmp_addflag=
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- esac
- archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test $supports_anon_versioning = yes; then
- archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- $echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
- else
- ld_shlibs=no
- fi
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- ld_shlibs=no
- cat <<EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-EOF
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
-
- if test "$ld_shlibs" = no; then
- runpath_var=
- hardcode_libdir_flag_spec=
- export_dynamic_flag_spec=
- whole_archive_flag_spec=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- allow_undefined_flag=unsupported
- always_export_symbols=yes
- archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct=unsupported
- fi
- ;;
-
- aix4* | aix5*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix5*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds=''
- hardcode_direct=yes
- hardcode_libdir_separator=':'
- link_all_deplibs=yes
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- hardcode_direct=yes
- else
- # We have old collect2
- hardcode_direct=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L=yes
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_libdir_separator=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag='-berok'
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`; fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag="-z nodefs"
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`; fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag=' ${wl}-bernotok'
- allow_undefined_flag=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec='$convenience'
- archive_cmds_need_lc=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs=no
- ;;
-
- bsdi[45]*)
- export_dynamic_flag_spec=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- allow_undefined_flag=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_From_new_cmds='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path='`cygpath -w "$srcfile"`'
- enable_shared_with_static_runtimes=yes
- ;;
-
- darwin* | rhapsody*)
- case $host_os in
- rhapsody* | darwin1.[012])
- allow_undefined_flag='${wl}-undefined ${wl}suppress'
- ;;
- *) # Darwin 1.3 on
- if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
- allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- else
- case ${MACOSX_DEPLOYMENT_TARGET} in
- 10.[012])
- allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- ;;
- 10.*)
- allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup'
- ;;
- esac
- fi
- ;;
- esac
- archive_cmds_need_lc=no
- hardcode_direct=no
- hardcode_automatic=yes
- hardcode_shlibpath_var=unsupported
- whole_archive_flag_spec=''
- link_all_deplibs=yes
- if test "$GCC" = yes ; then
- output_verbose_link_cmd='echo'
- archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- else
- case $cc_basename in
- xlc*)
- output_verbose_link_cmd='echo'
- archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
- module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
- fi
- ;;
-
- dgux*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- freebsd1*)
- ld_shlibs=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | kfreebsd*-gnu | dragonfly*)
- archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- export_dynamic_flag_spec='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
-
- hardcode_direct=yes
- export_dynamic_flag_spec='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_libdir_flag_spec_ld='+b $libdir'
- hardcode_direct=no
- hardcode_shlibpath_var=no
- ;;
- *)
- hardcode_direct=yes
- export_dynamic_flag_spec='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_ld='-rpath $libdir'
- fi
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- link_all_deplibs=yes
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- newsos6)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_shlibpath_var=no
- ;;
-
- openbsd*)
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- else
- case $host_os in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- *)
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- ;;
-
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- allow_undefined_flag=unsupported
- archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec='-rpath $libdir'
- fi
- hardcode_libdir_separator=:
- ;;
-
- solaris*)
- no_undefined_flag=' -z text'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
- else
- wlarc=''
- archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_shlibpath_var=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine linker options so we
- # cannot just pass the convience library names through
- # without $wl, iff we do not link with $LD.
- # Luckily, gcc supports the same syntax we need for Sun Studio.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- case $wlarc in
- '')
- whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
- *)
- whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
- esac ;;
- esac
- link_all_deplibs=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- reload_cmds='$CC -r -o $output$reload_objs'
- hardcode_direct=no
- ;;
- motorola)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var=no
- ;;
-
- sysv4.3*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- export_dynamic_flag_spec='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ld_shlibs=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
- no_undefined_flag='${wl}-z,text'
- archive_cmds_need_lc=no
- hardcode_shlibpath_var=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- no_undefined_flag='${wl}-z,text'
- allow_undefined_flag='${wl}-z,nodefs'
- archive_cmds_need_lc=no
- hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- hardcode_libdir_separator=':'
- link_all_deplibs=yes
- export_dynamic_flag_spec='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- *)
- ld_shlibs=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $ld_shlibs" >&5
-echo "${ECHO_T}$ld_shlibs" >&6; }
-test "$ld_shlibs" = no && can_build_shared=no
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
- $rm conftest*
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl
- pic_flag=$lt_prog_compiler_pic
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag
- allow_undefined_flag=
- if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
- (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
- then
- archive_cmds_need_lc=no
- else
- archive_cmds_need_lc=yes
- fi
- allow_undefined_flag=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $rm conftest*
- { echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5
-echo "${ECHO_T}$archive_cmds_need_lc" >&6; }
- ;;
- esac
- fi
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-if test "$GCC" = yes; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix4* | aix5*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $rm \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='.dylib'
- # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
- if test "$GCC" = yes; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
- else
- sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
- fi
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-kfreebsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='GNU ld.so'
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[123]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- freebsd*) # from 4.6 on
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix3*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-knetbsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='GNU ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-nto-qnx*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- shlibpath_overrides_runpath=no
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- shlibpath_overrides_runpath=yes
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
-hardcode_action=
-if test -n "$hardcode_libdir_flag_spec" || \
- test -n "$runpath_var" || \
- test "X$hardcode_automatic" = "Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no &&
- test "$hardcode_minus_L" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action=unsupported
-fi
-{ echo "$as_me:$LINENO: result: $hardcode_action" >&5
-echo "${ECHO_T}$hardcode_action" >&6; }
-
-if test "$hardcode_action" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-striplib=
-old_striplib=
-{ echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
-echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; }
-if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
- ;;
- *)
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- ;;
- esac
-fi
-
-if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- mingw* | pw32*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- cygwin*)
- lt_cv_dlopen="dlopen"
- lt_cv_dlopen_libs=
- ;;
-
- darwin*)
- # if libdl is installed we need to link against it
- { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dl_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_dl_dlopen=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
-if test $ac_cv_lib_dl_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-
- lt_cv_dlopen="dyld"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
-
-fi
-
- ;;
-
- *)
- { echo "$as_me:$LINENO: checking for shl_load" >&5
-echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; }
-if test "${ac_cv_func_shl_load+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define shl_load innocuous_shl_load
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char shl_load (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef shl_load
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char shl_load ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_shl_load || defined __stub___shl_load
-choke me
-#endif
-
-int
-main ()
-{
-return shl_load ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_shl_load=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_func_shl_load=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
-echo "${ECHO_T}$ac_cv_func_shl_load" >&6; }
-if test $ac_cv_func_shl_load = yes; then
- lt_cv_dlopen="shl_load"
-else
- { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
-echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; }
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char shl_load ();
-int
-main ()
-{
-return shl_load ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dld_shl_load=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_dld_shl_load=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; }
-if test $ac_cv_lib_dld_shl_load = yes; then
- lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
-else
- { echo "$as_me:$LINENO: checking for dlopen" >&5
-echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; }
-if test "${ac_cv_func_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define dlopen innocuous_dlopen
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char dlopen (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef dlopen
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_dlopen || defined __stub___dlopen
-choke me
-#endif
-
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_func_dlopen=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
-echo "${ECHO_T}$ac_cv_func_dlopen" >&6; }
-if test $ac_cv_func_dlopen = yes; then
- lt_cv_dlopen="dlopen"
-else
- { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dl_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_dl_dlopen=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
-if test $ac_cv_lib_dl_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
- { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
-echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; }
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsvld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_svld_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_svld_dlopen=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; }
-if test $ac_cv_lib_svld_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
-else
- { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
-echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; }
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dld_link ();
-int
-main ()
-{
-return dld_link ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dld_dld_link=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_dld_dld_link=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; }
-if test $ac_cv_lib_dld_dld_link = yes; then
- lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
- ;;
- esac
-
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
- else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
-echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; }
-if test "${lt_cv_dlopen_self+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<EOF
-#line 17809 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- exit (status);
-}
-EOF
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&5 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self=no
- fi
-fi
-rm -fr conftest*
-
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self" >&6; }
-
- if test "x$lt_cv_dlopen_self" = xyes; then
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
- { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
-echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; }
-if test "${lt_cv_dlopen_self_static+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self_static=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<EOF
-#line 17909 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- exit (status);
-}
-EOF
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&5 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self_static=no
- fi
-fi
-rm -fr conftest*
-
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; }
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
-
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
-fi
-
-
-# Report which library types will actually be built
-{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
-echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $can_build_shared" >&5
-echo "${ECHO_T}$can_build_shared" >&6; }
-
-{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
-echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; }
-test "$can_build_shared" = "no" && enable_shared=no
-
-# On AIX, shared libraries and static libraries use the same namespace, and
-# are all built from PIC.
-case $host_os in
-aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-
-aix4* | aix5*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $enable_shared" >&5
-echo "${ECHO_T}$enable_shared" >&6; }
-
-{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5
-echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; }
-# Make sure either enable_shared or enable_static is yes.
-test "$enable_shared" = yes || enable_static=yes
-{ echo "$as_me:$LINENO: result: $enable_static" >&5
-echo "${ECHO_T}$enable_static" >&6; }
-
-# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- compiler \
- CC \
- LD \
- lt_prog_compiler_wl \
- lt_prog_compiler_pic \
- lt_prog_compiler_static \
- lt_prog_compiler_no_builtin_flag \
- export_dynamic_flag_spec \
- thread_safe_flag_spec \
- whole_archive_flag_spec \
- enable_shared_with_static_runtimes \
- old_archive_cmds \
- old_archive_from_new_cmds \
- predep_objects \
- postdep_objects \
- predeps \
- postdeps \
- compiler_lib_search_path \
- archive_cmds \
- archive_expsym_cmds \
- postinstall_cmds \
- postuninstall_cmds \
- old_archive_from_expsyms_cmds \
- allow_undefined_flag \
- no_undefined_flag \
- export_symbols_cmds \
- hardcode_libdir_flag_spec \
- hardcode_libdir_flag_spec_ld \
- hardcode_libdir_separator \
- hardcode_automatic \
- module_cmds \
- module_expsym_cmds \
- lt_cv_prog_compiler_c_o \
- exclude_expsyms \
- include_expsyms; do
-
- case $var in
- old_archive_cmds | \
- old_archive_from_new_cmds | \
- archive_cmds | \
- archive_expsym_cmds | \
- module_cmds | \
- module_expsym_cmds | \
- old_archive_from_expsyms_cmds | \
- export_symbols_cmds | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\$0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
- ;;
- esac
-
-cfgfile="${ofile}T"
- trap "$rm \"$cfgfile\"; exit 1" 1 2 15
- $rm -f "$cfgfile"
- { echo "$as_me:$LINENO: creating $ofile" >&5
-echo "$as_me: creating $ofile" >&6;}
-
- cat <<__EOF__ >> "$cfgfile"
-#! $SHELL
-
-# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
-# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
-# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
-#
-# This file is part of GNU Libtool:
-# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# A sed program that does not truncate output.
-SED=$lt_SED
-
-# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="$SED -e 1s/^X//"
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# The names of the tagged configurations supported by this script.
-available_tags=
-
-# ### BEGIN LIBTOOL CONFIG
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_compiler
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_LD
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds
-archive_expsym_cmds=$lt_archive_expsym_cmds
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_module_cmds
-module_expsym_cmds=$lt_module_expsym_cmds
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_predep_objects
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_postdep_objects
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_predeps
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_postdeps
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$hardcode_automatic
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path"
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms
-
-# ### END LIBTOOL CONFIG
-
-__EOF__
-
-
- case $host_os in
- aix3*)
- cat <<\EOF >> "$cfgfile"
-
-# AIX sometimes has problems with the GCC collect2 program. For some
-# reason, if we set the COLLECT_NAMES environment variable, the problems
-# vanish in a puff of smoke.
-if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
-fi
-EOF
- ;;
- esac
-
- # We use sed instead of cat because bash on DJGPP gets confused if
- # if finds mixed CR/LF and LF-only lines. Since sed operates in
- # text mode, it properly converts lines to CR/LF. This bash problem
- # is reportedly fixed, but why not run on old versions too?
- sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
-
- mv -f "$cfgfile" "$ofile" || \
- (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
- chmod +x "$ofile"
-
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-CC="$lt_save_CC"
-
-
-# Check whether --with-tags was given.
-if test "${with_tags+set}" = set; then
- withval=$with_tags; tagnames="$withval"
-fi
-
-
-if test -f "$ltmain" && test -n "$tagnames"; then
- if test ! -f "${ofile}"; then
- { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5
-echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;}
- fi
-
- if test -z "$LTCC"; then
- eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
- if test -z "$LTCC"; then
- { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5
-echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;}
- else
- { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5
-echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;}
- fi
- fi
- if test -z "$LTCFLAGS"; then
- eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
- fi
-
- # Extract list of available tagged configurations in $ofile.
- # Note that this assumes the entire list is on one line.
- available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
-
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for tagname in $tagnames; do
- IFS="$lt_save_ifs"
- # Check whether tagname contains only valid characters
- case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in
- "") ;;
- *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5
-echo "$as_me: error: invalid tag name: $tagname" >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
-
- if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
- then
- { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5
-echo "$as_me: error: tag name \"$tagname\" already exists" >&2;}
- { (exit 1); exit 1; }; }
- fi
-
- # Update the list of available tags.
- if test -n "$tagname"; then
- echo appending configuration tag \"$tagname\" to $ofile
-
- case $tagname in
- CXX)
- if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-
-
-archive_cmds_need_lc_CXX=no
-allow_undefined_flag_CXX=
-always_export_symbols_CXX=no
-archive_expsym_cmds_CXX=
-export_dynamic_flag_spec_CXX=
-hardcode_direct_CXX=no
-hardcode_libdir_flag_spec_CXX=
-hardcode_libdir_flag_spec_ld_CXX=
-hardcode_libdir_separator_CXX=
-hardcode_minus_L_CXX=no
-hardcode_shlibpath_var_CXX=unsupported
-hardcode_automatic_CXX=no
-module_cmds_CXX=
-module_expsym_cmds_CXX=
-link_all_deplibs_CXX=unknown
-old_archive_cmds_CXX=$old_archive_cmds
-no_undefined_flag_CXX=
-whole_archive_flag_spec_CXX=
-enable_shared_with_static_runtimes_CXX=no
-
-# Dependencies to place before and after the object being linked:
-predep_objects_CXX=
-postdep_objects_CXX=
-predeps_CXX=
-postdeps_CXX=
-compiler_lib_search_path_CXX=
-
-# Source file extension for C++ test sources.
-ac_ext=cpp
-
-# Object file extension for compiled C++ test sources.
-objext=o
-objext_CXX=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;\n"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n'
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-
-ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm conftest*
-
-
-# Allow CC to be a program name with arguments.
-lt_save_CC=$CC
-lt_save_LD=$LD
-lt_save_GCC=$GCC
-GCC=$GXX
-lt_save_with_gnu_ld=$with_gnu_ld
-lt_save_path_LD=$lt_cv_path_LD
-if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
- lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
-else
- $as_unset lt_cv_prog_gnu_ld
-fi
-if test -n "${lt_cv_path_LDCXX+set}"; then
- lt_cv_path_LD=$lt_cv_path_LDCXX
-else
- $as_unset lt_cv_path_LD
-fi
-test -z "${LDCXX+set}" || LD=$LDCXX
-CC=${CXX-"c++"}
-compiler=$CC
-compiler_CXX=$CC
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-
-# We don't want -fno-exception wen compiling C++ code, so set the
-# no_builtin_flag separately
-if test "$GXX" = yes; then
- lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
-else
- lt_prog_compiler_no_builtin_flag_CXX=
-fi
-
-if test "$GXX" = yes; then
- # Set up default GNU C++ configuration
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then
- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
- with_gnu_ld=no
-fi
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
-echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [\\/]* | ?:[\\/]*)
- re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- { echo "$as_me:$LINENO: checking for GNU ld" >&5
-echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
-else
- { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
-echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
-fi
-if test "${lt_cv_path_LD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- { echo "$as_me:$LINENO: result: $LD" >&5
-echo "${ECHO_T}$LD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
-echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
- { (exit 1); exit 1; }; }
-{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
-echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
-echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$lt_cv_prog_gnu_ld
-
-
-
- # Check if GNU C++ uses GNU ld as the underlying linker, since the
- # archiving commands below assume that GNU ld is being used.
- if test "$with_gnu_ld" = yes; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
-
- # If archive_cmds runs LD, not CC, wlarc should be empty
- # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
- # investigate it a little bit more. (MM)
- wlarc='${wl}'
-
- # ancient GNU ld didn't support --whole-archive et. al.
- if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
- grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec_CXX=
- fi
- else
- with_gnu_ld=no
- wlarc=
-
- # A generic and very simple default shared library creation
- # command for GNU C++ for the case where it uses the native
- # linker, instead of GNU ld. If possible, this setting should
- # overridden to take advantage of the native linker features on
- # the platform it is being used on.
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- fi
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
-else
- GXX=no
- with_gnu_ld=no
- wlarc=
-fi
-
-# PORTME: fill in a description of your system's C++ link characteristics
-{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
-ld_shlibs_CXX=yes
-case $host_os in
- aix3*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- aix4* | aix5*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix5*)
- for ld_flag in $LDFLAGS; do
- case $ld_flag in
- *-brtl*)
- aix_use_runtimelinking=yes
- break
- ;;
- esac
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds_CXX=''
- hardcode_direct_CXX=yes
- hardcode_libdir_separator_CXX=':'
- link_all_deplibs_CXX=yes
-
- if test "$GXX" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- hardcode_direct_CXX=yes
- else
- # We have old collect2
- hardcode_direct_CXX=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L_CXX=yes
- hardcode_libdir_flag_spec_CXX='-L$libdir'
- hardcode_libdir_separator_CXX=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols_CXX=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag_CXX='-berok'
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`; fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
-
- archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag_CXX="-z nodefs"
- archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`; fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag_CXX=' ${wl}-bernotok'
- allow_undefined_flag_CXX=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_CXX='$convenience'
- archive_cmds_need_lc_CXX=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag_CXX=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs_CXX=no
- fi
- ;;
-
- chorus*)
- case $cc_basename in
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
-
- cygwin* | mingw* | pw32*)
- # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec_CXX='-L$libdir'
- allow_undefined_flag_CXX=unsupported
- always_export_symbols_CXX=no
- enable_shared_with_static_runtimes_CXX=yes
-
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs_CXX=no
- fi
- ;;
- darwin* | rhapsody*)
- case $host_os in
- rhapsody* | darwin1.[012])
- allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress'
- ;;
- *) # Darwin 1.3 on
- if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
- allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- else
- case ${MACOSX_DEPLOYMENT_TARGET} in
- 10.[012])
- allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- ;;
- 10.*)
- allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup'
- ;;
- esac
- fi
- ;;
- esac
- archive_cmds_need_lc_CXX=no
- hardcode_direct_CXX=no
- hardcode_automatic_CXX=yes
- hardcode_shlibpath_var_CXX=unsupported
- whole_archive_flag_spec_CXX=''
- link_all_deplibs_CXX=yes
-
- if test "$GXX" = yes ; then
- lt_int_apple_cc_single_mod=no
- output_verbose_link_cmd='echo'
- if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then
- lt_int_apple_cc_single_mod=yes
- fi
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- else
- archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- fi
- module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- else
- archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- fi
- module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- else
- case $cc_basename in
- xlc*)
- output_verbose_link_cmd='echo'
- archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
- module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- ;;
- *)
- ld_shlibs_CXX=no
- ;;
- esac
- fi
- ;;
-
- dgux*)
- case $cc_basename in
- ec++*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
- freebsd[12]*)
- # C++ shared libraries reported to be fairly broken before switch to ELF
- ld_shlibs_CXX=no
- ;;
- freebsd-elf*)
- archive_cmds_need_lc_CXX=no
- ;;
- freebsd* | kfreebsd*-gnu | dragonfly*)
- # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
- # conventions
- ld_shlibs_CXX=yes
- ;;
- gnu*)
- ;;
- hpux9*)
- hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
- export_dynamic_flag_spec_CXX='${wl}-E'
- hardcode_direct_CXX=yes
- hardcode_minus_L_CXX=yes # Not in the search PATH,
- # but as the default
- # location of the library.
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- aCC*)
- archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes; then
- archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
- hpux10*|hpux11*)
- if test $with_gnu_ld = no; then
- hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_libdir_flag_spec_ld_CXX='+b $libdir'
- ;;
- *)
- export_dynamic_flag_spec_CXX='${wl}-E'
- ;;
- esac
- fi
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_direct_CXX=no
- hardcode_shlibpath_var_CXX=no
- ;;
- *)
- hardcode_direct_CXX=yes
- hardcode_minus_L_CXX=yes # Not in the search PATH,
- # but as the default
- # location of the library.
- ;;
- esac
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- aCC*)
- case $host_cpu in
- hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes; then
- if test $with_gnu_ld = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- fi
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
- interix3*)
- hardcode_direct_CXX=no
- hardcode_shlibpath_var_CXX=no
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_CXX='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
- irix5* | irix6*)
- case $cc_basename in
- CC*)
- # SGI C++
- archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-
- # Archives containing C++ object files must be created using
- # "CC -ar", where "CC" is the IRIX C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
- ;;
- *)
- if test "$GXX" = yes; then
- if test "$with_gnu_ld" = no; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
- fi
- fi
- link_all_deplibs_CXX=yes
- ;;
- esac
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
- ;;
- linux*)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
- archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
-
- hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
-
- # Archives containing C++ object files must be created using
- # "CC -Bstatic", where "CC" is the KAI C++ compiler.
- old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
- ;;
- icpc*)
- # Intel C++
- with_gnu_ld=yes
- # version 8.0 and above of icpc choke on multiply defined symbols
- # if we add $predep_objects and $postdep_objects, however 7.1 and
- # earlier do not add the objects themselves.
- case `$CC -V 2>&1` in
- *"Version 7."*)
- archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- *) # Version 8.0 or newer
- tmp_idyn=
- case $host_cpu in
- ia64*) tmp_idyn=' -i_dynamic';;
- esac
- archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- esac
- archive_cmds_need_lc_CXX=no
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
- whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
- ;;
- pgCC*)
- # Portland Group C++ compiler
- archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
- whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- ;;
- cxx*)
- # Compaq C++
- archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
-
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec_CXX='-rpath $libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- esac
- ;;
- lynxos*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- m88k*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- mvs*)
- case $cc_basename in
- cxx*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
- wlarc=
- hardcode_libdir_flag_spec_CXX='-R$libdir'
- hardcode_direct_CXX=yes
- hardcode_shlibpath_var_CXX=no
- fi
- # Workaround some broken pre-1.5 toolchains
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
- ;;
- openbsd2*)
- # C++ shared libraries are fairly broken
- ld_shlibs_CXX=no
- ;;
- openbsd*)
- hardcode_direct_CXX=yes
- hardcode_shlibpath_var_CXX=no
- archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
- export_dynamic_flag_spec_CXX='${wl}-E'
- whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- fi
- output_verbose_link_cmd='echo'
- ;;
- osf3*)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Archives containing C++ object files must be created using
- # "CC -Bstatic", where "CC" is the KAI C++ compiler.
- old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
-
- ;;
- RCC*)
- # Rational C++ 2.4.1
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- cxx*)
- allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
- osf4* | osf5*)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Archives containing C++ object files must be created using
- # the KAI C++ compiler.
- old_archive_cmds_CXX='$CC -o $oldlib $oldobjs'
- ;;
- RCC*)
- # Rational C++ 2.4.1
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- cxx*)
- allow_undefined_flag_CXX=' -expect_unresolved \*'
- archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
- echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~
- $rm $lib.exp'
-
- hardcode_libdir_flag_spec_CXX='-rpath $libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
- psos*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- lcc*)
- # Lucid
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- archive_cmds_need_lc_CXX=yes
- no_undefined_flag_CXX=' -zdefs'
- archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
- hardcode_libdir_flag_spec_CXX='-R$libdir'
- hardcode_shlibpath_var_CXX=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The C++ compiler is used as linker so we must use $wl
- # flag to pass the commands to the underlying system
- # linker. We must also pass each convience library through
- # to the system linker between allextract/defaultextract.
- # The C++ compiler will combine linker options so we
- # cannot just pass the convience library names through
- # without $wl.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract'
- ;;
- esac
- link_all_deplibs_CXX=yes
-
- output_verbose_link_cmd='echo'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
- ;;
- gcx*)
- # Green Hills C++ Compiler
- archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
-
- # The C++ compiler must be used to create the archive.
- old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
- ;;
- *)
- # GNU C++ compiler with Solaris linker
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
- if $CC --version | grep -v '^2\.7' > /dev/null; then
- archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
- else
- # g++ 2.7 appears to require `-G' NOT `-shared' on this
- # platform.
- archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
- fi
-
- hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
- fi
- ;;
- esac
- ;;
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- no_undefined_flag_CXX='${wl}-z,text'
- archive_cmds_need_lc_CXX=no
- hardcode_shlibpath_var_CXX=no
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- # For security reasons, it is highly recommended that you always
- # use absolute paths for naming shared libraries, and exclude the
- # DT_RUNPATH tag from executables and libraries. But doing so
- # requires that you compile everything twice, which is a pain.
- # So that behaviour is only enabled if SCOABSPATH is set to a
- # non-empty value in the environment. Most likely only useful for
- # creating official distributions of packages.
- # This is a hack until libtool officially supports absolute path
- # names for shared libraries.
- no_undefined_flag_CXX='${wl}-z,text'
- allow_undefined_flag_CXX='${wl}-z,nodefs'
- archive_cmds_need_lc_CXX=no
- hardcode_shlibpath_var_CXX=no
- hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- hardcode_libdir_separator_CXX=':'
- link_all_deplibs_CXX=yes
- export_dynamic_flag_spec_CXX='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
- vxworks*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
-echo "${ECHO_T}$ld_shlibs_CXX" >&6; }
-test "$ld_shlibs_CXX" = no && can_build_shared=no
-
-GCC_CXX="$GXX"
-LD_CXX="$LD"
-
-
-cat > conftest.$ac_ext <<EOF
-class Foo
-{
-public:
- Foo (void) { a = 0; }
-private:
- int a;
-};
-EOF
-
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # Parse the compiler output and extract the necessary
- # objects, libraries and library flags.
-
- # Sentinel used to keep track of whether or not we are before
- # the conftest object file.
- pre_test_object_deps_done=no
-
- # The `*' in the case matches for architectures that use `case' in
- # $output_verbose_cmd can trigger glob expansion during the loop
- # eval without this substitution.
- output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
-
- for p in `eval $output_verbose_link_cmd`; do
- case $p in
-
- -L* | -R* | -l*)
- # Some compilers place space between "-{L,R}" and the path.
- # Remove the space.
- if test $p = "-L" \
- || test $p = "-R"; then
- prev=$p
- continue
- else
- prev=
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- case $p in
- -L* | -R*)
- # Internal compiler library paths should come after those
- # provided the user. The postdeps already come after the
- # user supplied libs so there is no need to process them.
- if test -z "$compiler_lib_search_path_CXX"; then
- compiler_lib_search_path_CXX="${prev}${p}"
- else
- compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
- fi
- ;;
- # The "-l" case would never come before the object being
- # linked, so don't bother handling this case.
- esac
- else
- if test -z "$postdeps_CXX"; then
- postdeps_CXX="${prev}${p}"
- else
- postdeps_CXX="${postdeps_CXX} ${prev}${p}"
- fi
- fi
- ;;
-
- *.$objext)
- # This assumes that the test object file only shows up
- # once in the compiler output.
- if test "$p" = "conftest.$objext"; then
- pre_test_object_deps_done=yes
- continue
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- if test -z "$predep_objects_CXX"; then
- predep_objects_CXX="$p"
- else
- predep_objects_CXX="$predep_objects_CXX $p"
- fi
- else
- if test -z "$postdep_objects_CXX"; then
- postdep_objects_CXX="$p"
- else
- postdep_objects_CXX="$postdep_objects_CXX $p"
- fi
- fi
- ;;
-
- *) ;; # Ignore the rest.
-
- esac
- done
-
- # Clean up.
- rm -f a.out a.exe
-else
- echo "libtool.m4: error: problem compiling CXX test program"
-fi
-
-$rm -f confest.$objext
-
-# PORTME: override above test on systems where it is broken
-case $host_os in
-interix3*)
- # Interix 3.5 installs completely hosed .la files for C++, so rather than
- # hack all around it, let's just trust "g++" to DTRT.
- predep_objects_CXX=
- postdep_objects_CXX=
- postdeps_CXX=
- ;;
-
-solaris*)
- case $cc_basename in
- CC*)
- # Adding this requires a known-good setup of shared libraries for
- # Sun compiler versions before 5.6, else PIC objects from an old
- # archive will be linked into the output, leading to subtle bugs.
- postdeps_CXX='-lCstd -lCrun'
- ;;
- esac
- ;;
-esac
-
-
-case " $postdeps_CXX " in
-*" -lc "*) archive_cmds_need_lc_CXX=no ;;
-esac
-
-lt_prog_compiler_wl_CXX=
-lt_prog_compiler_pic_CXX=
-lt_prog_compiler_static_CXX=
-
-{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
-
- # C++ specific cases for pic, static, wl, etc.
- if test "$GXX" = yes; then
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_CXX='-Bstatic'
- fi
- ;;
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
- ;;
- beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
- mingw* | os2* | pw32*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
- ;;
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic_CXX='-fno-common'
- ;;
- *djgpp*)
- # DJGPP does not support shared libraries at all
- lt_prog_compiler_pic_CXX=
- ;;
- interix3*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic_CXX=-Kconform_pic
- fi
- ;;
- hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- ;;
- *)
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- esac
- ;;
- *)
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- esac
- else
- case $host_os in
- aix4* | aix5*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_CXX='-Bstatic'
- else
- lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- chorus*)
- case $cc_basename in
- cxch68*)
- # Green Hills C++ Compiler
- # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
- ;;
- esac
- ;;
- darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- case $cc_basename in
- xlc*)
- lt_prog_compiler_pic_CXX='-qnocommon'
- lt_prog_compiler_wl_CXX='-Wl,'
- ;;
- esac
- ;;
- dgux*)
- case $cc_basename in
- ec++*)
- lt_prog_compiler_pic_CXX='-KPIC'
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- lt_prog_compiler_pic_CXX='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- freebsd* | kfreebsd*-gnu | dragonfly*)
- # FreeBSD uses GNU C++
- ;;
- hpux9* | hpux10* | hpux11*)
- case $cc_basename in
- CC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
- if test "$host_cpu" != ia64; then
- lt_prog_compiler_pic_CXX='+Z'
- fi
- ;;
- aCC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_CXX='+Z'
- ;;
- esac
- ;;
- *)
- ;;
- esac
- ;;
- interix*)
- # This is c89, which is MS Visual C++ (no shared libs)
- # Anyone wants to do a port?
- ;;
- irix5* | irix6* | nonstopux*)
- case $cc_basename in
- CC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='-non_shared'
- # CC pic flag -KPIC is the default.
- ;;
- *)
- ;;
- esac
- ;;
- linux*)
- case $cc_basename in
- KCC*)
- # KAI C++ Compiler
- lt_prog_compiler_wl_CXX='--backend -Wl,'
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- icpc* | ecpc*)
- # Intel C++
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-static'
- ;;
- pgCC*)
- # Portland Group C++ compiler.
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-fpic'
- lt_prog_compiler_static_CXX='-Bstatic'
- ;;
- cxx*)
- # Compaq C++
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- lt_prog_compiler_pic_CXX=
- lt_prog_compiler_static_CXX='-non_shared'
- ;;
- *)
- ;;
- esac
- ;;
- lynxos*)
- ;;
- m88k*)
- ;;
- mvs*)
- case $cc_basename in
- cxx*)
- lt_prog_compiler_pic_CXX='-W c,exportall'
- ;;
- *)
- ;;
- esac
- ;;
- netbsd*)
- ;;
- osf3* | osf4* | osf5*)
- case $cc_basename in
- KCC*)
- lt_prog_compiler_wl_CXX='--backend -Wl,'
- ;;
- RCC*)
- # Rational C++ 2.4.1
- lt_prog_compiler_pic_CXX='-pic'
- ;;
- cxx*)
- # Digital/Compaq C++
- lt_prog_compiler_wl_CXX='-Wl,'
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- lt_prog_compiler_pic_CXX=
- lt_prog_compiler_static_CXX='-non_shared'
- ;;
- *)
- ;;
- esac
- ;;
- psos*)
- ;;
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-Bstatic'
- lt_prog_compiler_wl_CXX='-Qoption ld '
- ;;
- gcx*)
- # Green Hills C++ Compiler
- lt_prog_compiler_pic_CXX='-PIC'
- ;;
- *)
- ;;
- esac
- ;;
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- lt_prog_compiler_pic_CXX='-pic'
- lt_prog_compiler_static_CXX='-Bstatic'
- ;;
- lcc*)
- # Lucid
- lt_prog_compiler_pic_CXX='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- lt_prog_compiler_pic_CXX='-KPIC'
- ;;
- *)
- ;;
- esac
- ;;
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- case $cc_basename in
- CC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-Bstatic'
- ;;
- esac
- ;;
- vxworks*)
- ;;
- *)
- lt_prog_compiler_can_build_shared_CXX=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6; }
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic_CXX"; then
-
-{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6; }
-if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_prog_compiler_pic_works_CXX=no
- ac_outfile=conftest.$ac_objext
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:20277: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:20281: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_prog_compiler_pic_works_CXX=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6; }
-
-if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then
- case $lt_prog_compiler_pic_CXX in
- "" | " "*) ;;
- *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
- esac
-else
- lt_prog_compiler_pic_CXX=
- lt_prog_compiler_can_build_shared_CXX=no
-fi
-
-fi
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic_CXX=
- ;;
- *)
- lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
- ;;
-esac
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
-{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
-if test "${lt_prog_compiler_static_works_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_prog_compiler_static_works_CXX=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- printf "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_prog_compiler_static_works_CXX=yes
- fi
- else
- lt_prog_compiler_static_works_CXX=yes
- fi
- fi
- $rm conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5
-echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6; }
-
-if test x"$lt_prog_compiler_static_works_CXX" = xyes; then
- :
-else
- lt_prog_compiler_static_CXX=
-fi
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_c_o_CXX=no
- $rm -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:20381: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:20385: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o_CXX=yes
- fi
- fi
- chmod u+w . 2>&5
- $rm conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
- $rm out/* && rmdir out
- cd ..
- rmdir conftest
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6; }
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
- hard_links=yes
- $rm conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6; }
- if test "$hard_links" = no; then
- { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
-
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- case $host_os in
- aix4* | aix5*)
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
- export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- fi
- ;;
- pw32*)
- export_symbols_cmds_CXX="$ltdll_cmds"
- ;;
- cygwin* | mingw*)
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
- *)
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
- esac
-
-{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
-echo "${ECHO_T}$ld_shlibs_CXX" >&6; }
-test "$ld_shlibs_CXX" = no && can_build_shared=no
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc_CXX" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc_CXX=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds_CXX in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
- $rm conftest*
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl_CXX
- pic_flag=$lt_prog_compiler_pic_CXX
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
- allow_undefined_flag_CXX=
- if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
- (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
- then
- archive_cmds_need_lc_CXX=no
- else
- archive_cmds_need_lc_CXX=yes
- fi
- allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $rm conftest*
- { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5
-echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6; }
- ;;
- esac
- fi
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-if test "$GCC" = yes; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix4* | aix5*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $rm \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='.dylib'
- # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
- if test "$GCC" = yes; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
- else
- sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
- fi
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-kfreebsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='GNU ld.so'
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[123]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- freebsd*) # from 4.6 on
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix3*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-knetbsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='GNU ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-nto-qnx*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- shlibpath_overrides_runpath=no
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- shlibpath_overrides_runpath=yes
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
-hardcode_action_CXX=
-if test -n "$hardcode_libdir_flag_spec_CXX" || \
- test -n "$runpath_var_CXX" || \
- test "X$hardcode_automatic_CXX" = "Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct_CXX" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
- test "$hardcode_minus_L_CXX" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action_CXX=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action_CXX=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action_CXX=unsupported
-fi
-{ echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
-echo "${ECHO_T}$hardcode_action_CXX" >&6; }
-
-if test "$hardcode_action_CXX" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-
-# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- compiler_CXX \
- CC_CXX \
- LD_CXX \
- lt_prog_compiler_wl_CXX \
- lt_prog_compiler_pic_CXX \
- lt_prog_compiler_static_CXX \
- lt_prog_compiler_no_builtin_flag_CXX \
- export_dynamic_flag_spec_CXX \
- thread_safe_flag_spec_CXX \
- whole_archive_flag_spec_CXX \
- enable_shared_with_static_runtimes_CXX \
- old_archive_cmds_CXX \
- old_archive_from_new_cmds_CXX \
- predep_objects_CXX \
- postdep_objects_CXX \
- predeps_CXX \
- postdeps_CXX \
- compiler_lib_search_path_CXX \
- archive_cmds_CXX \
- archive_expsym_cmds_CXX \
- postinstall_cmds_CXX \
- postuninstall_cmds_CXX \
- old_archive_from_expsyms_cmds_CXX \
- allow_undefined_flag_CXX \
- no_undefined_flag_CXX \
- export_symbols_cmds_CXX \
- hardcode_libdir_flag_spec_CXX \
- hardcode_libdir_flag_spec_ld_CXX \
- hardcode_libdir_separator_CXX \
- hardcode_automatic_CXX \
- module_cmds_CXX \
- module_expsym_cmds_CXX \
- lt_cv_prog_compiler_c_o_CXX \
- exclude_expsyms_CXX \
- include_expsyms_CXX; do
-
- case $var in
- old_archive_cmds_CXX | \
- old_archive_from_new_cmds_CXX | \
- archive_cmds_CXX | \
- archive_expsym_cmds_CXX | \
- module_cmds_CXX | \
- module_expsym_cmds_CXX | \
- old_archive_from_expsyms_cmds_CXX | \
- export_symbols_cmds_CXX | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\$0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
- ;;
- esac
-
-cfgfile="$ofile"
-
- cat <<__EOF__ >> "$cfgfile"
-# ### BEGIN LIBTOOL TAG CONFIG: $tagname
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc_CXX
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_compiler_CXX
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC_CXX
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_LD_CXX
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl_CXX
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic_CXX
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static_CXX
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds_CXX
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds_CXX
-archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_module_cmds_CXX
-module_expsym_cmds=$lt_module_expsym_cmds_CXX
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_predep_objects_CXX
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_postdep_objects_CXX
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_predeps_CXX
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_postdeps_CXX
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag_CXX
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag_CXX
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action_CXX
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct_CXX
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L_CXX
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$hardcode_automatic_CXX
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs_CXX
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path_CXX"
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols_CXX
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds_CXX
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms_CXX
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms_CXX
-
-# ### END LIBTOOL TAG CONFIG: $tagname
-
-__EOF__
-
-
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-CC=$lt_save_CC
-LDCXX=$LD
-LD=$lt_save_LD
-GCC=$lt_save_GCC
-with_gnu_ldcxx=$with_gnu_ld
-with_gnu_ld=$lt_save_with_gnu_ld
-lt_cv_path_LDCXX=$lt_cv_path_LD
-lt_cv_path_LD=$lt_save_path_LD
-lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
-lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-
- else
- tagname=""
- fi
- ;;
-
- F77)
- if test -n "$F77" && test "X$F77" != "Xno"; then
-
-ac_ext=f
-ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
-ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_f77_compiler_gnu
-
-
-archive_cmds_need_lc_F77=no
-allow_undefined_flag_F77=
-always_export_symbols_F77=no
-archive_expsym_cmds_F77=
-export_dynamic_flag_spec_F77=
-hardcode_direct_F77=no
-hardcode_libdir_flag_spec_F77=
-hardcode_libdir_flag_spec_ld_F77=
-hardcode_libdir_separator_F77=
-hardcode_minus_L_F77=no
-hardcode_automatic_F77=no
-module_cmds_F77=
-module_expsym_cmds_F77=
-link_all_deplibs_F77=unknown
-old_archive_cmds_F77=$old_archive_cmds
-no_undefined_flag_F77=
-whole_archive_flag_spec_F77=
-enable_shared_with_static_runtimes_F77=no
-
-# Source file extension for f77 test sources.
-ac_ext=f
-
-# Object file extension for compiled f77 test sources.
-objext=o
-objext_F77=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code=" subroutine t\n return\n end\n"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code=" program t\n end\n"
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-
-ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm conftest*
-
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-CC=${F77-"f77"}
-compiler=$CC
-compiler_F77=$CC
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-
-{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
-echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $can_build_shared" >&5
-echo "${ECHO_T}$can_build_shared" >&6; }
-
-{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
-echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; }
-test "$can_build_shared" = "no" && enable_shared=no
-
-# On AIX, shared libraries and static libraries use the same namespace, and
-# are all built from PIC.
-case $host_os in
-aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-aix4* | aix5*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $enable_shared" >&5
-echo "${ECHO_T}$enable_shared" >&6; }
-
-{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5
-echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; }
-# Make sure either enable_shared or enable_static is yes.
-test "$enable_shared" = yes || enable_static=yes
-{ echo "$as_me:$LINENO: result: $enable_static" >&5
-echo "${ECHO_T}$enable_static" >&6; }
-
-GCC_F77="$G77"
-LD_F77="$LD"
-
-lt_prog_compiler_wl_F77=
-lt_prog_compiler_pic_F77=
-lt_prog_compiler_static_F77=
-
-{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
-
- if test "$GCC" = yes; then
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_static_F77='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_F77='-Bstatic'
- fi
- ;;
-
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4'
- ;;
-
- beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic_F77='-DDLL_EXPORT'
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic_F77='-fno-common'
- ;;
-
- interix3*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- lt_prog_compiler_can_build_shared_F77=no
- enable_shared=no
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic_F77=-Kconform_pic
- fi
- ;;
-
- hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_F77='-fPIC'
- ;;
- esac
- ;;
-
- *)
- lt_prog_compiler_pic_F77='-fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- lt_prog_compiler_wl_F77='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_F77='-Bstatic'
- else
- lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- case $cc_basename in
- xlc*)
- lt_prog_compiler_pic_F77='-qnocommon'
- lt_prog_compiler_wl_F77='-Wl,'
- ;;
- esac
- ;;
-
- mingw* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic_F77='-DDLL_EXPORT'
- ;;
-
- hpux9* | hpux10* | hpux11*)
- lt_prog_compiler_wl_F77='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_F77='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- lt_prog_compiler_static_F77='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- lt_prog_compiler_wl_F77='-Wl,'
- # PIC (with -KPIC) is the default.
- lt_prog_compiler_static_F77='-non_shared'
- ;;
-
- newsos6)
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
-
- linux*)
- case $cc_basename in
- icc* | ecc*)
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_pic_F77='-fpic'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
- ccc*)
- lt_prog_compiler_wl_F77='-Wl,'
- # All Alpha code is PIC.
- lt_prog_compiler_static_F77='-non_shared'
- ;;
- esac
- ;;
-
- osf3* | osf4* | osf5*)
- lt_prog_compiler_wl_F77='-Wl,'
- # All OSF/1 code is PIC.
- lt_prog_compiler_static_F77='-non_shared'
- ;;
-
- solaris*)
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- lt_prog_compiler_wl_F77='-Qoption ld ';;
- *)
- lt_prog_compiler_wl_F77='-Wl,';;
- esac
- ;;
-
- sunos4*)
- lt_prog_compiler_wl_F77='-Qoption ld '
- lt_prog_compiler_pic_F77='-PIC'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- lt_prog_compiler_pic_F77='-Kconform_pic'
- lt_prog_compiler_static_F77='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
-
- unicos*)
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_can_build_shared_F77=no
- ;;
-
- uts4*)
- lt_prog_compiler_pic_F77='-pic'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
-
- *)
- lt_prog_compiler_can_build_shared_F77=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6; }
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic_F77"; then
-
-{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6; }
-if test "${lt_prog_compiler_pic_works_F77+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_prog_compiler_pic_works_F77=no
- ac_outfile=conftest.$ac_objext
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic_F77"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:21951: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:21955: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_prog_compiler_pic_works_F77=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6; }
-
-if test x"$lt_prog_compiler_pic_works_F77" = xyes; then
- case $lt_prog_compiler_pic_F77 in
- "" | " "*) ;;
- *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;;
- esac
-else
- lt_prog_compiler_pic_F77=
- lt_prog_compiler_can_build_shared_F77=no
-fi
-
-fi
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic_F77=
- ;;
- *)
- lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77"
- ;;
-esac
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\"
-{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
-if test "${lt_prog_compiler_static_works_F77+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_prog_compiler_static_works_F77=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- printf "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_prog_compiler_static_works_F77=yes
- fi
- else
- lt_prog_compiler_static_works_F77=yes
- fi
- fi
- $rm conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5
-echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6; }
-
-if test x"$lt_prog_compiler_static_works_F77" = xyes; then
- :
-else
- lt_prog_compiler_static_F77=
-fi
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_c_o_F77=no
- $rm -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:22055: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:22059: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o_F77=yes
- fi
- fi
- chmod u+w . 2>&5
- $rm conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
- $rm out/* && rmdir out
- cd ..
- rmdir conftest
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6; }
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
- hard_links=yes
- $rm conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6; }
- if test "$hard_links" = no; then
- { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
-
- runpath_var=
- allow_undefined_flag_F77=
- enable_shared_with_static_runtimes_F77=no
- archive_cmds_F77=
- archive_expsym_cmds_F77=
- old_archive_From_new_cmds_F77=
- old_archive_from_expsyms_cmds_F77=
- export_dynamic_flag_spec_F77=
- whole_archive_flag_spec_F77=
- thread_safe_flag_spec_F77=
- hardcode_libdir_flag_spec_F77=
- hardcode_libdir_flag_spec_ld_F77=
- hardcode_libdir_separator_F77=
- hardcode_direct_F77=no
- hardcode_minus_L_F77=no
- hardcode_shlibpath_var_F77=unsupported
- link_all_deplibs_F77=unknown
- hardcode_automatic_F77=no
- module_cmds_F77=
- module_expsym_cmds_F77=
- always_export_symbols_F77=no
- export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- include_expsyms_F77=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_"
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- extract_expsyms_cmds=
- # Just being paranoid about ensuring that cc_basename is set.
- for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
- case $host_os in
- cygwin* | mingw* | pw32*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- esac
-
- ld_shlibs_F77=yes
- if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_F77='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec_F77=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix3* | aix4* | aix5*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs_F77=no
- cat <<EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-EOF
- fi
- ;;
-
- amigaos*)
- archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_minus_L_F77=yes
-
- # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we can't use
- # them.
- ld_shlibs_F77=no
- ;;
-
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag_F77=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs_F77=no
- fi
- ;;
-
- cygwin* | mingw* | pw32*)
- # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec_F77='-L$libdir'
- allow_undefined_flag_F77=unsupported
- always_export_symbols_F77=no
- enable_shared_with_static_runtimes_F77=yes
- export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs_F77=no
- fi
- ;;
-
- interix3*)
- hardcode_direct_F77=no
- hardcode_shlibpath_var_F77=no
- hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_F77='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- linux*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- tmp_addflag=
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- esac
- archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test $supports_anon_versioning = yes; then
- archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- $echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
- else
- ld_shlibs_F77=no
- fi
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- ld_shlibs_F77=no
- cat <<EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-EOF
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs_F77=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs_F77=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
- archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
- else
- ld_shlibs_F77=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- hardcode_direct_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs_F77=no
- fi
- ;;
- esac
-
- if test "$ld_shlibs_F77" = no; then
- runpath_var=
- hardcode_libdir_flag_spec_F77=
- export_dynamic_flag_spec_F77=
- whole_archive_flag_spec_F77=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- allow_undefined_flag_F77=unsupported
- always_export_symbols_F77=yes
- archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L_F77=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct_F77=unsupported
- fi
- ;;
-
- aix4* | aix5*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
- export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix5*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds_F77=''
- hardcode_direct_F77=yes
- hardcode_libdir_separator_F77=':'
- link_all_deplibs_F77=yes
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- hardcode_direct_F77=yes
- else
- # We have old collect2
- hardcode_direct_F77=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L_F77=yes
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_libdir_separator_F77=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols_F77=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag_F77='-berok'
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
- program main
-
- end
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`; fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag_F77="-z nodefs"
- archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
- program main
-
- end
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`; fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag_F77=' ${wl}-bernotok'
- allow_undefined_flag_F77=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_F77='$convenience'
- archive_cmds_need_lc_F77=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_minus_L_F77=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs_F77=no
- ;;
-
- bsdi[45]*)
- export_dynamic_flag_spec_F77=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec_F77=' '
- allow_undefined_flag_F77=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_From_new_cmds_F77='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path_F77='`cygpath -w "$srcfile"`'
- enable_shared_with_static_runtimes_F77=yes
- ;;
-
- darwin* | rhapsody*)
- case $host_os in
- rhapsody* | darwin1.[012])
- allow_undefined_flag_F77='${wl}-undefined ${wl}suppress'
- ;;
- *) # Darwin 1.3 on
- if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
- allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- else
- case ${MACOSX_DEPLOYMENT_TARGET} in
- 10.[012])
- allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- ;;
- 10.*)
- allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup'
- ;;
- esac
- fi
- ;;
- esac
- archive_cmds_need_lc_F77=no
- hardcode_direct_F77=no
- hardcode_automatic_F77=yes
- hardcode_shlibpath_var_F77=unsupported
- whole_archive_flag_spec_F77=''
- link_all_deplibs_F77=yes
- if test "$GCC" = yes ; then
- output_verbose_link_cmd='echo'
- archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- else
- case $cc_basename in
- xlc*)
- output_verbose_link_cmd='echo'
- archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
- module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- ;;
- *)
- ld_shlibs_F77=no
- ;;
- esac
- fi
- ;;
-
- dgux*)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_shlibpath_var_F77=no
- ;;
-
- freebsd1*)
- ld_shlibs_F77=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- hardcode_libdir_flag_spec_F77='-R$libdir'
- hardcode_direct_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_F77=yes
- hardcode_minus_L_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | kfreebsd*-gnu | dragonfly*)
- archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec_F77='-R$libdir'
- hardcode_direct_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_F77=:
- hardcode_direct_F77=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_F77=yes
- export_dynamic_flag_spec_F77='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_F77=:
-
- hardcode_direct_F77=yes
- export_dynamic_flag_spec_F77='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_F77=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_F77=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_libdir_flag_spec_ld_F77='+b $libdir'
- hardcode_direct_F77=no
- hardcode_shlibpath_var_F77=no
- ;;
- *)
- hardcode_direct_F77=yes
- export_dynamic_flag_spec_F77='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_F77=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_ld_F77='-rpath $libdir'
- fi
- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_F77=:
- link_all_deplibs_F77=yes
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- hardcode_libdir_flag_spec_F77='-R$libdir'
- hardcode_direct_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- newsos6)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_F77=yes
- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_F77=:
- hardcode_shlibpath_var_F77=no
- ;;
-
- openbsd*)
- hardcode_direct_F77=yes
- hardcode_shlibpath_var_F77=no
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_F77='${wl}-E'
- else
- case $host_os in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_F77='-R$libdir'
- ;;
- *)
- archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- ;;
-
- os2*)
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_minus_L_F77=yes
- allow_undefined_flag_F77=unsupported
- archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- allow_undefined_flag_F77=' -expect_unresolved \*'
- archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_F77=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
- else
- allow_undefined_flag_F77=' -expect_unresolved \*'
- archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec_F77='-rpath $libdir'
- fi
- hardcode_libdir_separator_F77=:
- ;;
-
- solaris*)
- no_undefined_flag_F77=' -z text'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
- else
- wlarc=''
- archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- fi
- hardcode_libdir_flag_spec_F77='-R$libdir'
- hardcode_shlibpath_var_F77=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine linker options so we
- # cannot just pass the convience library names through
- # without $wl, iff we do not link with $LD.
- # Luckily, gcc supports the same syntax we need for Sun Studio.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- case $wlarc in
- '')
- whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;;
- *)
- whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
- esac ;;
- esac
- link_all_deplibs_F77=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_direct_F77=yes
- hardcode_minus_L_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_F77=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- reload_cmds_F77='$CC -r -o $output$reload_objs'
- hardcode_direct_F77=no
- ;;
- motorola)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var_F77=no
- ;;
-
- sysv4.3*)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var_F77=no
- export_dynamic_flag_spec_F77='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var_F77=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ld_shlibs_F77=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
- no_undefined_flag_F77='${wl}-z,text'
- archive_cmds_need_lc_F77=no
- hardcode_shlibpath_var_F77=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- no_undefined_flag_F77='${wl}-z,text'
- allow_undefined_flag_F77='${wl}-z,nodefs'
- archive_cmds_need_lc_F77=no
- hardcode_shlibpath_var_F77=no
- hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- hardcode_libdir_separator_F77=':'
- link_all_deplibs_F77=yes
- export_dynamic_flag_spec_F77='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_shlibpath_var_F77=no
- ;;
-
- *)
- ld_shlibs_F77=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5
-echo "${ECHO_T}$ld_shlibs_F77" >&6; }
-test "$ld_shlibs_F77" = no && can_build_shared=no
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc_F77" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc_F77=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds_F77 in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
- $rm conftest*
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl_F77
- pic_flag=$lt_prog_compiler_pic_F77
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag_F77
- allow_undefined_flag_F77=
- if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
- (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
- then
- archive_cmds_need_lc_F77=no
- else
- archive_cmds_need_lc_F77=yes
- fi
- allow_undefined_flag_F77=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $rm conftest*
- { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5
-echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6; }
- ;;
- esac
- fi
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-if test "$GCC" = yes; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix4* | aix5*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $rm \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='.dylib'
- # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
- if test "$GCC" = yes; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
- else
- sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
- fi
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-kfreebsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='GNU ld.so'
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[123]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- freebsd*) # from 4.6 on
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix3*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-knetbsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='GNU ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-nto-qnx*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- shlibpath_overrides_runpath=no
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- shlibpath_overrides_runpath=yes
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
-hardcode_action_F77=
-if test -n "$hardcode_libdir_flag_spec_F77" || \
- test -n "$runpath_var_F77" || \
- test "X$hardcode_automatic_F77" = "Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct_F77" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no &&
- test "$hardcode_minus_L_F77" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action_F77=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action_F77=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action_F77=unsupported
-fi
-{ echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5
-echo "${ECHO_T}$hardcode_action_F77" >&6; }
-
-if test "$hardcode_action_F77" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-
-# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- compiler_F77 \
- CC_F77 \
- LD_F77 \
- lt_prog_compiler_wl_F77 \
- lt_prog_compiler_pic_F77 \
- lt_prog_compiler_static_F77 \
- lt_prog_compiler_no_builtin_flag_F77 \
- export_dynamic_flag_spec_F77 \
- thread_safe_flag_spec_F77 \
- whole_archive_flag_spec_F77 \
- enable_shared_with_static_runtimes_F77 \
- old_archive_cmds_F77 \
- old_archive_from_new_cmds_F77 \
- predep_objects_F77 \
- postdep_objects_F77 \
- predeps_F77 \
- postdeps_F77 \
- compiler_lib_search_path_F77 \
- archive_cmds_F77 \
- archive_expsym_cmds_F77 \
- postinstall_cmds_F77 \
- postuninstall_cmds_F77 \
- old_archive_from_expsyms_cmds_F77 \
- allow_undefined_flag_F77 \
- no_undefined_flag_F77 \
- export_symbols_cmds_F77 \
- hardcode_libdir_flag_spec_F77 \
- hardcode_libdir_flag_spec_ld_F77 \
- hardcode_libdir_separator_F77 \
- hardcode_automatic_F77 \
- module_cmds_F77 \
- module_expsym_cmds_F77 \
- lt_cv_prog_compiler_c_o_F77 \
- exclude_expsyms_F77 \
- include_expsyms_F77; do
-
- case $var in
- old_archive_cmds_F77 | \
- old_archive_from_new_cmds_F77 | \
- archive_cmds_F77 | \
- archive_expsym_cmds_F77 | \
- module_cmds_F77 | \
- module_expsym_cmds_F77 | \
- old_archive_from_expsyms_cmds_F77 | \
- export_symbols_cmds_F77 | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\$0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
- ;;
- esac
-
-cfgfile="$ofile"
-
- cat <<__EOF__ >> "$cfgfile"
-# ### BEGIN LIBTOOL TAG CONFIG: $tagname
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc_F77
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_compiler_F77
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC_F77
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_LD_F77
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl_F77
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic_F77
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static_F77
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds_F77
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds_F77
-archive_expsym_cmds=$lt_archive_expsym_cmds_F77
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_module_cmds_F77
-module_expsym_cmds=$lt_module_expsym_cmds_F77
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_predep_objects_F77
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_postdep_objects_F77
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_predeps_F77
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_postdeps_F77
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_F77
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag_F77
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag_F77
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action_F77
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct_F77
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L_F77
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var_F77
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$hardcode_automatic_F77
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs_F77
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path_F77"
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols_F77
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds_F77
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms_F77
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms_F77
-
-# ### END LIBTOOL TAG CONFIG: $tagname
-
-__EOF__
-
-
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-CC="$lt_save_CC"
-
- else
- tagname=""
- fi
- ;;
-
- GCJ)
- if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# Source file extension for Java test sources.
-ac_ext=java
-
-# Object file extension for compiled Java test sources.
-objext=o
-objext_GCJ=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="class foo {}\n"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n'
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-
-ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm conftest*
-
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-CC=${GCJ-"gcj"}
-compiler=$CC
-compiler_GCJ=$CC
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-
-# GCJ did not exist at the time GCC didn't implicitly link libc in.
-archive_cmds_need_lc_GCJ=no
-
-old_archive_cmds_GCJ=$old_archive_cmds
-
-
-lt_prog_compiler_no_builtin_flag_GCJ=
-
-if test "$GCC" = yes; then
- lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin'
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
-echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_rtti_exceptions=no
- ac_outfile=conftest.$ac_objext
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="-fno-rtti -fno-exceptions"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:24290: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:24294: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_rtti_exceptions=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; }
-
-if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
- lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions"
-else
- :
-fi
-
-fi
-
-lt_prog_compiler_wl_GCJ=
-lt_prog_compiler_pic_GCJ=
-lt_prog_compiler_static_GCJ=
-
-{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
-
- if test "$GCC" = yes; then
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_static_GCJ='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_GCJ='-Bstatic'
- fi
- ;;
-
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4'
- ;;
-
- beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic_GCJ='-fno-common'
- ;;
-
- interix3*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- lt_prog_compiler_can_build_shared_GCJ=no
- enable_shared=no
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic_GCJ=-Kconform_pic
- fi
- ;;
-
- hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_GCJ='-fPIC'
- ;;
- esac
- ;;
-
- *)
- lt_prog_compiler_pic_GCJ='-fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_GCJ='-Bstatic'
- else
- lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- case $cc_basename in
- xlc*)
- lt_prog_compiler_pic_GCJ='-qnocommon'
- lt_prog_compiler_wl_GCJ='-Wl,'
- ;;
- esac
- ;;
-
- mingw* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
- ;;
-
- hpux9* | hpux10* | hpux11*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_GCJ='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- # PIC (with -KPIC) is the default.
- lt_prog_compiler_static_GCJ='-non_shared'
- ;;
-
- newsos6)
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
-
- linux*)
- case $cc_basename in
- icc* | ecc*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_pic_GCJ='-fpic'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
- ccc*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- # All Alpha code is PIC.
- lt_prog_compiler_static_GCJ='-non_shared'
- ;;
- esac
- ;;
-
- osf3* | osf4* | osf5*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- # All OSF/1 code is PIC.
- lt_prog_compiler_static_GCJ='-non_shared'
- ;;
-
- solaris*)
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- lt_prog_compiler_wl_GCJ='-Qoption ld ';;
- *)
- lt_prog_compiler_wl_GCJ='-Wl,';;
- esac
- ;;
-
- sunos4*)
- lt_prog_compiler_wl_GCJ='-Qoption ld '
- lt_prog_compiler_pic_GCJ='-PIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- lt_prog_compiler_pic_GCJ='-Kconform_pic'
- lt_prog_compiler_static_GCJ='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
-
- unicos*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_can_build_shared_GCJ=no
- ;;
-
- uts4*)
- lt_prog_compiler_pic_GCJ='-pic'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
-
- *)
- lt_prog_compiler_can_build_shared_GCJ=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6; }
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic_GCJ"; then
-
-{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6; }
-if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_prog_compiler_pic_works_GCJ=no
- ac_outfile=conftest.$ac_objext
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic_GCJ"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:24558: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:24562: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_prog_compiler_pic_works_GCJ=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6; }
-
-if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then
- case $lt_prog_compiler_pic_GCJ in
- "" | " "*) ;;
- *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;;
- esac
-else
- lt_prog_compiler_pic_GCJ=
- lt_prog_compiler_can_build_shared_GCJ=no
-fi
-
-fi
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic_GCJ=
- ;;
- *)
- lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ"
- ;;
-esac
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\"
-{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
-if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_prog_compiler_static_works_GCJ=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- printf "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_prog_compiler_static_works_GCJ=yes
- fi
- else
- lt_prog_compiler_static_works_GCJ=yes
- fi
- fi
- $rm conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5
-echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6; }
-
-if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then
- :
-else
- lt_prog_compiler_static_GCJ=
-fi
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_c_o_GCJ=no
- $rm -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:24662: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:24666: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o_GCJ=yes
- fi
- fi
- chmod u+w . 2>&5
- $rm conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
- $rm out/* && rmdir out
- cd ..
- rmdir conftest
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6; }
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
- hard_links=yes
- $rm conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6; }
- if test "$hard_links" = no; then
- { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
-
- runpath_var=
- allow_undefined_flag_GCJ=
- enable_shared_with_static_runtimes_GCJ=no
- archive_cmds_GCJ=
- archive_expsym_cmds_GCJ=
- old_archive_From_new_cmds_GCJ=
- old_archive_from_expsyms_cmds_GCJ=
- export_dynamic_flag_spec_GCJ=
- whole_archive_flag_spec_GCJ=
- thread_safe_flag_spec_GCJ=
- hardcode_libdir_flag_spec_GCJ=
- hardcode_libdir_flag_spec_ld_GCJ=
- hardcode_libdir_separator_GCJ=
- hardcode_direct_GCJ=no
- hardcode_minus_L_GCJ=no
- hardcode_shlibpath_var_GCJ=unsupported
- link_all_deplibs_GCJ=unknown
- hardcode_automatic_GCJ=no
- module_cmds_GCJ=
- module_expsym_cmds_GCJ=
- always_export_symbols_GCJ=no
- export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- include_expsyms_GCJ=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_"
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- extract_expsyms_cmds=
- # Just being paranoid about ensuring that cc_basename is set.
- for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
- case $host_os in
- cygwin* | mingw* | pw32*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- esac
-
- ld_shlibs_GCJ=yes
- if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_GCJ='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec_GCJ=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix3* | aix4* | aix5*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs_GCJ=no
- cat <<EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-EOF
- fi
- ;;
-
- amigaos*)
- archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_minus_L_GCJ=yes
-
- # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we can't use
- # them.
- ld_shlibs_GCJ=no
- ;;
-
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag_GCJ=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs_GCJ=no
- fi
- ;;
-
- cygwin* | mingw* | pw32*)
- # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- allow_undefined_flag_GCJ=unsupported
- always_export_symbols_GCJ=no
- enable_shared_with_static_runtimes_GCJ=yes
- export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs_GCJ=no
- fi
- ;;
-
- interix3*)
- hardcode_direct_GCJ=no
- hardcode_shlibpath_var_GCJ=no
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_GCJ='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- linux*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- tmp_addflag=
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- esac
- archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test $supports_anon_versioning = yes; then
- archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- $echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
- else
- ld_shlibs_GCJ=no
- fi
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- ld_shlibs_GCJ=no
- cat <<EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-EOF
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs_GCJ=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs_GCJ=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
- archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
- else
- ld_shlibs_GCJ=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- hardcode_direct_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs_GCJ=no
- fi
- ;;
- esac
-
- if test "$ld_shlibs_GCJ" = no; then
- runpath_var=
- hardcode_libdir_flag_spec_GCJ=
- export_dynamic_flag_spec_GCJ=
- whole_archive_flag_spec_GCJ=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- allow_undefined_flag_GCJ=unsupported
- always_export_symbols_GCJ=yes
- archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L_GCJ=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct_GCJ=unsupported
- fi
- ;;
-
- aix4* | aix5*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
- export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix5*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds_GCJ=''
- hardcode_direct_GCJ=yes
- hardcode_libdir_separator_GCJ=':'
- link_all_deplibs_GCJ=yes
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- hardcode_direct_GCJ=yes
- else
- # We have old collect2
- hardcode_direct_GCJ=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L_GCJ=yes
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_libdir_separator_GCJ=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols_GCJ=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag_GCJ='-berok'
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`; fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag_GCJ="-z nodefs"
- archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
-
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`; fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag_GCJ=' ${wl}-bernotok'
- allow_undefined_flag_GCJ=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_GCJ='$convenience'
- archive_cmds_need_lc_GCJ=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_minus_L_GCJ=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs_GCJ=no
- ;;
-
- bsdi[45]*)
- export_dynamic_flag_spec_GCJ=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec_GCJ=' '
- allow_undefined_flag_GCJ=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_From_new_cmds_GCJ='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`'
- enable_shared_with_static_runtimes_GCJ=yes
- ;;
-
- darwin* | rhapsody*)
- case $host_os in
- rhapsody* | darwin1.[012])
- allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress'
- ;;
- *) # Darwin 1.3 on
- if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
- allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- else
- case ${MACOSX_DEPLOYMENT_TARGET} in
- 10.[012])
- allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- ;;
- 10.*)
- allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup'
- ;;
- esac
- fi
- ;;
- esac
- archive_cmds_need_lc_GCJ=no
- hardcode_direct_GCJ=no
- hardcode_automatic_GCJ=yes
- hardcode_shlibpath_var_GCJ=unsupported
- whole_archive_flag_spec_GCJ=''
- link_all_deplibs_GCJ=yes
- if test "$GCC" = yes ; then
- output_verbose_link_cmd='echo'
- archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- else
- case $cc_basename in
- xlc*)
- output_verbose_link_cmd='echo'
- archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
- module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- ;;
- *)
- ld_shlibs_GCJ=no
- ;;
- esac
- fi
- ;;
-
- dgux*)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- freebsd1*)
- ld_shlibs_GCJ=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- hardcode_libdir_flag_spec_GCJ='-R$libdir'
- hardcode_direct_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_GCJ=yes
- hardcode_minus_L_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | kfreebsd*-gnu | dragonfly*)
- archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec_GCJ='-R$libdir'
- hardcode_direct_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
- hardcode_direct_GCJ=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_GCJ=yes
- export_dynamic_flag_spec_GCJ='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
-
- hardcode_direct_GCJ=yes
- export_dynamic_flag_spec_GCJ='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_GCJ=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_libdir_flag_spec_ld_GCJ='+b $libdir'
- hardcode_direct_GCJ=no
- hardcode_shlibpath_var_GCJ=no
- ;;
- *)
- hardcode_direct_GCJ=yes
- export_dynamic_flag_spec_GCJ='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_GCJ=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir'
- fi
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
- link_all_deplibs_GCJ=yes
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- hardcode_libdir_flag_spec_GCJ='-R$libdir'
- hardcode_direct_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- newsos6)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_GCJ=yes
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- openbsd*)
- hardcode_direct_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_GCJ='${wl}-E'
- else
- case $host_os in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_GCJ='-R$libdir'
- ;;
- *)
- archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- ;;
-
- os2*)
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_minus_L_GCJ=yes
- allow_undefined_flag_GCJ=unsupported
- archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- allow_undefined_flag_GCJ=' -expect_unresolved \*'
- archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
- else
- allow_undefined_flag_GCJ=' -expect_unresolved \*'
- archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec_GCJ='-rpath $libdir'
- fi
- hardcode_libdir_separator_GCJ=:
- ;;
-
- solaris*)
- no_undefined_flag_GCJ=' -z text'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
- else
- wlarc=''
- archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- fi
- hardcode_libdir_flag_spec_GCJ='-R$libdir'
- hardcode_shlibpath_var_GCJ=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine linker options so we
- # cannot just pass the convience library names through
- # without $wl, iff we do not link with $LD.
- # Luckily, gcc supports the same syntax we need for Sun Studio.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- case $wlarc in
- '')
- whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;;
- *)
- whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
- esac ;;
- esac
- link_all_deplibs_GCJ=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_direct_GCJ=yes
- hardcode_minus_L_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_GCJ=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- reload_cmds_GCJ='$CC -r -o $output$reload_objs'
- hardcode_direct_GCJ=no
- ;;
- motorola)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- sysv4.3*)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var_GCJ=no
- export_dynamic_flag_spec_GCJ='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var_GCJ=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ld_shlibs_GCJ=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
- no_undefined_flag_GCJ='${wl}-z,text'
- archive_cmds_need_lc_GCJ=no
- hardcode_shlibpath_var_GCJ=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- no_undefined_flag_GCJ='${wl}-z,text'
- allow_undefined_flag_GCJ='${wl}-z,nodefs'
- archive_cmds_need_lc_GCJ=no
- hardcode_shlibpath_var_GCJ=no
- hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- hardcode_libdir_separator_GCJ=':'
- link_all_deplibs_GCJ=yes
- export_dynamic_flag_spec_GCJ='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- *)
- ld_shlibs_GCJ=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5
-echo "${ECHO_T}$ld_shlibs_GCJ" >&6; }
-test "$ld_shlibs_GCJ" = no && can_build_shared=no
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc_GCJ" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc_GCJ=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds_GCJ in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
- $rm conftest*
- printf "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl_GCJ
- pic_flag=$lt_prog_compiler_pic_GCJ
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ
- allow_undefined_flag_GCJ=
- if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
- (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
- then
- archive_cmds_need_lc_GCJ=no
- else
- archive_cmds_need_lc_GCJ=yes
- fi
- allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $rm conftest*
- { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5
-echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6; }
- ;;
- esac
- fi
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-if test "$GCC" = yes; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix4* | aix5*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $rm \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='.dylib'
- # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
- if test "$GCC" = yes; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
- else
- sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
- fi
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-kfreebsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='GNU ld.so'
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[123]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- freebsd*) # from 4.6 on
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix3*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-knetbsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='GNU ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-nto-qnx*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- shlibpath_overrides_runpath=no
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- shlibpath_overrides_runpath=yes
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
-hardcode_action_GCJ=
-if test -n "$hardcode_libdir_flag_spec_GCJ" || \
- test -n "$runpath_var_GCJ" || \
- test "X$hardcode_automatic_GCJ" = "Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct_GCJ" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no &&
- test "$hardcode_minus_L_GCJ" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action_GCJ=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action_GCJ=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action_GCJ=unsupported
-fi
-{ echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5
-echo "${ECHO_T}$hardcode_action_GCJ" >&6; }
-
-if test "$hardcode_action_GCJ" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-
-# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- compiler_GCJ \
- CC_GCJ \
- LD_GCJ \
- lt_prog_compiler_wl_GCJ \
- lt_prog_compiler_pic_GCJ \
- lt_prog_compiler_static_GCJ \
- lt_prog_compiler_no_builtin_flag_GCJ \
- export_dynamic_flag_spec_GCJ \
- thread_safe_flag_spec_GCJ \
- whole_archive_flag_spec_GCJ \
- enable_shared_with_static_runtimes_GCJ \
- old_archive_cmds_GCJ \
- old_archive_from_new_cmds_GCJ \
- predep_objects_GCJ \
- postdep_objects_GCJ \
- predeps_GCJ \
- postdeps_GCJ \
- compiler_lib_search_path_GCJ \
- archive_cmds_GCJ \
- archive_expsym_cmds_GCJ \
- postinstall_cmds_GCJ \
- postuninstall_cmds_GCJ \
- old_archive_from_expsyms_cmds_GCJ \
- allow_undefined_flag_GCJ \
- no_undefined_flag_GCJ \
- export_symbols_cmds_GCJ \
- hardcode_libdir_flag_spec_GCJ \
- hardcode_libdir_flag_spec_ld_GCJ \
- hardcode_libdir_separator_GCJ \
- hardcode_automatic_GCJ \
- module_cmds_GCJ \
- module_expsym_cmds_GCJ \
- lt_cv_prog_compiler_c_o_GCJ \
- exclude_expsyms_GCJ \
- include_expsyms_GCJ; do
-
- case $var in
- old_archive_cmds_GCJ | \
- old_archive_from_new_cmds_GCJ | \
- archive_cmds_GCJ | \
- archive_expsym_cmds_GCJ | \
- module_cmds_GCJ | \
- module_expsym_cmds_GCJ | \
- old_archive_from_expsyms_cmds_GCJ | \
- export_symbols_cmds_GCJ | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\$0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
- ;;
- esac
-
-cfgfile="$ofile"
-
- cat <<__EOF__ >> "$cfgfile"
-# ### BEGIN LIBTOOL TAG CONFIG: $tagname
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc_GCJ
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_compiler_GCJ
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC_GCJ
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_LD_GCJ
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl_GCJ
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic_GCJ
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static_GCJ
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds_GCJ
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds_GCJ
-archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_module_cmds_GCJ
-module_expsym_cmds=$lt_module_expsym_cmds_GCJ
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_predep_objects_GCJ
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_postdep_objects_GCJ
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_predeps_GCJ
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_postdeps_GCJ
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag_GCJ
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag_GCJ
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action_GCJ
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct_GCJ
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L_GCJ
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$hardcode_automatic_GCJ
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs_GCJ
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path_GCJ"
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols_GCJ
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds_GCJ
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms_GCJ
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms_GCJ
-
-# ### END LIBTOOL TAG CONFIG: $tagname
-
-__EOF__
-
-
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-CC="$lt_save_CC"
-
- else
- tagname=""
- fi
- ;;
-
- RC)
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# Source file extension for RC test sources.
-ac_ext=rc
-
-# Object file extension for compiled RC test sources.
-objext=o
-objext_RC=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
-
-# Code to be used in simple link tests
-lt_simple_link_test_code="$lt_simple_compile_test_code"
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-
-ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm conftest*
-
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-CC=${RC-"windres"}
-compiler=$CC
-compiler_RC=$CC
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-lt_cv_prog_compiler_c_o_RC=yes
-
-# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- compiler_RC \
- CC_RC \
- LD_RC \
- lt_prog_compiler_wl_RC \
- lt_prog_compiler_pic_RC \
- lt_prog_compiler_static_RC \
- lt_prog_compiler_no_builtin_flag_RC \
- export_dynamic_flag_spec_RC \
- thread_safe_flag_spec_RC \
- whole_archive_flag_spec_RC \
- enable_shared_with_static_runtimes_RC \
- old_archive_cmds_RC \
- old_archive_from_new_cmds_RC \
- predep_objects_RC \
- postdep_objects_RC \
- predeps_RC \
- postdeps_RC \
- compiler_lib_search_path_RC \
- archive_cmds_RC \
- archive_expsym_cmds_RC \
- postinstall_cmds_RC \
- postuninstall_cmds_RC \
- old_archive_from_expsyms_cmds_RC \
- allow_undefined_flag_RC \
- no_undefined_flag_RC \
- export_symbols_cmds_RC \
- hardcode_libdir_flag_spec_RC \
- hardcode_libdir_flag_spec_ld_RC \
- hardcode_libdir_separator_RC \
- hardcode_automatic_RC \
- module_cmds_RC \
- module_expsym_cmds_RC \
- lt_cv_prog_compiler_c_o_RC \
- exclude_expsyms_RC \
- include_expsyms_RC; do
-
- case $var in
- old_archive_cmds_RC | \
- old_archive_from_new_cmds_RC | \
- archive_cmds_RC | \
- archive_expsym_cmds_RC | \
- module_cmds_RC | \
- module_expsym_cmds_RC | \
- old_archive_from_expsyms_cmds_RC | \
- export_symbols_cmds_RC | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\$0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
- ;;
- esac
-
-cfgfile="$ofile"
-
- cat <<__EOF__ >> "$cfgfile"
-# ### BEGIN LIBTOOL TAG CONFIG: $tagname
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc_RC
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_compiler_RC
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC_RC
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_LD_RC
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl_RC
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic_RC
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static_RC
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds_RC
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds_RC
-archive_expsym_cmds=$lt_archive_expsym_cmds_RC
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_module_cmds_RC
-module_expsym_cmds=$lt_module_expsym_cmds_RC
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_predep_objects_RC
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_postdep_objects_RC
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_predeps_RC
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_postdeps_RC
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_RC
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag_RC
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag_RC
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action_RC
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct_RC
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L_RC
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var_RC
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$hardcode_automatic_RC
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs_RC
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path_RC"
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols_RC
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds_RC
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms_RC
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms_RC
-
-# ### END LIBTOOL TAG CONFIG: $tagname
-
-__EOF__
-
-
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-CC="$lt_save_CC"
-
- ;;
-
- *)
- { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5
-echo "$as_me: error: Unsupported tag name: $tagname" >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
-
- # Append the new tag name to the list of available tags.
- if test -n "$tagname" ; then
- available_tags="$available_tags $tagname"
- fi
- fi
- done
- IFS="$lt_save_ifs"
-
- # Now substitute the updated list of available tags.
- if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
- mv "${ofile}T" "$ofile"
- chmod +x "$ofile"
- else
- rm -f "${ofile}T"
- { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5
-echo "$as_me: error: unable to update list of available tagged configurations." >&2;}
- { (exit 1); exit 1; }; }
- fi
-fi
-
-
-
-# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
-
-# Always use our own libtool.
-LIBTOOL='$(SHELL) $(top_builddir)/mklib'
-
-# Prevent multiple expansion
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-if test "$lt_cv_dlopen_self" = "yes" ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define CAN_DLOPEN_SELF 1
-_ACEOF
-
-fi
-
if test "$WITH_LLVMGCCDIR" = "default" ; then
LLVMGCC="llvm-gcc${EXEEXT}"
@@ -28043,8 +13370,9 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
else
- { echo "$as_me:$LINENO: WARNING: libffi not found - disabling external calls from interpreter" >&5
-echo "$as_me: WARNING: libffi not found - disabling external calls from interpreter" >&2;}
+ { { echo "$as_me:$LINENO: error: libffi not found - configure without --enable-libffi to compile without it" >&5
+echo "$as_me: error: libffi not found - configure without --enable-libffi to compile without it" >&2;}
+ { (exit 1); exit 1; }; }
fi
fi
@@ -31072,6 +16400,7 @@ fi
+
{ echo "$as_me:$LINENO: checking for HUGE_VAL sanity" >&5
echo $ECHO_N "checking for HUGE_VAL sanity... $ECHO_C" >&6; }
if test "${ac_cv_huge_val_sanity+set}" = set; then
@@ -31309,80 +16638,11 @@ _ACEOF
fi
-{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5
-echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; }
-if test "${ac_cv_type_signal+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <signal.h>
-
-int
-main ()
-{
-return *(signal (0, 0)) (0) == 1;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_signal=int
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_signal=void
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
-echo "${ECHO_T}$ac_cv_type_signal" >&6; }
cat >>confdefs.h <<_ACEOF
-#define RETSIGTYPE $ac_cv_type_signal
+#define RETSIGTYPE void
_ACEOF
-
{ echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6; }
if test "${ac_cv_struct_tm+set}" = set; then
@@ -32709,413 +17969,6 @@ _ACEOF
fi
-# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
-# for constant arguments. Useless!
-{ echo "$as_me:$LINENO: checking for working alloca.h" >&5
-echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6; }
-if test "${ac_cv_working_alloca_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <alloca.h>
-int
-main ()
-{
-char *p = (char *) alloca (2 * sizeof (int));
- if (p) return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_working_alloca_h=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_working_alloca_h=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
-echo "${ECHO_T}$ac_cv_working_alloca_h" >&6; }
-if test $ac_cv_working_alloca_h = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_ALLOCA_H 1
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for alloca" >&5
-echo $ECHO_N "checking for alloca... $ECHO_C" >&6; }
-if test "${ac_cv_func_alloca_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __GNUC__
-# define alloca __builtin_alloca
-#else
-# ifdef _MSC_VER
-# include <malloc.h>
-# define alloca _alloca
-# else
-# if HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifdef _AIX
- #pragma alloca
-# else
-# ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-# endif
-# endif
-# endif
-# endif
-#endif
-
-int
-main ()
-{
-char *p = (char *) alloca (1);
- if (p) return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_alloca_works=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_func_alloca_works=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
-echo "${ECHO_T}$ac_cv_func_alloca_works" >&6; }
-
-if test $ac_cv_func_alloca_works = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_ALLOCA 1
-_ACEOF
-
-else
- # The SVR3 libPW and SVR4 libucb both contain incompatible functions
-# that cause trouble. Some versions do not even contain alloca or
-# contain a buggy version. If you still want to use their alloca,
-# use ar to extract alloca.o from them instead of compiling alloca.c.
-
-ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
-
-cat >>confdefs.h <<\_ACEOF
-#define C_ALLOCA 1
-_ACEOF
-
-
-{ echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
-echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6; }
-if test "${ac_cv_os_cray+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#if defined CRAY && ! defined CRAY2
-webecray
-#else
-wenotbecray
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "webecray" >/dev/null 2>&1; then
- ac_cv_os_cray=yes
-else
- ac_cv_os_cray=no
-fi
-rm -f conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
-echo "${ECHO_T}$ac_cv_os_cray" >&6; }
-if test $ac_cv_os_cray = yes; then
- for ac_func in _getb67 GETB67 getb67; do
- as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
-int
-main ()
-{
-return $ac_func ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_var=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define CRAY_STACKSEG_END $ac_func
-_ACEOF
-
- break
-fi
-
- done
-fi
-
-{ echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
-echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6; }
-if test "${ac_cv_c_stack_direction+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_c_stack_direction=0
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-find_stack_direction ()
-{
- static char *addr = 0;
- auto char dummy;
- if (addr == 0)
- {
- addr = &dummy;
- return find_stack_direction ();
- }
- else
- return (&dummy > addr) ? 1 : -1;
-}
-
-int
-main ()
-{
- return find_stack_direction () < 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_c_stack_direction=1
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_c_stack_direction=-1
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
-echo "${ECHO_T}$ac_cv_c_stack_direction" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define STACK_DIRECTION $ac_cv_c_stack_direction
-_ACEOF
-
-
-fi
-
{ echo "$as_me:$LINENO: checking for srand48/lrand48/drand48 in <stdlib.h>" >&5
echo $ECHO_N "checking for srand48/lrand48/drand48 in <stdlib.h>... $ECHO_C" >&6; }
@@ -33205,387 +18058,6 @@ _ACEOF
fi
-{ echo "$as_me:$LINENO: checking whether the compiler implements namespaces" >&5
-echo $ECHO_N "checking whether the compiler implements namespaces... $ECHO_C" >&6; }
-if test "${ac_cv_cxx_namespaces+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-namespace Outer { namespace Inner { int i = 0; }}
-int
-main ()
-{
-using namespace Outer::Inner; return i;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_cxx_namespaces=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_cxx_namespaces=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_cxx_namespaces" >&5
-echo "${ECHO_T}$ac_cv_cxx_namespaces" >&6; }
-if test "$ac_cv_cxx_namespaces" = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_NAMESPACES
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking whether the compiler has the standard iterator" >&5
-echo $ECHO_N "checking whether the compiler has the standard iterator... $ECHO_C" >&6; }
-if test "${ac_cv_cxx_have_std_iterator+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <iterator>
-#ifdef HAVE_NAMESPACES
-using namespace std;
-#endif
-int
-main ()
-{
-iterator<int,int,int> t; return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_cxx_have_std_iterator=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_cxx_have_std_iterator=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_cxx_have_std_iterator" >&5
-echo "${ECHO_T}$ac_cv_cxx_have_std_iterator" >&6; }
-if test "$ac_cv_cxx_have_std_iterator" = yes
-then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_STD_ITERATOR 1
-_ACEOF
-
-else
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_STD_ITERATOR 0
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking whether the compiler has the bidirectional iterator" >&5
-echo $ECHO_N "checking whether the compiler has the bidirectional iterator... $ECHO_C" >&6; }
-if test "${ac_cv_cxx_have_bi_iterator+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <iterator>
-#ifdef HAVE_NAMESPACES
-using namespace std;
-#endif
-int
-main ()
-{
-bidirectional_iterator<int,int> t; return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_cxx_have_bi_iterator=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_cxx_have_bi_iterator=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_cxx_have_bi_iterator" >&5
-echo "${ECHO_T}$ac_cv_cxx_have_bi_iterator" >&6; }
-if test "$ac_cv_cxx_have_bi_iterator" = yes
-then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_BI_ITERATOR 1
-_ACEOF
-
-else
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_BI_ITERATOR 0
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking whether the compiler has forward iterators" >&5
-echo $ECHO_N "checking whether the compiler has forward iterators... $ECHO_C" >&6; }
-if test "${ac_cv_cxx_have_fwd_iterator+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <iterator>
-#ifdef HAVE_NAMESPACES
-using namespace std;
-#endif
-int
-main ()
-{
-forward_iterator<int,int> t; return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_cxx_have_fwd_iterator=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_cxx_have_fwd_iterator=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_cxx_have_fwd_iterator" >&5
-echo "${ECHO_T}$ac_cv_cxx_have_fwd_iterator" >&6; }
-if test "$ac_cv_cxx_have_fwd_iterator" = yes
-then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_FWD_ITERATOR 1
-_ACEOF
-
-else
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_FWD_ITERATOR 0
-_ACEOF
-
-fi
-
{ echo "$as_me:$LINENO: checking for isnan in <math.h>" >&5
echo $ECHO_N "checking for isnan in <math.h>... $ECHO_C" >&6; }
@@ -36245,6 +20717,7 @@ FIND!$FIND$ac_delim
MKDIR!$MKDIR$ac_delim
MV!$MV$ac_delim
RANLIB!$RANLIB$ac_delim
+AR!$AR$ac_delim
RM!$RM$ac_delim
SED!$SED$ac_delim
TAR!$TAR$ac_delim
@@ -36281,14 +20754,6 @@ INSTALL_LTDL_FALSE!$INSTALL_LTDL_FALSE$ac_delim
CONVENIENCE_LTDL_TRUE!$CONVENIENCE_LTDL_TRUE$ac_delim
CONVENIENCE_LTDL_FALSE!$CONVENIENCE_LTDL_FALSE$ac_delim
LIBADD_DL!$LIBADD_DL$ac_delim
-ECHO!$ECHO$ac_delim
-AR!$AR$ac_delim
-STRIP!$STRIP$ac_delim
-CXXCPP!$CXXCPP$ac_delim
-F77!$F77$ac_delim
-FFLAGS!$FFLAGS$ac_delim
-ac_ct_F77!$ac_ct_F77$ac_delim
-LIBTOOL!$LIBTOOL$ac_delim
LLVMGCCCOMMAND!$LLVMGCCCOMMAND$ac_delim
LLVMGXXCOMMAND!$LLVMGXXCOMMAND$ac_delim
LLVMGCC!$LLVMGCC$ac_delim
@@ -36299,7 +20764,6 @@ USE_UDIS86!$USE_UDIS86$ac_delim
USE_OPROFILE!$USE_OPROFILE$ac_delim
HAVE_PTHREAD!$HAVE_PTHREAD$ac_delim
HUGE_VAL_SANITY!$HUGE_VAL_SANITY$ac_delim
-ALLOCA!$ALLOCA$ac_delim
MMAP_FILE!$MMAP_FILE$ac_delim
LLVMCC1!$LLVMCC1$ac_delim
LLVMCC1PLUS!$LLVMCC1PLUS$ac_delim
@@ -36329,7 +20793,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 96; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 88; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -36348,7 +20812,7 @@ fi
cat >>$CONFIG_STATUS <<_ACEOF
cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
_ACEOF
sed '
s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
@@ -36361,6 +20825,8 @@ N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
' >>$CONFIG_STATUS <conf$$subs.sed
rm -f conf$$subs.sed
cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
CEOF$ac_eof
_ACEOF
@@ -36608,7 +21074,7 @@ s&@abs_builddir@&$ac_abs_builddir&;t t
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
s&@INSTALL@&$ac_INSTALL&;t t
$ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" | sed 's/|#_!!_#|//g' >$tmp/out
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
diff --git a/docs/CommandGuide/lit.pod b/docs/CommandGuide/lit.pod
index 246fc66..72d9d2b 100644
--- a/docs/CommandGuide/lit.pod
+++ b/docs/CommandGuide/lit.pod
@@ -49,13 +49,13 @@ Show the B<lit> help message.
=item B<-j> I<N>, B<--threads>=I<N>
-Run I<N> tests in parallel. By default, this is automatically chose to match the
-number of detected available CPUs.
+Run I<N> tests in parallel. By default, this is automatically chosen to match
+the number of detected available CPUs.
=item B<--config-prefix>=I<NAME>
Search for I<NAME.cfg> and I<NAME.site.cfg> when searching for test suites,
-instead I<lit.cfg> and I<lit.site.cfg>.
+instead of I<lit.cfg> and I<lit.site.cfg>.
=item B<--param> I<NAME>, B<--param> I<NAME>=I<VALUE>
@@ -237,7 +237,7 @@ creating a new B<lit> testing implementation, or extending an existing one.
B<lit> proper is primarily an infrastructure for discovering and running
arbitrary tests, and to expose a single convenient interface to these
-tests. B<lit> itself doesn't contain know how to run tests, rather this logic is
+tests. B<lit> itself doesn't know how to run tests, rather this logic is
defined by I<test suites>.
=head2 TEST SUITES
diff --git a/docs/CommandGuide/llvm-extract.pod b/docs/CommandGuide/llvm-extract.pod
index b62e8ae..02f38ad 100644
--- a/docs/CommandGuide/llvm-extract.pod
+++ b/docs/CommandGuide/llvm-extract.pod
@@ -34,7 +34,13 @@ B<llvm-extract> will write raw bitcode regardless of the output device.
=item B<--func> I<function-name>
-Extract the function named I<function-name> from the LLVM bitcode.
+Extract the function named I<function-name> from the LLVM bitcode. May be
+specified multiple times to extract multiple functions at once.
+
+=item B<--glob> I<global-name>
+
+Extract the global variable named I<global-name> from the LLVM bitcode. May be
+specified multiple times to extract multiple global variables at once.
=item B<--help>
diff --git a/docs/ExceptionHandling.html b/docs/ExceptionHandling.html
index 0ca702f..dfe7ee8 100644
--- a/docs/ExceptionHandling.html
+++ b/docs/ExceptionHandling.html
@@ -39,6 +39,7 @@
<li><a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a></li>
<li><a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a></li>
<li><a href="#llvm_eh_sjlj_lsda"><tt>llvm.eh.sjlj.lsda</tt></a></li>
+ <li><a href="#llvm_eh_sjlj_callsite"><tt>llvm.eh.sjlj.callsite</tt></a></li>
</ol></li>
<li><a href="#asm">Asm Table Formats</a>
<ol>
@@ -509,6 +510,24 @@
</div>
<!-- ======================================================================= -->
+<div class="doc_subsubsection">
+ <a name="llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>
+</div>
+
+<div class="doc_text">
+
+<pre>
+ void %<a href="#llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>(i32)
+</pre>
+
+<p>For SJLJ based exception handling, the <a href="#llvm_eh_sjlj_callsite">
+ <tt>llvm.eh.sjlj.callsite</tt></a> intrinsic identifies the callsite value
+ associated with the following invoke instruction. This is used to ensure
+ that landing pad entries in the LSDA are generated in the matching order.</p>
+
+</div>
+
+<!-- ======================================================================= -->
<div class="doc_section">
<a name="asm">Asm Table Formats</a>
</div>
@@ -580,7 +599,7 @@
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-10-14 18:11:37 +0200 (Wed, 14 Oct 2009) $
+ Last modified: $Date: 2010-01-28 02:45:32 +0100 (Thu, 28 Jan 2010) $
</address>
</body>
diff --git a/docs/GettingStarted.html b/docs/GettingStarted.html
index 5f17b5b..44fbf21 100644
--- a/docs/GettingStarted.html
+++ b/docs/GettingStarted.html
@@ -256,13 +256,13 @@ software you will need.</p>
<td>Cygwin/Win32</td>
<td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_8">8</a>,
<a href="#pf_11">11</a></sup></td>
- <td>GCC 3.4.X, binutils 2.15</td>
+ <td>GCC 3.4.X, binutils 2.20</td>
</tr>
<tr>
<td>MinGW/Win32</td>
<td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_6">6</a>,
<a href="#pf_8">8</a>, <a href="#pf_10">10</a></sup></td>
- <td>GCC 3.4.X, binutils 2.15</td>
+ <td>GCC 3.4.X, binutils 2.20</td>
</tr>
</table>
@@ -318,12 +318,8 @@ up</a></li>
<li><a name="pf_5">The GCC-based C/C++ frontend does not build</a></li>
<li><a name="pf_6">The port is done using the MSYS shell.</a></li>
<li><a name="pf_7">Native code generation exists but is not complete.</a></li>
-<li><a name="pf_8">Binutils</a> up to post-2.17 has bug in bfd/cofflink.c
- preventing LLVM from building correctly. Several workarounds have been
- introduced into LLVM build system, but the bug can occur anytime in the
- future. We highly recommend that you rebuild your current binutils with the
- patch from <a href="http://sourceware.org/bugzilla/show_bug.cgi?id=2659">
- Binutils bugzilla</a>, if it wasn't already applied.</li>
+<li><a name="pf_8">Binutils 2.20 or later is required to build the assembler
+ generated by LLVM properly.</a></li>
<li><a name="pf_9">XCode 2.5 and gcc 4.0.1</a> (Apple Build 5370) will trip
internal LLVM assert messages when compiled for Release at optimization
levels greater than 0 (i.e., <i>"-O1"</i> and higher).
@@ -1671,7 +1667,7 @@ out:</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.x10sys.com/rspencer/">Reid Spencer</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-12-17 18:18:11 +0100 (Thu, 17 Dec 2009) $
+ Last modified: $Date: 2010-02-11 22:51:51 +0100 (Thu, 11 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/LangRef.html b/docs/LangRef.html
index cbb7d56..b31d22f 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -66,12 +66,17 @@
</li>
<li><a href="#t_derived">Derived Types</a>
<ol>
- <li><a href="#t_array">Array Type</a></li>
+ <li><a href="#t_aggregate">Aggregate Types</a>
+ <ol>
+ <li><a href="#t_array">Array Type</a></li>
+ <li><a href="#t_struct">Structure Type</a></li>
+ <li><a href="#t_pstruct">Packed Structure Type</a></li>
+ <li><a href="#t_union">Union Type</a></li>
+ <li><a href="#t_vector">Vector Type</a></li>
+ </ol>
+ </li>
<li><a href="#t_function">Function Type</a></li>
<li><a href="#t_pointer">Pointer Type</a></li>
- <li><a href="#t_struct">Structure Type</a></li>
- <li><a href="#t_pstruct">Packed Structure Type</a></li>
- <li><a href="#t_vector">Vector Type</a></li>
<li><a href="#t_opaque">Opaque Type</a></li>
</ol>
</li>
@@ -1078,11 +1083,21 @@ define void @f() optsize { ... }
</div>
<dl>
+ <dt><tt><b>alignstack(&lt;<em>n</em>&gt;)</b></tt></dt>
+ <dd>This attribute indicates that, when emitting the prologue and epilogue,
+ the backend should forcibly align the stack pointer. Specify the
+ desired alignment, which must be a power of two, in parentheses.
+
<dt><tt><b>alwaysinline</b></tt></dt>
<dd>This attribute indicates that the inliner should attempt to inline this
function into callers whenever possible, ignoring any active inlining size
threshold for this caller.</dd>
+ <dt><tt><b>inlinehint</b></tt></dt>
+ <dd>This attribute indicates that the source code contained a hint that inlining
+ this function is desirable (such as the "inline" keyword in C/C++). It
+ is just a hint; it imposes no requirements on the inliner.</dd>
+
<dt><tt><b>noinline</b></tt></dt>
<dd>This attribute indicates that the inliner should never inline this
function in any situation. This attribute may not be used together with
@@ -1394,6 +1409,7 @@ Classifications</a> </div>
<a href="#t_pointer">pointer</a>,
<a href="#t_vector">vector</a>,
<a href="#t_struct">structure</a>,
+ <a href="#t_union">union</a>,
<a href="#t_array">array</a>,
<a href="#t_label">label</a>,
<a href="#t_metadata">metadata</a>.
@@ -1408,12 +1424,12 @@ Classifications</a> </div>
</tr>
<tr>
<td><a href="#t_derived">derived</a></td>
- <td><a href="#t_integer">integer</a>,
- <a href="#t_array">array</a>,
+ <td><a href="#t_array">array</a>,
<a href="#t_function">function</a>,
<a href="#t_pointer">pointer</a>,
<a href="#t_struct">structure</a>,
<a href="#t_pstruct">packed structure</a>,
+ <a href="#t_union">union</a>,
<a href="#t_vector">vector</a>,
<a href="#t_opaque">opaque</a>.
</td>
@@ -1551,6 +1567,21 @@ Classifications</a> </div>
possible to have a two dimensional array, using an array as the element type
of another array.</p>
+
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection"> <a name="t_aggregate">Aggregate Types</a> </div>
+
+<div class="doc_text">
+
+<p>Aggregate Types are a subset of derived types that can contain multiple
+ member types. <a href="#t_array">Arrays</a>,
+ <a href="#t_struct">structs</a>, <a href="#t_vector">vectors</a> and
+ <a href="#t_union">unions</a> are aggregate types.</p>
+
+</div>
+
</div>
<!-- _______________________________________________________________________ -->
@@ -1619,9 +1650,9 @@ Classifications</a> </div>
<h5>Overview:</h5>
<p>The function type can be thought of as a function signature. It consists of
a return type and a list of formal parameter types. The return type of a
- function type is a scalar type, a void type, or a struct type. If the return
- type is a struct type then all struct elements must be of first class types,
- and the struct must have at least one element.</p>
+ function type is a scalar type, a void type, a struct type, or a union
+ type. If the return type is a struct type then all struct elements must be
+ of first class types, and the struct must have at least one element.</p>
<h5>Syntax:</h5>
<pre>
@@ -1744,6 +1775,53 @@ Classifications</a> </div>
</div>
<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection"> <a name="t_union">Union Type</a> </div>
+
+<div class="doc_text">
+
+<h5>Overview:</h5>
+<p>A union type describes an object with size and alignment suitable for
+ an object of any one of a given set of types (also known as an "untagged"
+ union). It is similar in concept and usage to a
+ <a href="#t_struct">struct</a>, except that all members of the union
+ have an offset of zero. The elements of a union may be any type that has a
+ size. Unions must have at least one member - empty unions are not allowed.
+ </p>
+
+<p>The size of the union as a whole will be the size of its largest member,
+ and the alignment requirements of the union as a whole will be the largest
+ alignment requirement of any member.</p>
+
+<p>Unions members are accessed using '<tt><a href="#i_load">load</a></tt> and
+ '<tt><a href="#i_store">store</a></tt>' by getting a pointer to a field with
+ the '<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.
+ Since all members are at offset zero, the getelementptr instruction does
+ not affect the address, only the type of the resulting pointer.</p>
+
+<h5>Syntax:</h5>
+<pre>
+ union { &lt;type list&gt; }
+</pre>
+
+<h5>Examples:</h5>
+<table class="layout">
+ <tr class="layout">
+ <td class="left"><tt>union { i32, i32*, float }</tt></td>
+ <td class="left">A union of three types: an <tt>i32</tt>, a pointer to
+ an <tt>i32</tt>, and a <tt>float</tt>.</td>
+ </tr><tr class="layout">
+ <td class="left">
+ <tt>union {&nbsp;float,&nbsp;i32&nbsp;(i32)&nbsp;*&nbsp;}</tt></td>
+ <td class="left">A union, where the first element is a <tt>float</tt> and the
+ second element is a <a href="#t_pointer">pointer</a> to a
+ <a href="#t_function">function</a> that takes an <tt>i32</tt>, returning
+ an <tt>i32</tt>.</td>
+ </tr>
+</table>
+
+</div>
+
+<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection"> <a name="t_pointer">Pointer Type</a> </div>
<div class="doc_text">
@@ -1981,6 +2059,14 @@ Classifications</a> </div>
the number and types of elements must match those specified by the
type.</dd>
+ <dt><b>Union constants</b></dt>
+ <dd>Union constants are represented with notation similar to a structure with
+ a single element - that is, a single typed element surrounded
+ by braces (<tt>{}</tt>)). For example: "<tt>{ i32 4 }</tt>". The
+ <a href="#t_union">union type</a> can be initialized with a single-element
+ struct as long as the type of the struct element matches the type of
+ one of the union members.</dd>
+
<dt><b>Array constants</b></dt>
<dd>Array constants are represented with notation similar to array type
definitions (a comma separated list of elements, surrounded by square
@@ -1999,7 +2085,8 @@ Classifications</a> </div>
<dt><b>Zero initialization</b></dt>
<dd>The string '<tt>zeroinitializer</tt>' can be used to zero initialize a
- value to zero of <em>any</em> type, including scalar and aggregate types.
+ value to zero of <em>any</em> type, including scalar and
+ <a href="#t_aggregate">aggregate</a> types.
This is often used to avoid having to print large zero initializers
(e.g. for large arrays) and is always exactly equivalent to using explicit
zero initializers.</dd>
@@ -3835,7 +3922,8 @@ Instruction</a> </div>
<div class="doc_text">
-<p>LLVM supports several instructions for working with aggregate values.</p>
+<p>LLVM supports several instructions for working with
+ <a href="#t_aggregate">aggregate</a> values.</p>
</div>
@@ -3852,14 +3940,14 @@ Instruction</a> </div>
</pre>
<h5>Overview:</h5>
-<p>The '<tt>extractvalue</tt>' instruction extracts the value of a struct field
- or array element from an aggregate value.</p>
+<p>The '<tt>extractvalue</tt>' instruction extracts the value of a member field
+ from an <a href="#t_aggregate">aggregate</a> value.</p>
<h5>Arguments:</h5>
<p>The first operand of an '<tt>extractvalue</tt>' instruction is a value
- of <a href="#t_struct">struct</a> or <a href="#t_array">array</a> type. The
- operands are constant indices to specify which value to extract in a similar
- manner as indices in a
+ of <a href="#t_struct">struct</a>, <a href="#t_union">union</a> or
+ <a href="#t_array">array</a> type. The operands are constant indices to
+ specify which value to extract in a similar manner as indices in a
'<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.</p>
<h5>Semantics:</h5>
@@ -3886,16 +3974,15 @@ Instruction</a> </div>
</pre>
<h5>Overview:</h5>
-<p>The '<tt>insertvalue</tt>' instruction inserts a value into a struct field or
- array element in an aggregate.</p>
-
+<p>The '<tt>insertvalue</tt>' instruction inserts a value into a member field
+ in an <a href="#t_aggregate">aggregate</a> value.</p>
<h5>Arguments:</h5>
<p>The first operand of an '<tt>insertvalue</tt>' instruction is a value
- of <a href="#t_struct">struct</a> or <a href="#t_array">array</a> type. The
- second operand is a first-class value to insert. The following operands are
- constant indices indicating the position at which to insert the value in a
- similar manner as indices in a
+ of <a href="#t_struct">struct</a>, <a href="#t_union">union</a> or
+ <a href="#t_array">array</a> type. The second operand is a first-class
+ value to insert. The following operands are constant indices indicating
+ the position at which to insert the value in a similar manner as indices in a
'<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction. The
value to insert must have the same type as the value identified by the
indices.</p>
@@ -4097,8 +4184,8 @@ Instruction</a> </div>
<h5>Overview:</h5>
<p>The '<tt>getelementptr</tt>' instruction is used to get the address of a
- subelement of an aggregate data structure. It performs address calculation
- only and does not access memory.</p>
+ subelement of an <a href="#t_aggregate">aggregate</a> data structure.
+ It performs address calculation only and does not access memory.</p>
<h5>Arguments:</h5>
<p>The first argument is always a pointer, and forms the basis of the
@@ -4108,15 +4195,15 @@ Instruction</a> </div>
indexes the pointer value given as the first argument, the second index
indexes a value of the type pointed to (not necessarily the value directly
pointed to, since the first index can be non-zero), etc. The first type
- indexed into must be a pointer value, subsequent types can be arrays, vectors
- and structs. Note that subsequent types being indexed into can never be
- pointers, since that would require loading the pointer before continuing
- calculation.</p>
+ indexed into must be a pointer value, subsequent types can be arrays,
+ vectors, structs and unions. Note that subsequent types being indexed into
+ can never be pointers, since that would require loading the pointer before
+ continuing calculation.</p>
<p>The type of each index argument depends on the type it is indexing into.
- When indexing into a (optionally packed) structure, only <tt>i32</tt> integer
- <b>constants</b> are allowed. When indexing into an array, pointer or
- vector, integers of any width are allowed, and they are not required to be
+ When indexing into a (optionally packed) structure or union, only <tt>i32</tt>
+ integer <b>constants</b> are allowed. When indexing into an array, pointer
+ or vector, integers of any width are allowed, and they are not required to be
constant.</p>
<p>For example, let's consider a C code fragment and how it gets compiled to
@@ -7345,7 +7432,7 @@ LLVM</a>.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-01-15 22:50:19 +0100 (Fri, 15 Jan 2010) $
+ Last modified: $Date: 2010-02-12 21:49:41 +0100 (Fri, 12 Feb 2010) $
</address>
</body>
diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html
index 80a5db0..df4366a 100644
--- a/docs/ProgrammersManual.html
+++ b/docs/ProgrammersManual.html
@@ -150,6 +150,7 @@ with another <tt>Value</tt></a> </li>
<li><a href="#shutdown">Ending execution with <tt>llvm_shutdown()</tt></a></li>
<li><a href="#managedstatic">Lazy initialization with <tt>ManagedStatic</tt></a></li>
<li><a href="#llvmcontext">Achieving Isolation with <tt>LLVMContext</tt></a></li>
+ <li><a href="#jitthreading">Threads and the JIT</a></li>
</ul>
</li>
@@ -2386,9 +2387,9 @@ failure of the initialization. Failure typically indicates that your copy of
LLVM was built without multithreading support, typically because GCC atomic
intrinsics were not found in your system compiler. In this case, the LLVM API
will not be safe for concurrent calls. However, it <em>will</em> be safe for
-hosting threaded applications in the JIT, though care must be taken to ensure
-that side exits and the like do not accidentally result in concurrent LLVM API
-calls.
+hosting threaded applications in the JIT, though <a href="#jitthreading">care
+must be taken</a> to ensure that side exits and the like do not accidentally
+result in concurrent LLVM API calls.
</p>
</div>
@@ -2485,6 +2486,34 @@ isolation is not a concern.
</p>
</div>
+<!-- ======================================================================= -->
+<div class="doc_subsection">
+ <a name="jitthreading">Threads and the JIT</a>
+</div>
+
+<div class="doc_text">
+<p>
+LLVM's "eager" JIT compiler is safe to use in threaded programs. Multiple
+threads can call <tt>ExecutionEngine::getPointerToFunction()</tt> or
+<tt>ExecutionEngine::runFunction()</tt> concurrently, and multiple threads can
+run code output by the JIT concurrently. The user must still ensure that only
+one thread accesses IR in a given <tt>LLVMContext</tt> while another thread
+might be modifying it. One way to do that is to always hold the JIT lock while
+accessing IR outside the JIT (the JIT <em>modifies</em> the IR by adding
+<tt>CallbackVH</tt>s). Another way is to only
+call <tt>getPointerToFunction()</tt> from the <tt>LLVMContext</tt>'s thread.
+</p>
+
+<p>When the JIT is configured to compile lazily (using
+<tt>ExecutionEngine::DisableLazyCompilation(false)</tt>), there is currently a
+<a href="http://llvm.org/bugs/show_bug.cgi?id=5184">race condition</a> in
+updating call sites after a function is lazily-jitted. It's still possible to
+use the lazy JIT in a threaded program if you ensure that only one thread at a
+time can call any particular lazy stub and that the JIT lock guards any IR
+access, but we suggest using only the eager JIT in threaded programs.
+</p>
+</div>
+
<!-- *********************************************************************** -->
<div class="doc_section">
<a name="advanced">Advanced Topics</a>
@@ -2970,9 +2999,9 @@ the <tt>lib/VMCore</tt> directory.</p>
<div class="doc_text">
<ul>
- <li><tt>bool isInteger() const</tt>: Returns true for any integer type.</li>
+ <li><tt>bool isIntegerTy() const</tt>: Returns true for any integer type.</li>
- <li><tt>bool isFloatingPoint()</tt>: Return true if this is one of the two
+ <li><tt>bool isFloatingPointTy()</tt>: Return true if this is one of the five
floating point types.</li>
<li><tt>bool isAbstract()</tt>: Return true if the type is abstract (contains
@@ -3892,7 +3921,7 @@ arguments. An argument has a pointer to the parent Function.</p>
<a href="mailto:dhurjati@cs.uiuc.edu">Dinakar Dhurjati</a> and
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-01-05 19:24:00 +0100 (Tue, 05 Jan 2010) $
+ Last modified: $Date: 2010-02-15 17:12:20 +0100 (Mon, 15 Feb 2010) $
</address>
</body>
diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html
index 03a3545..21f5082 100644
--- a/docs/ReleaseNotes.html
+++ b/docs/ReleaseNotes.html
@@ -4,17 +4,17 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="llvm.css" type="text/css">
- <title>LLVM 2.6 Release Notes</title>
+ <title>LLVM 2.7 Release Notes</title>
</head>
<body>
-<div class="doc_title">LLVM 2.6 Release Notes</div>
+<div class="doc_title">LLVM 2.7 Release Notes</div>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#subproj">Sub-project Status Update</a></li>
- <li><a href="#externalproj">External Projects Using LLVM 2.6</a></li>
- <li><a href="#whatsnew">What's New in LLVM 2.6?</a></li>
+ <li><a href="#externalproj">External Projects Using LLVM 2.7</a></li>
+ <li><a href="#whatsnew">What's New in LLVM 2.7?</a></li>
<li><a href="GettingStarted.html">Installation Instructions</a></li>
<li><a href="#portability">Portability and Supported Platforms</a></li>
<li><a href="#knownproblems">Known Problems</a></li>
@@ -25,6 +25,12 @@
<p>Written by the <a href="http://llvm.org">LLVM Team</a></p>
</div>
+<h1 style="color:red">These are in-progress notes for the upcoming LLVM 2.7
+release.<br>
+You may prefer the
+<a href="http://llvm.org/releases/2.6/docs/ReleaseNotes.html">LLVM 2.6
+Release Notes</a>.</h1>
+
<!-- *********************************************************************** -->
<div class="doc_section">
<a name="intro">Introduction</a>
@@ -34,7 +40,7 @@
<div class="doc_text">
<p>This document contains the release notes for the LLVM Compiler
-Infrastructure, release 2.6. Here we describe the status of LLVM, including
+Infrastructure, release 2.7. Here we describe the status of LLVM, including
major improvements from the previous release and significant known problems.
All LLVM releases may be downloaded from the <a
href="http://llvm.org/releases/">LLVM releases web site</a>.</p>
@@ -63,7 +69,7 @@ Almost dead code.
-->
-<!-- Unfinished features in 2.6:
+<!-- Features that need text if they're finished for 2.7:
gcc plugin.
strong phi elim
variable debug info for optimized code
@@ -94,7 +100,7 @@ Almost dead code.
<div class="doc_text">
<p>
-The LLVM 2.6 distribution currently consists of code from the core LLVM
+The LLVM 2.7 distribution currently consists of code from the core LLVM
repository (which roughly includes the LLVM optimizers, code generators
and supporting tools), the Clang repository and the llvm-gcc repository. In
addition to this code, the LLVM Project includes other sub-projects that are in
@@ -111,31 +117,12 @@ development. Here we include updates on these subprojects.
<div class="doc_text">
-<p>The <a href="http://clang.llvm.org/">Clang project</a> is an effort to build
-a set of new 'LLVM native' front-end technologies for the C family of languages.
-LLVM 2.6 is the first release to officially include Clang, and it provides a
-production quality C and Objective-C compiler. If you are interested in <a
-href="http://clang.llvm.org/performance.html">fast compiles</a> and
-<a href="http://clang.llvm.org/diagnostics.html">good diagnostics</a>, we
-encourage you to try it out. Clang currently compiles typical Objective-C code
-3x faster than GCC and compiles C code about 30% faster than GCC at -O0 -g
-(which is when the most pressure is on the frontend).</p>
-
-<p>In addition to supporting these languages, C++ support is also <a
-href="http://clang.llvm.org/cxx_status.html">well under way</a>, and mainline
-Clang is able to parse the libstdc++ 4.2 headers and even codegen simple apps.
-If you are interested in Clang C++ support or any other Clang feature, we
-strongly encourage you to get involved on the <a
-href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">Clang front-end mailing
-list</a>.</p>
-
-<p>In the LLVM 2.6 time-frame, the Clang team has made many improvements:</p>
+<p>The <a href="http://clang.llvm.org/">Clang project</a> is ...</p>
+
+<p>In the LLVM 2.7 time-frame, the Clang team has made many improvements:</p>
<ul>
-<li>C and Objective-C support are now considered production quality.</li>
-<li>AuroraUX, FreeBSD and OpenBSD are now supported.</li>
-<li>Most of Objective-C 2.0 is now supported with the GNU runtime.</li>
-<li>Many many bugs are fixed and lots of features have been added.</li>
+<li>...</li>
</ul>
</div>
@@ -146,24 +133,13 @@ list</a>.</p>
<div class="doc_text">
-<p>Previously announced in the 2.4 and 2.5 LLVM releases, the Clang project also
+<p>Previously announced in the 2.4, 2.5, and 2.6 LLVM releases, the Clang project also
includes an early stage static source code analysis tool for <a
href="http://clang.llvm.org/StaticAnalysis.html">automatically finding bugs</a>
in C and Objective-C programs. The tool performs checks to find
bugs that occur on a specific path within a program.</p>
-<p>In the LLVM 2.6 time-frame, the analyzer core has undergone several important
-improvements and cleanups and now includes a new <em>Checker</em> interface that
-is intended to eventually serve as a basis for domain-specific checks. Further,
-in addition to generating HTML files for reporting analysis results, the
-analyzer can now also emit bug reports in a structured XML format that is
-intended to be easily readable by other programs.</p>
-
-<p>The set of checks performed by the static analyzer continues to expand, and
-future plans for the tool include full source-level inter-procedural analysis
-and deeper checks such as buffer overrun detection. There are many opportunities
-to extend and enhance the static analyzer, and anyone interested in working on
-this project is encouraged to get involved!</p>
+<p>In the LLVM 2.7 time-frame, the analyzer core has ...</p>
</div>
@@ -180,20 +156,13 @@ implementation of the CLI) using LLVM for static and just-in-time
compilation.</p>
<p>
-VMKit version 0.26 builds with LLVM 2.6 and you can find it on its
+VMKit version ?? builds with LLVM 2.7 and you can find it on its
<a href="http://vmkit.llvm.org/releases/">web page</a>. The release includes
bug fixes, cleanup and new features. The major changes are:</p>
<ul>
-<li>A new llcj tool to generate shared libraries or executables of Java
- files.</li>
-<li>Cooperative garbage collection. </li>
-<li>Fast subtype checking (paper from Click et al [JGI'02]). </li>
-<li>Implementation of a two-word header for Java objects instead of the original
- three-word header. </li>
-<li>Better Java specification-compliance: division by zero checks, stack
- overflow checks, finalization and references support. </li>
+<li>...</li>
</ul>
</div>
@@ -249,22 +218,7 @@ KLEE.</p>
The goal of <a href="http://dragonegg.llvm.org/">DragonEgg</a> is to make
gcc-4.5 act like llvm-gcc without requiring any gcc modifications whatsoever.
<a href="http://dragonegg.llvm.org/">DragonEgg</a> is a shared library (dragonegg.so)
-that is loaded by gcc at runtime. It uses the new gcc plugin architecture to
-disable the GCC optimizers and code generators, and schedule the LLVM optimizers
-and code generators (or direct output of LLVM IR) instead. Currently only Linux
-and Darwin are supported, and only on x86-32 and x86-64. It should be easy to
-add additional unix-like architectures and other processor families. In theory
-it should be possible to use <a href="http://dragonegg.llvm.org/">DragonEgg</a>
-with any language supported by gcc, however only C and Fortran work well for the
-moment. Ada and C++ work to some extent, while Java, Obj-C and Obj-C++ are so
-far entirely untested. Since gcc-4.5 has not yet been released, neither has
-<a href="http://dragonegg.llvm.org/">DragonEgg</a>. To build
-<a href="http://dragonegg.llvm.org/">DragonEgg</a> you will need to check out the
-development versions of <a href="http://gcc.gnu.org/svn.html/"> gcc</a>,
-<a href="http://llvm.org/docs/GettingStarted.html#checkout">llvm</a> and
-<a href="http://dragonegg.llvm.org/">DragonEgg</a> from their respective
-subversion repositories, and follow the instructions in the
-<a href="http://dragonegg.llvm.org/">DragonEgg</a> README.
+that is loaded by gcc at runtime. It ...
</p>
</div>
@@ -277,29 +231,7 @@ subversion repositories, and follow the instructions in the
<div class="doc_text">
<p>
-The LLVM Machine Code (MC) Toolkit project is a (very early) effort to build
-better tools for dealing with machine code, object file formats, etc. The idea
-is to be able to generate most of the target specific details of assemblers and
-disassemblers from existing LLVM target .td files (with suitable enhancements),
-and to build infrastructure for reading and writing common object file formats.
-One of the first deliverables is to build a full assembler and integrate it into
-the compiler, which is predicted to substantially reduce compile time in some
-scenarios.
-</p>
-
-<p>In the LLVM 2.6 timeframe, the MC framework has grown to the point where it
-can reliably parse and pretty print (with some encoding information) a
-darwin/x86 .s file successfully, and has the very early phases of a Mach-O
-assembler in progress. Beyond the MC framework itself, major refactoring of the
-LLVM code generator has started. The idea is to make the code generator reason
-about the code it is producing in a much more semantic way, rather than a
-textual way. For example, the code generator now uses MCSection objects to
-represent section assignments, instead of text strings that print to .section
-directives.</p>
-
-<p>MC is an early and ongoing project that will hopefully continue to lead to
-many improvements in the code generator and build infrastructure useful for many
-other situations.
+The LLVM Machine Code (MC) Toolkit project is ...
</p>
</div>
@@ -307,7 +239,7 @@ other situations.
<!-- *********************************************************************** -->
<div class="doc_section">
- <a name="externalproj">External Open Source Projects Using LLVM 2.6</a>
+ <a name="externalproj">External Open Source Projects Using LLVM 2.7</a>
</div>
<!-- *********************************************************************** -->
@@ -315,7 +247,7 @@ other situations.
<p>An exciting aspect of LLVM is that it is used as an enabling technology for
a lot of other language and tools projects. This section lists some of the
- projects that have already been updated to work with LLVM 2.6.</p>
+ projects that have already been updated to work with LLVM 2.7.</p>
</div>
@@ -376,8 +308,8 @@ built-in list and matrix support (including list and matrix comprehensions) and
an easy-to-use C interface. The interpreter uses LLVM as a backend to
JIT-compile Pure programs to fast native code.</p>
-<p>Pure versions 0.31 and later have been tested and are known to work with
-LLVM 2.6 (and continue to work with older LLVM releases >= 2.3 as well).
+<p>Pure versions ??? and later have been tested and are known to work with
+LLVM 2.7 (and continue to work with older LLVM releases >= 2.3 as well).
</p>
</div>
@@ -460,7 +392,7 @@ code.
<!-- *********************************************************************** -->
<div class="doc_section">
- <a name="whatsnew">What's New in LLVM 2.6?</a>
+ <a name="whatsnew">What's New in LLVM 2.7?</a>
</div>
<!-- *********************************************************************** -->
@@ -480,28 +412,10 @@ in this section.
<div class="doc_text">
-<p>LLVM 2.6 includes several major new capabilities:</p>
+<p>LLVM 2.7 includes several major new capabilities:</p>
<ul>
-<li>New <a href="#compiler-rt">compiler-rt</a>, <A href="#klee">KLEE</a>
- and <a href="#mc">machine code toolkit</a> sub-projects.</li>
-<li>Debug information now includes line numbers when optimizations are enabled.
- This allows statistical sampling tools like OProfile and Shark to map
- samples back to source lines.</li>
-<li>LLVM now includes new experimental backends to support the MSP430, SystemZ
- and BlackFin architectures.</li>
-<li>LLVM supports a new <a href="GoldPlugin.html">Gold Linker Plugin</a> which
- enables support for <a href="LinkTimeOptimization.html">transparent
- link-time optimization</a> on ELF targets when used with the Gold binutils
- linker.</li>
-<li>LLVM now supports doing optimization and code generation on multiple
- threads. Please see the <a href="ProgrammersManual.html#threading">LLVM
- Programmer's Manual</a> for more information.</li>
-<li>LLVM now has experimental support for <a
- href="http://nondot.org/~sabre/LLVMNotes/EmbeddedMetadata.txt">embedded
- metadata</a> in LLVM IR, though the implementation is not guaranteed to be
- final and the .bc file format may change in future releases. Debug info
- does not yet use this format in LLVM 2.6.</li>
+<li>...</li>
</ul>
</div>
@@ -516,50 +430,7 @@ in this section.
expose new optimization opportunities:</p>
<ul>
-<li>The <a href="LangRef.html#i_add">add</a>, <a
- href="LangRef.html#i_sub">sub</a> and <a href="LangRef.html#i_mul">mul</a>
- instructions have been split into integer and floating point versions (like
- divide and remainder), introducing new <a
- href="LangRef.html#i_fadd">fadd</a>, <a href="LangRef.html#i_fsub">fsub</a>,
- and <a href="LangRef.html#i_fmul">fmul</a> instructions.</li>
-<li>The <a href="LangRef.html#i_add">add</a>, <a
- href="LangRef.html#i_sub">sub</a> and <a href="LangRef.html#i_mul">mul</a>
- instructions now support optional "nsw" and "nuw" bits which indicate that
- the operation is guaranteed to not overflow (in the signed or
- unsigned case, respectively). This gives the optimizer more information and
- can be used for things like C signed integer values, which are undefined on
- overflow.</li>
-<li>The <a href="LangRef.html#i_sdiv">sdiv</a> instruction now supports an
- optional "exact" flag which indicates that the result of the division is
- guaranteed to have a remainder of zero. This is useful for optimizing pointer
- subtraction in C.</li>
-<li>The <a href="LangRef.html#i_getelementptr">getelementptr</a> instruction now
- supports arbitrary integer index values for array/pointer indices. This
- allows for better code generation on 16-bit pointer targets like PIC16.</li>
-<li>The <a href="LangRef.html#i_getelementptr">getelementptr</a> instruction now
- supports an "inbounds" optimization hint that tells the optimizer that the
- pointer is guaranteed to be within its allocated object.</li>
-<li>LLVM now support a series of new linkage types for global values which allow
- for better optimization and new capabilities:
- <ul>
- <li><a href="LangRef.html#linkage_linkonce">linkonce_odr</a> and
- <a href="LangRef.html#linkage_weak">weak_odr</a> have the same linkage
- semantics as the non-"odr" linkage types. The difference is that these
- linkage types indicate that all definitions of the specified function
- are guaranteed to have the same semantics. This allows inlining
- templates functions in C++ but not inlining weak functions in C,
- which previously both got the same linkage type.</li>
- <li><a href="LangRef.html#linkage_available_externally">available_externally
- </a> is a new linkage type that gives the optimizer visibility into the
- definition of a function (allowing inlining and side effect analysis)
- but that does not cause code to be generated. This allows better
- optimization of "GNU inline" functions, extern templates, etc.</li>
- <li><a href="LangRef.html#linkage_linker_private">linker_private</a> is a
- new linkage type (which is only useful on Mac OS X) that is used for
- some metadata generation and other obscure things.</li>
- </ul></li>
-<li>Finally, target-specific intrinsics can now return multiple values, which
- is useful for modeling target operations with multiple results.</li>
+<li>...</li>
</ul>
</div>
@@ -576,23 +447,7 @@ release includes a few major enhancements and additions to the optimizers:</p>
<ul>
-<li>The <a href="Passes.html#scalarrepl">Scalar Replacement of Aggregates</a>
- pass has many improvements that allow it to better promote vector unions,
- variables which are memset, and much more strange code that can happen to
- do bitfield accesses to register operations. An interesting change is that
- it now produces "unusual" integer sizes (like i1704) in some cases and lets
- other optimizers clean things up.</li>
-<li>The <a href="Passes.html#loop-reduce">Loop Strength Reduction</a> pass now
- promotes small integer induction variables to 64-bit on 64-bit targets,
- which provides a major performance boost for much numerical code. It also
- promotes shorts to int on 32-bit hosts, etc. LSR now also analyzes pointer
- expressions (e.g. getelementptrs), as well as integers.</li>
-<li>The <a href="Passes.html#gvn">GVN</a> pass now eliminates partial
- redundancies of loads in simple cases.</li>
-<li>The <a href="Passes.html#inline">Inliner</a> now reuses stack space when
- inlining similar arrays from multiple callees into one caller.</li>
-<li>LLVM includes a new experimental Static Single Information (SSI)
- construction pass.</li>
+<li>...</li>
</ul>
@@ -607,17 +462,15 @@ release includes a few major enhancements and additions to the optimizers:</p>
<div class="doc_text">
<ul>
-<li>LLVM has a new "EngineBuilder" class which makes it more obvious how to
- set up and configure an ExecutionEngine (a JIT or interpreter).</li>
-<li>The JIT now supports generating more than 16M of code.</li>
-<li>When configured with <tt>--with-oprofile</tt>, the JIT can now inform
- OProfile about JIT'd code, allowing OProfile to get line number and function
- name information for JIT'd functions.</li>
-<li>When "libffi" is available, the LLVM interpreter now uses it, which supports
- calling almost arbitrary external (natively compiled) functions.</li>
-<li>Clients of the JIT can now register a 'JITEventListener' object to receive
- callbacks when the JIT emits or frees machine code. The OProfile support
- uses this mechanism.</li>
+<li>The JIT now <a
+href="http://llvm.org/viewvc/llvm-project?view=rev&revision=85295">defaults
+to compiling eagerly</a> to avoid a race condition in the lazy JIT.
+Clients that still want the lazy JIT can switch it on by calling
+<tt>ExecutionEngine::DisableLazyCompilation(false)</tt>.</li>
+<li>It is now possible to create more than one JIT instance in the same process.
+These JITs can generate machine code in parallel,
+although <a href="http://llvm.org/docs/ProgrammersManual.html#jitthreading">you
+still have to obey the other threading restrictions</a>.</li>
</ul>
</div>
@@ -635,54 +488,7 @@ it run faster:</p>
<ul>
-<li>The <tt>llc -asm-verbose</tt> option (exposed from llvm-gcc as <tt>-dA</tt>
- and clang as <tt>-fverbose-asm</tt> or <tt>-dA</tt>) now adds a lot of
- useful information in comments to
- the generated .s file. This information includes location information (if
- built with <tt>-g</tt>) and loop nest information.</li>
-<li>The code generator now supports a new MachineVerifier pass which is useful
- for finding bugs in targets and codegen passes.</li>
-<li>The Machine LICM is now enabled by default. It hoists instructions out of
- loops (such as constant pool loads, loads from read-only stubs, vector
- constant synthesization code, etc.) and is currently configured to only do
- so when the hoisted operation can be rematerialized.</li>
-<li>The Machine Sinking pass is now enabled by default. This pass moves
- side-effect free operations down the CFG so that they are executed on fewer
- paths through a function.</li>
-<li>The code generator now performs "stack slot coloring" of register spills,
- which allows spill slots to be reused. This leads to smaller stack frames
- in cases where there are lots of register spills.</li>
-<li>The register allocator has many improvements to take better advantage of
- commutable operations, various spiller peephole optimizations, and can now
- coalesce cross-register-class copies.</li>
-<li>Tblgen now supports multiclass inheritance and a number of new string and
- list operations like <tt>!(subst)</tt>, <tt>!(foreach)</tt>, <tt>!car</tt>,
- <tt>!cdr</tt>, <tt>!null</tt>, <tt>!if</tt>, <tt>!cast</tt>.
- These make the .td files more expressive and allow more aggressive factoring
- of duplication across instruction patterns.</li>
-<li>Target-specific intrinsics can now be added without having to hack VMCore to
- add them. This makes it easier to maintain out-of-tree targets.</li>
-<li>The instruction selector is better at propagating information about values
- (such as whether they are sign/zero extended etc.) across basic block
- boundaries.</li>
-<li>The SelectionDAG datastructure has new nodes for representing buildvector
- and <a href="http://llvm.org/PR2957">vector shuffle</a> operations. This
- makes operations and pattern matching more efficient and easier to get
- right.</li>
-<li>The Prolog/Epilog Insertion Pass now has experimental support for performing
- the "shrink wrapping" optimization, which moves spills and reloads around in
- the CFG to avoid doing saves on paths that don't need them.</li>
-<li>LLVM includes new experimental support for writing ELF .o files directly
- from the compiler. It works well for many simple C testcases, but doesn't
- support exception handling, debug info, inline assembly, etc.</li>
-<li>Targets can now specify register allocation hints through
- <tt>MachineRegisterInfo::setRegAllocationHint</tt>. A regalloc hint consists
- of hint type and physical register number. A hint type of zero specifies a
- register allocation preference. Other hint type values are target specific
- which are resolved by <tt>TargetRegisterInfo::ResolveRegAllocHint</tt>. An
- example is the ARM target which uses register hints to request that the
- register allocator provide an even / odd register pair to two virtual
- registers.</li>
+<li>...</li>
</ul>
</div>
@@ -697,31 +503,7 @@ it run faster:</p>
<ul>
-<li>SSE 4.2 builtins are now supported.</li>
-<li>GCC-compatible soft float modes are now supported, which are typically used
- by OS kernels.</li>
-<li>X86-64 now models implicit zero extensions better, which allows the code
- generator to remove a lot of redundant zexts. It also models the 8-bit "H"
- registers as subregs, which allows them to be used in some tricky
- situations.</li>
-<li>X86-64 now supports the "local exec" and "initial exec" thread local storage
- model.</li>
-<li>The vector forms of the <a href="LangRef.html#i_icmp">icmp</a> and <a
- href="LangRef.html#i_fcmp">fcmp</a> instructions now select to efficient
- SSE operations.</li>
-<li>Support for the win64 calling conventions have improved. The primary
- missing feature is support for varargs function definitions. It seems to
- work well for many win64 JIT purposes.</li>
-<li>The X86 backend has preliminary support for <a
- href="CodeGenerator.html#x86_memory">mapping address spaces to segment
- register references</a>. This allows you to write GS or FS relative memory
- accesses directly in LLVM IR for cases where you know exactly what you're
- doing (such as in an OS kernel). There are some known problems with this
- support, but it works in simple cases.</li>
-<li>The X86 code generator has been refactored to move all global variable
- reference logic to one place
- (<tt>X86Subtarget::ClassifyGlobalReference</tt>) which
- makes it easier to reason about.</li>
+<li>...</li>
</ul>
@@ -737,11 +519,7 @@ it run faster:</p>
</p>
<ul>
-<li>Support for floating-point, indirect function calls, and
- passing/returning aggregate types to functions.
-<li>The code generator is able to generate debug info into output COFF files.
-<li>Support for placing an object into a specific section or at a specific
- address in memory.</li>
+<li>...</li>
</ul>
<p>Things not yet supported:</p>
@@ -764,22 +542,9 @@ it run faster:</p>
<ul>
-<li>Preliminary support for processors, such as the Cortex-A8 and Cortex-A9,
-that implement version v7-A of the ARM architecture. The ARM backend now
-supports both the Thumb2 and Advanced SIMD (Neon) instruction sets.</li>
-
-<li>The AAPCS-VFP "hard float" calling conventions are also supported with the
-<tt>-float-abi=hard</tt> flag.</li>
-
-<li>The ARM calling convention code is now tblgen generated instead of resorting
- to C++ code.</li>
+<li>...</li>
</ul>
-<p>These features are still somewhat experimental
-and subject to change. The Neon intrinsics, in particular, may change in future
-releases of LLVM. ARMv7 support has progressed a lot on top of tree since 2.6
-branched.</p>
-
</div>
@@ -793,11 +558,7 @@ branched.</p>
</p>
<ul>
-<li>Mips now supports O32 Calling Convention.</li>
-<li>Many improvements to the 32-bit PowerPC SVR4 ABI (used on powerpc-linux)
- support, lots of bugs fixed.</li>
-<li>Added support for the 64-bit PowerPC SVR4 ABI (used on powerpc64-linux).
- Needs more testing.</li>
+<li>...</li>
</ul>
</div>
@@ -814,40 +575,7 @@ branched.</p>
</p>
<ul>
-<li>New <a href="http://llvm.org/doxygen/PrettyStackTrace_8h-source.html">
- <tt>PrettyStackTrace</tt> class</a> allows crashes of llvm tools (and applications
- that integrate them) to provide more detailed indication of what the
- compiler was doing at the time of the crash (e.g. running a pass).
- At the top level for each LLVM tool, it includes the command line arguments.
- </li>
-<li>New <a href="http://llvm.org/doxygen/StringRef_8h-source.html">StringRef</a>
- and <a href="http://llvm.org/doxygen/Twine_8h-source.html">Twine</a> classes
- make operations on character ranges and
- string concatenation to be more efficient. <tt>StringRef</tt> is just a <tt>const
- char*</tt> with a length, <tt>Twine</tt> is a light-weight rope.</li>
-<li>LLVM has new <tt>WeakVH</tt>, <tt>AssertingVH</tt> and <tt>CallbackVH</tt>
- classes, which make it easier to write LLVM IR transformations. <tt>WeakVH</tt>
- is automatically drops to null when the referenced <tt>Value</tt> is deleted,
- and is updated across a <tt>replaceAllUsesWith</tt> operation.
- <tt>AssertingVH</tt> aborts the program if the
- referenced value is destroyed while it is being referenced. <tt>CallbackVH</tt>
- is a customizable class for handling value references. See <a
- href="http://llvm.org/doxygen/ValueHandle_8h-source.html">ValueHandle.h</a>
- for more information.</li>
-<li>The new '<a href="http://llvm.org/doxygen/Triple_8h-source.html">Triple
- </a>' class centralizes a lot of logic that reasons about target
- triples.</li>
-<li>The new '<a href="http://llvm.org/doxygen/ErrorHandling_8h-source.html">
- llvm_report_error()</a>' set of APIs allows tools to embed the LLVM
- optimizer and backend and recover from previously unrecoverable errors.</li>
-<li>LLVM has new abstractions for <a
- href="http://llvm.org/doxygen/Atomic_8h-source.html">atomic operations</a>
- and <a href="http://llvm.org/doxygen/RWMutex_8h-source.html">reader/writer
- locks</a>.</li>
-<li>LLVM has new <a href="http://llvm.org/doxygen/SourceMgr_8h-source.html">
- <tt>SourceMgr</tt> and <tt>SMLoc</tt> classes</a> which implement caret
- diagnostics and basic include stack processing for simple parsers. It is
- used by tablegen, llvm-mc, the .ll parser and FileCheck.</li>
+<li>...</li>
</ul>
@@ -862,32 +590,7 @@ branched.</p>
<p>Other miscellaneous features include:</p>
<ul>
-<li>LLVM now includes a new internal '<a
- href="http://llvm.org/cmds/FileCheck.html">FileCheck</a>' tool which allows
- writing much more accurate regression tests that run faster. Please see the
- <a href="TestingGuide.html#FileCheck">FileCheck section of the Testing
- Guide</a> for more information.</li>
-<li>LLVM profile information support has been significantly improved to produce
-correct use counts, and has support for edge profiling with reduced runtime
-overhead. Combined, the generated profile information is both more correct and
-imposes about half as much overhead (2.6. from 12% to 6% overhead on SPEC
-CPU2000).</li>
-<li>The C bindings (in the llvm/include/llvm-c directory) include many newly
- supported APIs.</li>
-<li>LLVM 2.6 includes a brand new experimental LLVM bindings to the Ada2005
- programming language.</li>
-
-<li>The LLVMC driver has several new features:
- <ul>
- <li>Dynamic plugins now work on Windows.</li>
- <li>New option property: init. Makes possible to provide default values for
- options defined in plugins (interface to <tt>cl::init</tt>).</li>
- <li>New example: Skeleton, shows how to create a standalone LLVMC-based
- driver.</li>
- <li>New example: mcc16, a driver for the PIC16 toolchain.</li>
- </ul>
-</li>
-
+<li>...</li>
</ul>
</div>
@@ -901,24 +604,15 @@ CPU2000).</li>
<div class="doc_text">
<p>If you're already an LLVM user or developer with out-of-tree changes based
-on LLVM 2.5, this section lists some "gotchas" that you may run into upgrading
+on LLVM 2.6, this section lists some "gotchas" that you may run into upgrading
from the previous release.</p>
<ul>
-<li>The Itanium (IA64) backend has been removed. It was not actively supported
- and had bitrotted.</li>
-<li>The BigBlock register allocator has been removed, it had also bitrotted.</li>
-<li>The C Backend (<tt>-march=c</tt>) is no longer considered part of the LLVM release
-criteria. We still want it to work, but no one is maintaining it and it lacks
-support for arbitrary precision integers and other important IR features.</li>
-
-<li>All LLVM tools now default to overwriting their output file, behaving more
- like standard unix tools. Previously, this only happened with the '<tt>-f</tt>'
- option.</li>
-<li>LLVM build now builds all libraries as .a files instead of some
- libraries as relinked .o files. This requires some APIs like
- InitializeAllTargets.h.
- </li>
+<li>The LLVM interpreter now defaults to <em>not</em> using <tt>libffi</tt> even
+if you have it installed. This makes it more likely that an LLVM built on one
+system will work when copied to a similar system. To use <tt>libffi</tt>,
+configure with <tt>--enable-libffi</tt>.
+</li>
</ul>
@@ -926,82 +620,30 @@ support for arbitrary precision integers and other important IR features.</li>
API changes are:</p>
<ul>
-<li>All uses of <tt>hash_set</tt> and <tt>hash_map</tt> have been removed from
- the LLVM tree and the wrapper headers have been removed.</li>
-<li>The llvm/Streams.h and <tt>DOUT</tt> member of Debug.h have been removed. The
- <tt>llvm::Ostream</tt> class has been completely removed and replaced with
- uses of <tt>raw_ostream</tt>.</li>
-<li>LLVM's global uniquing tables for <tt>Type</tt>s and <tt>Constant</tt>s have
- been privatized into members of an <tt>LLVMContext</tt>. A number of APIs
- now take an <tt>LLVMContext</tt> as a parameter. To smooth the transition
- for clients that will only ever use a single context, the new
- <tt>getGlobalContext()</tt> API can be used to access a default global
- context which can be passed in any and all cases where a context is
- required.
-<li>The <tt>getABITypeSize</tt> methods are now called <tt>getAllocSize</tt>.</li>
-<li>The <tt>Add</tt>, <tt>Sub</tt> and <tt>Mul</tt> operators are no longer
- overloaded for floating-point types. Floating-point addition, subtraction
- and multiplication are now represented with new operators <tt>FAdd</tt>,
- <tt>FSub</tt> and <tt>FMul</tt>. In the <tt>IRBuilder</tt> API,
- <tt>CreateAdd</tt>, <tt>CreateSub</tt>, <tt>CreateMul</tt> and
- <tt>CreateNeg</tt> should only be used for integer arithmetic now;
- <tt>CreateFAdd</tt>, <tt>CreateFSub</tt>, <tt>CreateFMul</tt> and
- <tt>CreateFNeg</tt> should now be used for floating-point arithmetic.</li>
-<li>The <tt>DynamicLibrary</tt> class can no longer be constructed, its functionality has
- moved to static member functions.</li>
-<li><tt>raw_fd_ostream</tt>'s constructor for opening a given filename now
- takes an extra <tt>Force</tt> argument. If <tt>Force</tt> is set to
- <tt>false</tt>, an error will be reported if a file with the given name
- already exists. If <tt>Force</tt> is set to <tt>true</tt>, the file will
- be silently truncated (which is the behavior before this flag was
- added).</li>
-<li><tt>SCEVHandle</tt> no longer exists, because reference counting is no
- longer done for <tt>SCEV*</tt> objects, instead <tt>const SCEV*</tt>
- should be used.</li>
-
-<li>Many APIs, notably <tt>llvm::Value</tt>, now use the <tt>StringRef</tt>
-and <tt>Twine</tt> classes instead of passing <tt>const char*</tt>
-or <tt>std::string</tt>, as described in
-the <a href="ProgrammersManual.html#string_apis">Programmer's Manual</a>. Most
-clients should be unaffected by this transition, unless they are used to
-<tt>Value::getName()</tt> returning a string. Here are some tips on updating to
-2.6:
- <ul>
- <li><tt>getNameStr()</tt> is still available, and matches the old
- behavior. Replacing <tt>getName()</tt> calls with this is an safe option,
- although more efficient alternatives are now possible.</li>
-
- <li>If you were just relying on <tt>getName()</tt> being able to be sent to
- a <tt>std::ostream</tt>, consider migrating
- to <tt>llvm::raw_ostream</tt>.</li>
-
- <li>If you were using <tt>getName().c_str()</tt> to get a <tt>const
- char*</tt> pointer to the name, you can use <tt>getName().data()</tt>.
- Note that this string (as before), may not be the entire name if the
- name contains embedded null characters.</li>
-
- <li>If you were using <tt>operator +</tt> on the result of <tt>getName()</tt> and
- treating the result as an <tt>std::string</tt>, you can either
- use <tt>Twine::str</tt> to get the result as an <tt>std::string</tt>, or
- could move to a <tt>Twine</tt> based design.</li>
-
- <li><tt>isName()</tt> should be replaced with comparison
- against <tt>getName()</tt> (this is now efficient).
- </ul>
-</li>
+<li><tt>ModuleProvider</tt> has been <a
+href="http://llvm.org/viewvc/llvm-project?view=rev&revision=94686">removed</a>
+and its methods moved to <tt>Module</tt> and <tt>GlobalValue</tt>.
+Most clients can remove uses of <tt>ExistingModuleProvider</tt>,
+replace <tt>getBitcodeModuleProvider</tt> with
+<tt>getLazyBitcodeModule</tt>, and pass their <tt>Module</tt> to
+functions that used to accept <tt>ModuleProvider</tt>. Clients who
+wrote their own <tt>ModuleProvider</tt>s will need to derive from
+<tt>GVMaterializer</tt> instead and use
+<tt>Module::setMaterializer</tt> to attach it to a
+<tt>Module</tt>.</li>
+
+<li><tt>GhostLinkage</tt> has given up the ghost.
+<tt>GlobalValue</tt>s that have not yet been read from their backing
+storage have the same linkage they will have after being read in.
+Clients must replace calls to
+<tt>GlobalValue::hasNotBeenReadFromBitcode</tt> with
+<tt>GlobalValue::isMaterializable</tt>.</li>
+
+<li>FIXME: Debug info has been totally redone. Add pointers to new APIs. Substantial caveats about compatibility of .ll and .bc files.</li>
+
+<li>The <tt>llvm/Support/DataTypes.h</tt> header has moved
+to <tt>llvm/System/DataTypes.h</tt>.</li>
-<li>The registration interfaces for backend Targets has changed (what was
-previously <tt>TargetMachineRegistry</tt>). For backend authors, see the <a
-href="WritingAnLLVMBackend.html#TargetRegistration">Writing An LLVM Backend</a>
-guide. For clients, the notable API changes are:
- <ul>
- <li><tt>TargetMachineRegistry</tt> has been renamed
- to <tt>TargetRegistry</tt>.</li>
-
- <li>Clients should move to using the <tt>TargetRegistry::lookupTarget()</tt>
- function to find targets.</li>
- </ul>
-</li>
</ul>
</div>
@@ -1055,8 +697,8 @@ there isn't already one.</p>
<li>The llvm-gcc bootstrap will fail with some versions of binutils (e.g. 2.15)
with a message of "<tt><a href="http://llvm.org/PR5004">Error: can not do 8
byte pc-relative relocation</a></tt>" when building C++ code. We intend to
- fix this on mainline, but a workaround for 2.6 is to upgrade to binutils
- 2.17 or later.</li>
+ fix this on mainline, but a workaround is to upgrade to binutils 2.17 or
+ later.</li>
<li>LLVM will not correctly compile on Solaris and/or OpenSolaris
using the stock GCC 3.x.x series 'out the box',
@@ -1350,7 +992,7 @@ lists</a>.</p>
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-01-16 22:25:13 +0100 (Sat, 16 Jan 2010) $
+ Last modified: $Date: 2010-02-14 02:47:19 +0100 (Sun, 14 Feb 2010) $
</address>
</body>
diff --git a/docs/WritingAnLLVMBackend.html b/docs/WritingAnLLVMBackend.html
index 5a95185..75353cf 100644
--- a/docs/WritingAnLLVMBackend.html
+++ b/docs/WritingAnLLVMBackend.html
@@ -354,8 +354,6 @@ public:
// Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &amp;PM, bool Fast);
virtual bool addPreEmitPass(PassManagerBase &amp;PM, bool Fast);
- virtual bool addAssemblyEmitter(PassManagerBase &amp;PM, bool Fast,
- std::ostream &amp;Out);
};
} // end namespace llvm
@@ -2152,12 +2150,6 @@ in <tt>XXXGenAsmWriter.inc</tt> contains an implementation of the
<li><tt>printImplicitDef</tt></li>
<li><tt>printInlineAsm</tt></li>
-
-<li><tt>printLabel</tt></li>
-
-<li><tt>printPICJumpTableEntry</tt></li>
-
-<li><tt>printPICJumpTableSetLabel</tt></li>
</ul>
<p>
@@ -2563,7 +2555,7 @@ with assembler.
<a href="http://www.woo.com">Mason Woo</a> and <a href="http://misha.brukman.net">Misha Brukman</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a>
<br>
- Last modified: $Date: 2009-09-13 00:57:37 +0200 (Sun, 13 Sep 2009) $
+ Last modified: $Date: 2010-02-02 19:44:12 +0100 (Tue, 02 Feb 2010) $
</address>
</body>
diff --git a/docs/index.html b/docs/index.html
index 36ed0e2..1ada7de 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -2,12 +2,16 @@
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
- <title>Documentation for the LLVM System</title>
+ <title>Documentation for the LLVM System at SVN head</title>
<link rel="stylesheet" href="llvm.css" type="text/css">
</head>
<body>
-<div class="doc_title">Documentation for the LLVM System</div>
+<div class="doc_title">Documentation for the LLVM System at SVN head</div>
+
+<p class="doc_warning">If you are using a released version of LLVM,
+see <a href="http://llvm.org/releases/">the download page</a> to find
+your documentation.</p>
<div class="doc_text">
<table class="layout" width="95%"><tr class="layout"><td class="left">
@@ -281,7 +285,7 @@ times each day, making it a high volume list.</li>
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-09-21 04:34:59 +0200 (Mon, 21 Sep 2009) $
+ Last modified: $Date: 2010-02-03 19:49:55 +0100 (Wed, 03 Feb 2010) $
</address>
</body></html>
diff --git a/docs/tutorial/LangImpl1.html b/docs/tutorial/LangImpl1.html
index 5e1786c..9f4737d 100644
--- a/docs/tutorial/LangImpl1.html
+++ b/docs/tutorial/LangImpl1.html
@@ -342,7 +342,7 @@ so that you can use the lexer and parser together.
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl2.html b/docs/tutorial/LangImpl2.html
index 5bcd0dd..f06db16 100644
--- a/docs/tutorial/LangImpl2.html
+++ b/docs/tutorial/LangImpl2.html
@@ -1227,7 +1227,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl3.html b/docs/tutorial/LangImpl3.html
index e3d2117..a628145 100644
--- a/docs/tutorial/LangImpl3.html
+++ b/docs/tutorial/LangImpl3.html
@@ -1263,7 +1263,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-07-21 11:05:13 -0700 (Tue, 21 Jul 2009) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl4.html b/docs/tutorial/LangImpl4.html
index 728d518..85e48c5 100644
--- a/docs/tutorial/LangImpl4.html
+++ b/docs/tutorial/LangImpl4.html
@@ -171,10 +171,7 @@ add a set of optimizations to run. The code looks like this:</p>
<div class="doc_code">
<pre>
- ExistingModuleProvider *OurModuleProvider =
- new ExistingModuleProvider(TheModule);
-
- FunctionPassManager OurFPM(OurModuleProvider);
+ FunctionPassManager OurFPM(TheModule);
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
@@ -198,19 +195,13 @@ add a set of optimizations to run. The code looks like this:</p>
</pre>
</div>
-<p>This code defines two objects, an <tt>ExistingModuleProvider</tt> and a
-<tt>FunctionPassManager</tt>. The former is basically a wrapper around our
-<tt>Module</tt> that the PassManager requires. It provides certain flexibility
-that we're not going to take advantage of here, so I won't dive into any details
-about it.</p>
-
-<p>The meat of the matter here, is the definition of "<tt>OurFPM</tt>". It
-requires a pointer to the <tt>Module</tt> (through the <tt>ModuleProvider</tt>)
-to construct itself. Once it is set up, we use a series of "add" calls to add
-a bunch of LLVM passes. The first pass is basically boilerplate, it adds a pass
-so that later optimizations know how the data structures in the program are
-laid out. The "<tt>TheExecutionEngine</tt>" variable is related to the JIT,
-which we will get to in the next section.</p>
+<p>This code defines a <tt>FunctionPassManager</tt>, "<tt>OurFPM</tt>". It
+requires a pointer to the <tt>Module</tt> to construct itself. Once it is set
+up, we use a series of "add" calls to add a bunch of LLVM passes. The first
+pass is basically boilerplate, it adds a pass so that later optimizations know
+how the data structures in the program are laid out. The
+"<tt>TheExecutionEngine</tt>" variable is related to the JIT, which we will get
+to in the next section.</p>
<p>In this case, we choose to add 4 optimization passes. The passes we chose
here are a pretty standard set of "cleanup" optimizations that are useful for
@@ -302,8 +293,8 @@ by adding a global variable and a call in <tt>main</tt>:</p>
...
int main() {
..
- <b>// Create the JIT. This takes ownership of the module and module provider.
- TheExecutionEngine = EngineBuilder(OurModuleProvider).create();</b>
+ <b>// Create the JIT. This takes ownership of the module.
+ TheExecutionEngine = EngineBuilder(TheModule).create();</b>
..
}
</pre>
@@ -494,7 +485,7 @@ LLVM JIT and optimizer. To build this example, use:
<div class="doc_code">
<pre>
# Compile
- g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit interpreter native` -O3 -o toy
+ g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
</pre>
@@ -511,11 +502,9 @@ at runtime.</p>
<pre>
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
@@ -1084,13 +1073,15 @@ int main() {
// Make the module, which holds all the code.
TheModule = new Module("my cool jit", Context);
- ExistingModuleProvider *OurModuleProvider =
- new ExistingModuleProvider(TheModule);
-
- // Create the JIT. This takes ownership of the module and module provider.
- TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
+ // Create the JIT. This takes ownership of the module.
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
- FunctionPassManager OurFPM(OurModuleProvider);
+ FunctionPassManager OurFPM(TheModule);
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
@@ -1135,7 +1126,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl5.html b/docs/tutorial/LangImpl5.html
index f93b59b..f80f3f3 100644
--- a/docs/tutorial/LangImpl5.html
+++ b/docs/tutorial/LangImpl5.html
@@ -902,11 +902,9 @@ if/then/else and for expressions.. To build this example, use:
<pre>
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
@@ -1720,13 +1718,15 @@ int main() {
// Make the module, which holds all the code.
TheModule = new Module("my cool jit", Context);
- ExistingModuleProvider *OurModuleProvider =
- new ExistingModuleProvider(TheModule);
-
- // Create the JIT. This takes ownership of the module and module provider.
- TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
+ // Create the JIT. This takes ownership of the module.
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
- FunctionPassManager OurFPM(OurModuleProvider);
+ FunctionPassManager OurFPM(TheModule);
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
@@ -1771,7 +1771,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl6.html b/docs/tutorial/LangImpl6.html
index f113e96..f70bc50 100644
--- a/docs/tutorial/LangImpl6.html
+++ b/docs/tutorial/LangImpl6.html
@@ -821,11 +821,9 @@ if/then/else and for expressions.. To build this example, use:
<pre>
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
@@ -1757,13 +1755,15 @@ int main() {
// Make the module, which holds all the code.
TheModule = new Module("my cool jit", Context);
- ExistingModuleProvider *OurModuleProvider =
- new ExistingModuleProvider(TheModule);
-
- // Create the JIT. This takes ownership of the module and module provider.
- TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
+ // Create the JIT. This takes ownership of the module.
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
- FunctionPassManager OurFPM(OurModuleProvider);
+ FunctionPassManager OurFPM(TheModule);
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
@@ -1808,7 +1808,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl7.html b/docs/tutorial/LangImpl7.html
index ec07fa8..1a779ba 100644
--- a/docs/tutorial/LangImpl7.html
+++ b/docs/tutorial/LangImpl7.html
@@ -1004,11 +1004,9 @@ variables and var/in support. To build this example, use:
<pre>
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
@@ -2105,13 +2103,15 @@ int main() {
// Make the module, which holds all the code.
TheModule = new Module("my cool jit", Context);
- ExistingModuleProvider *OurModuleProvider =
- new ExistingModuleProvider(TheModule);
-
- // Create the JIT. This takes ownership of the module and module provider.
- TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
+ // Create the JIT. This takes ownership of the module.
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&amp;ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
- FunctionPassManager OurFPM(OurModuleProvider);
+ FunctionPassManager OurFPM(TheModule);
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
@@ -2158,7 +2158,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/LangImpl8.html b/docs/tutorial/LangImpl8.html
index 855b8f3..5effd70 100644
--- a/docs/tutorial/LangImpl8.html
+++ b/docs/tutorial/LangImpl8.html
@@ -359,7 +359,7 @@ Passing Style</a> and the use of tail calls (which LLVM also supports).</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl1.html b/docs/tutorial/OCamlLangImpl1.html
index 3c0fd8b..f3345aa 100644
--- a/docs/tutorial/OCamlLangImpl1.html
+++ b/docs/tutorial/OCamlLangImpl1.html
@@ -359,7 +359,7 @@ include a driver so that you can use the lexer and parser together.
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl2.html b/docs/tutorial/OCamlLangImpl2.html
index 7d60aa6..a59e829 100644
--- a/docs/tutorial/OCamlLangImpl2.html
+++ b/docs/tutorial/OCamlLangImpl2.html
@@ -1039,7 +1039,7 @@ main ()
<a href="mailto:sabre@nondot.org">Chris Lattner</a>
<a href="mailto:erickt@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl3.html b/docs/tutorial/OCamlLangImpl3.html
index a598875..b335147 100644
--- a/docs/tutorial/OCamlLangImpl3.html
+++ b/docs/tutorial/OCamlLangImpl3.html
@@ -1085,7 +1085,7 @@ main ()
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl4.html b/docs/tutorial/OCamlLangImpl4.html
index 543e12f..451ab11 100644
--- a/docs/tutorial/OCamlLangImpl4.html
+++ b/docs/tutorial/OCamlLangImpl4.html
@@ -1032,7 +1032,7 @@ extern double putchard(double X) {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl5.html b/docs/tutorial/OCamlLangImpl5.html
index f19e900..ae075ec 100644
--- a/docs/tutorial/OCamlLangImpl5.html
+++ b/docs/tutorial/OCamlLangImpl5.html
@@ -1563,7 +1563,7 @@ operators</a>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl6.html b/docs/tutorial/OCamlLangImpl6.html
index 2edb22e..e0503c0 100644
--- a/docs/tutorial/OCamlLangImpl6.html
+++ b/docs/tutorial/OCamlLangImpl6.html
@@ -1568,7 +1568,7 @@ SSA construction</a>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/docs/tutorial/OCamlLangImpl7.html b/docs/tutorial/OCamlLangImpl7.html
index 0776821..ed1a558 100644
--- a/docs/tutorial/OCamlLangImpl7.html
+++ b/docs/tutorial/OCamlLangImpl7.html
@@ -1901,7 +1901,7 @@ extern double printd(double X) {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
</address>
</body>
</html>
diff --git a/examples/BrainF/BrainFDriver.cpp b/examples/BrainF/BrainFDriver.cpp
index 6f4ba69..c11a580 100644
--- a/examples/BrainF/BrainFDriver.cpp
+++ b/examples/BrainF/BrainFDriver.cpp
@@ -27,7 +27,6 @@
#include "BrainF.h"
#include "llvm/Constants.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index c5b8079..f60c0ed 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -4,6 +4,10 @@ add_subdirectory(HowToUseJIT)
add_subdirectory(Kaleidoscope)
add_subdirectory(ModuleMaker)
+if( NOT WIN32 )
+ add_subdirectory(ExceptionDemo)
+endif()
+
include(CheckIncludeFile)
check_include_file(pthread.h HAVE_PTHREAD_H)
diff --git a/examples/ExceptionDemo/CMakeLists.txt b/examples/ExceptionDemo/CMakeLists.txt
new file mode 100644
index 0000000..d6619155
--- /dev/null
+++ b/examples/ExceptionDemo/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(LLVM_LINK_COMPONENTS jit nativecodegen)
+
+add_llvm_example(ExceptionDemo
+ ExceptionDemo.cpp
+ )
diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp
new file mode 100644
index 0000000..46dc481
--- /dev/null
+++ b/examples/ExceptionDemo/ExceptionDemo.cpp
@@ -0,0 +1,2028 @@
+//===-- examples/ExceptionDemo/ExceptionDemo.cpp -
+// An example use of the llvm Exception mechanism --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--------------------------------------------------------------------===//
+//
+// Demo program which implements an example LLVM exception implementation, and
+// shows several test cases including the handling of foreign exceptions.
+// It is run with type info types arguments to throw. A test will
+// be run for each given type info type. While type info types with the value
+// of -1 will trigger a foreign C++ exception to be thrown; type info types
+// <= 6 and >= 1 will cause the associated generated exceptions to be thrown
+// and caught by generated test functions; and type info types > 6
+// will result in exceptions which pass through to the test harness. All other
+// type info types are not supported and could cause a crash. In all cases,
+// the "finally" blocks of every generated test functions will executed
+// regardless of whether or not that test function ignores or catches the
+// thrown exception.
+//
+// examples:
+//
+// ExceptionDemo
+//
+// causes a usage to be printed to stderr
+//
+// ExceptionDemo 2 3 7 -1
+//
+// results in the following cases:
+// - Value 2 causes an exception with a type info type of 2 to be
+// thrown and caught by an inner generated test function.
+// - Value 3 causes an exception with a type info type of 3 to be
+// thrown and caught by an outer generated test function.
+// - Value 7 causes an exception with a type info type of 7 to be
+// thrown and NOT be caught by any generated function.
+// - Value -1 causes a foreign C++ exception to be thrown and not be
+// caught by any generated function
+//
+// Cases -1 and 7 are caught by a C++ test harness where the validity of
+// of a C++ catch(...) clause catching a generated exception with a
+// type info type of 7 is questionable.
+//
+// This code uses code from the llvm compiler-rt project and the llvm
+// Kaleidoscope project.
+//
+//===--------------------------------------------------------------------===//
+
+
+#include "llvm/LLVMContext.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetSelect.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Support/Dwarf.h"
+
+#include <cstdio>
+#include <string>
+#include <sstream>
+#include <map>
+#include <vector>
+#include <stdexcept>
+
+
+#ifndef USE_GLOBAL_STR_CONSTS
+#define USE_GLOBAL_STR_CONSTS true
+#endif
+
+// System C++ ABI unwind types from:
+// http://refspecs.freestandards.org/abi-eh-1.21.html
+
+extern "C" {
+
+typedef enum {
+ _URC_NO_REASON = 0,
+ _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+ _URC_FATAL_PHASE2_ERROR = 2,
+ _URC_FATAL_PHASE1_ERROR = 3,
+ _URC_NORMAL_STOP = 4,
+ _URC_END_OF_STACK = 5,
+ _URC_HANDLER_FOUND = 6,
+ _URC_INSTALL_CONTEXT = 7,
+ _URC_CONTINUE_UNWIND = 8
+} _Unwind_Reason_Code;
+
+typedef enum {
+ _UA_SEARCH_PHASE = 1,
+ _UA_CLEANUP_PHASE = 2,
+ _UA_HANDLER_FRAME = 4,
+ _UA_FORCE_UNWIND = 8,
+ _UA_END_OF_STACK = 16
+} _Unwind_Action;
+
+struct _Unwind_Exception;
+
+typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
+ struct _Unwind_Exception *);
+
+struct _Unwind_Exception {
+ uint64_t exception_class;
+ _Unwind_Exception_Cleanup_Fn exception_cleanup;
+
+ uintptr_t private_1;
+ uintptr_t private_2;
+
+ // @@@ The IA-64 ABI says that this structure must be double-word aligned.
+ // Taking that literally does not make much sense generically. Instead
+ // we provide the maximum alignment required by any type for the machine.
+} __attribute__((__aligned__));
+
+struct _Unwind_Context;
+typedef struct _Unwind_Context* _Unwind_Context_t;
+
+extern const uint8_t* _Unwind_GetLanguageSpecificData (_Unwind_Context_t c);
+extern uintptr_t _Unwind_GetGR (_Unwind_Context_t c, int i);
+extern void _Unwind_SetGR (_Unwind_Context_t c, int i, uintptr_t n);
+extern void _Unwind_SetIP (_Unwind_Context_t, uintptr_t new_value);
+extern uintptr_t _Unwind_GetIP (_Unwind_Context_t context);
+extern uintptr_t _Unwind_GetRegionStart (_Unwind_Context_t context);
+
+} // extern "C"
+
+//
+// Example types
+//
+
+/// This is our simplistic type info
+struct OurExceptionType_t {
+ /// type info type
+ int type;
+};
+
+
+/// This is our Exception class which relies on a negative offset to calculate
+/// pointers to its instances from pointers to its unwindException member.
+///
+/// Note: The above unwind.h defines struct _Unwind_Exception to be aligned
+/// on a double word boundary. This is necessary to match the standard:
+/// http://refspecs.freestandards.org/abi-eh-1.21.html
+struct OurBaseException_t {
+ struct OurExceptionType_t type;
+
+ // Note: This is properly aligned in unwind.h
+ struct _Unwind_Exception unwindException;
+};
+
+
+// Note: Not needed since we are C++
+typedef struct OurBaseException_t OurException;
+typedef struct _Unwind_Exception OurUnwindException;
+
+//
+// Various globals used to support typeinfo and generatted exceptions in
+// general
+//
+
+static std::map<std::string, llvm::Value*> namedValues;
+
+int64_t ourBaseFromUnwindOffset;
+
+const unsigned char ourBaseExcpClassChars[] =
+ {'o', 'b', 'j', '\0', 'b', 'a', 's', '\0'};
+
+
+static uint64_t ourBaseExceptionClass = 0;
+
+static std::vector<std::string> ourTypeInfoNames;
+static std::map<int, std::string> ourTypeInfoNamesIndex;
+
+static llvm::StructType* ourTypeInfoType;
+static llvm::StructType* ourExceptionType;
+static llvm::StructType* ourUnwindExceptionType;
+
+static llvm::ConstantInt* ourExceptionNotThrownState;
+static llvm::ConstantInt* ourExceptionThrownState;
+static llvm::ConstantInt* ourExceptionCaughtState;
+
+typedef std::vector<std::string> ArgNames;
+typedef std::vector<const llvm::Type*> ArgTypes;
+
+//
+// Code Generation Utilities
+//
+
+/// Utility used to create a function, both declarations and definitions
+/// @param module for module instance
+/// @param retType function return type
+/// @param theArgTypes function's ordered argument types
+/// @param theArgNames function's ordered arguments needed if use of this
+/// function corresponds to a function definition. Use empty
+/// aggregate for function declarations.
+/// @param functName function name
+/// @param linkage function linkage
+/// @param declarationOnly for function declarations
+/// @param isVarArg function uses vararg arguments
+/// @returns function instance
+llvm::Function *createFunction(llvm::Module& module,
+ const llvm::Type* retType,
+ const ArgTypes& theArgTypes,
+ const ArgNames& theArgNames,
+ const std::string& functName,
+ llvm::GlobalValue::LinkageTypes linkage,
+ bool declarationOnly,
+ bool isVarArg) {
+ llvm::FunctionType* functType = llvm::FunctionType::get(retType,
+ theArgTypes,
+ isVarArg);
+ llvm::Function* ret = llvm::Function::Create(functType,
+ linkage,
+ functName,
+ &module);
+ if (!ret || declarationOnly)
+ return(ret);
+
+ namedValues.clear();
+ unsigned i = 0;
+ for (llvm::Function::arg_iterator argIndex = ret->arg_begin();
+ i != theArgNames.size();
+ ++argIndex, ++i) {
+
+ argIndex->setName(theArgNames[i]);
+ namedValues[theArgNames[i]] = argIndex;
+ }
+
+ return(ret);
+}
+
+
+/// Create an alloca instruction in the entry block of
+/// the parent function. This is used for mutable variables etc.
+/// @param function parent instance
+/// @param varName stack variable name
+/// @param type stack variable type
+/// @param initWith optional constant initialization value
+/// @returns AllocaInst instance
+static llvm::AllocaInst *createEntryBlockAlloca(llvm::Function& function,
+ const std::string &varName,
+ const llvm::Type* type,
+ llvm::Constant* initWith = NULL) {
+ llvm::BasicBlock& block = function.getEntryBlock();
+ llvm::IRBuilder<> tmp(&block, block.begin());
+ llvm::AllocaInst* ret = tmp.CreateAlloca(type, 0, varName.c_str());
+
+ if (initWith)
+ tmp.CreateStore(initWith, ret);
+
+ return(ret);
+}
+
+
+//
+// Code Generation Utilities End
+//
+
+//
+// Runtime C Library functions
+//
+
+// Note: using an extern "C" block so that static functions can be used
+extern "C" {
+
+// Note: Better ways to decide on bit width
+//
+/// Prints a 32 bit number, according to the format, to stderr.
+/// @param intToPrint integer to print
+/// @param format printf like format to use when printing
+void print32Int(int intToPrint, const char* format) {
+ if (format) {
+ // Note: No NULL check
+ fprintf(stderr, format, intToPrint);
+ }
+ else {
+ // Note: No NULL check
+ fprintf(stderr, "::print32Int(...):NULL arg.\n");
+ }
+}
+
+
+// Note: Better ways to decide on bit width
+//
+/// Prints a 64 bit number, according to the format, to stderr.
+/// @param intToPrint integer to print
+/// @param format printf like format to use when printing
+void print64Int(long int intToPrint, const char* format) {
+ if (format) {
+ // Note: No NULL check
+ fprintf(stderr, format, intToPrint);
+ }
+ else {
+ // Note: No NULL check
+ fprintf(stderr, "::print64Int(...):NULL arg.\n");
+ }
+}
+
+
+/// Prints a C string to stderr
+/// @param toPrint string to print
+void printStr(char* toPrint) {
+ if (toPrint) {
+ fprintf(stderr, "%s", toPrint);
+ }
+ else {
+ fprintf(stderr, "::printStr(...):NULL arg.\n");
+ }
+}
+
+
+/// Deletes the true previosly allocated exception whose address
+/// is calculated from the supplied OurBaseException_t::unwindException
+/// member address. Handles (ignores), NULL pointers.
+/// @param expToDelete exception to delete
+void deleteOurException(OurUnwindException* expToDelete) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "deleteOurException(...).\n");
+#endif
+
+ if (expToDelete &&
+ (expToDelete->exception_class == ourBaseExceptionClass)) {
+
+ free(((char*) expToDelete) + ourBaseFromUnwindOffset);
+ }
+}
+
+
+/// This function is the struct _Unwind_Exception API mandated delete function
+/// used by foreign exception handlers when deleting our exception
+/// (OurException), instances.
+/// @param reason @link http://refspecs.freestandards.org/abi-eh-1.21.html
+/// @unlink
+/// @param expToDelete exception instance to delete
+void deleteFromUnwindOurException(_Unwind_Reason_Code reason,
+ OurUnwindException* expToDelete) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "deleteFromUnwindOurException(...).\n");
+#endif
+
+ deleteOurException(expToDelete);
+}
+
+
+/// Creates (allocates on the heap), an exception (OurException instance),
+/// of the supplied type info type.
+/// @param type type info type
+OurUnwindException* createOurException(int type) {
+ size_t size = sizeof(OurException);
+ OurException* ret = (OurException*) memset(malloc(size), 0, size);
+ (ret->type).type = type;
+ (ret->unwindException).exception_class = ourBaseExceptionClass;
+ (ret->unwindException).exception_cleanup = deleteFromUnwindOurException;
+
+ return(&(ret->unwindException));
+}
+
+
+/// Read a uleb128 encoded value and advance pointer
+/// See Variable Length Data in:
+/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
+/// @param data reference variable holding memory pointer to decode from
+/// @returns decoded value
+static uintptr_t readULEB128(const uint8_t** data) {
+ uintptr_t result = 0;
+ uintptr_t shift = 0;
+ unsigned char byte;
+ const uint8_t* p = *data;
+
+ do {
+ byte = *p++;
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ }
+ while (byte & 0x80);
+
+ *data = p;
+
+ return result;
+}
+
+
+/// Read a sleb128 encoded value and advance pointer
+/// See Variable Length Data in:
+/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
+/// @param data reference variable holding memory pointer to decode from
+/// @returns decoded value
+static uintptr_t readSLEB128(const uint8_t** data) {
+ uintptr_t result = 0;
+ uintptr_t shift = 0;
+ unsigned char byte;
+ const uint8_t* p = *data;
+
+ do {
+ byte = *p++;
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ }
+ while (byte & 0x80);
+
+ *data = p;
+
+ if ((byte & 0x40) && (shift < (sizeof(result) << 3))) {
+ result |= (~0 << shift);
+ }
+
+ return result;
+}
+
+
+/// Read a pointer encoded value and advance pointer
+/// See Variable Length Data in:
+/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
+/// @param data reference variable holding memory pointer to decode from
+/// @param encoding dwarf encoding type
+/// @returns decoded value
+static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding) {
+ uintptr_t result = 0;
+ const uint8_t* p = *data;
+
+ if (encoding == llvm::dwarf::DW_EH_PE_omit)
+ return(result);
+
+ // first get value
+ switch (encoding & 0x0F) {
+ case llvm::dwarf::DW_EH_PE_absptr:
+ result = *((uintptr_t*)p);
+ p += sizeof(uintptr_t);
+ break;
+ case llvm::dwarf::DW_EH_PE_uleb128:
+ result = readULEB128(&p);
+ break;
+ // Note: This case has not been tested
+ case llvm::dwarf::DW_EH_PE_sleb128:
+ result = readSLEB128(&p);
+ break;
+ case llvm::dwarf::DW_EH_PE_udata2:
+ result = *((uint16_t*)p);
+ p += sizeof(uint16_t);
+ break;
+ case llvm::dwarf::DW_EH_PE_udata4:
+ result = *((uint32_t*)p);
+ p += sizeof(uint32_t);
+ break;
+ case llvm::dwarf::DW_EH_PE_udata8:
+ result = *((uint64_t*)p);
+ p += sizeof(uint64_t);
+ break;
+ case llvm::dwarf::DW_EH_PE_sdata2:
+ result = *((int16_t*)p);
+ p += sizeof(int16_t);
+ break;
+ case llvm::dwarf::DW_EH_PE_sdata4:
+ result = *((int32_t*)p);
+ p += sizeof(int32_t);
+ break;
+ case llvm::dwarf::DW_EH_PE_sdata8:
+ result = *((int64_t*)p);
+ p += sizeof(int64_t);
+ break;
+ default:
+ // not supported
+ abort();
+ break;
+ }
+
+ // then add relative offset
+ switch (encoding & 0x70) {
+ case llvm::dwarf::DW_EH_PE_absptr:
+ // do nothing
+ break;
+ case llvm::dwarf::DW_EH_PE_pcrel:
+ result += (uintptr_t)(*data);
+ break;
+ case llvm::dwarf::DW_EH_PE_textrel:
+ case llvm::dwarf::DW_EH_PE_datarel:
+ case llvm::dwarf::DW_EH_PE_funcrel:
+ case llvm::dwarf::DW_EH_PE_aligned:
+ default:
+ // not supported
+ abort();
+ break;
+ }
+
+ // then apply indirection
+ if (encoding & llvm::dwarf::DW_EH_PE_indirect) {
+ result = *((uintptr_t*)result);
+ }
+
+ *data = p;
+
+ return result;
+}
+
+
+/// Deals with Dwarf actions matching our type infos
+/// (OurExceptionType_t instances). Returns whether or not a dwarf emitted
+/// action matches the supplied exception type. If such a match succeeds,
+/// the resultAction argument will be set with > 0 index value. Only
+/// corresponding llvm.eh.selector type info arguments, cleanup arguments
+/// are supported. Filters are not supported.
+/// See Variable Length Data in:
+/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
+/// Also see @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
+/// @param resultAction reference variable which will be set with result
+/// @param classInfo our array of type info pointers (to globals)
+/// @param actionEntry index into above type info array or 0 (clean up).
+/// We do not support filters.
+/// @param exceptionClass exception class (_Unwind_Exception::exception_class)
+/// of thrown exception.
+/// @param exceptionObject thrown _Unwind_Exception instance.
+/// @returns whether or not a type info was found. False is returned if only
+/// a cleanup was found
+static bool handleActionValue(int64_t *resultAction,
+ struct OurExceptionType_t **classInfo,
+ uintptr_t actionEntry,
+ uint64_t exceptionClass,
+ struct _Unwind_Exception *exceptionObject) {
+ bool ret = false;
+
+ if (!resultAction ||
+ !exceptionObject ||
+ (exceptionClass != ourBaseExceptionClass))
+ return(ret);
+
+ struct OurBaseException_t* excp = (struct OurBaseException_t*)
+ (((char*) exceptionObject) + ourBaseFromUnwindOffset);
+ struct OurExceptionType_t *excpType = &(excp->type);
+ int type = excpType->type;
+
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleActionValue(...): exceptionObject = <%p>, "
+ "excp = <%p>.\n",
+ exceptionObject,
+ excp);
+#endif
+
+ const uint8_t *actionPos = (uint8_t*) actionEntry,
+ *tempActionPos;
+ int64_t typeOffset = 0,
+ actionOffset;
+
+ for (int i = 0; true; ++i) {
+ // Each emitted dwarf action corresponds to a 2 tuple of
+ // type info address offset, and action offset to the next
+ // emitted action.
+ typeOffset = readSLEB128(&actionPos);
+ tempActionPos = actionPos;
+ actionOffset = readSLEB128(&tempActionPos);
+
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleActionValue(...):typeOffset: <%lld>, "
+ "actionOffset: <%lld>.\n",
+ typeOffset,
+ actionOffset);
+#endif
+ assert((typeOffset >= 0) &&
+ "handleActionValue(...):filters are not supported.");
+
+ // Note: A typeOffset == 0 implies that a cleanup llvm.eh.selector
+ // argument has been matched.
+ if ((typeOffset > 0) &&
+ (type == (classInfo[-typeOffset])->type)) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleActionValue(...):actionValue <%d> found.\n",
+ i);
+#endif
+ *resultAction = i + 1;
+ ret = true;
+ break;
+ }
+
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleActionValue(...):actionValue not found.\n");
+#endif
+ if (!actionOffset)
+ break;
+
+ actionPos += actionOffset;
+ }
+
+ return(ret);
+}
+
+
+/// Deals with the Language specific data portion of the emitted dwarf code.
+/// See @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
+/// @param version unsupported (ignored), unwind version
+/// @param lsda language specific data area
+/// @param _Unwind_Action actions minimally supported unwind stage
+/// (forced specifically not supported)
+/// @param exceptionClass exception class (_Unwind_Exception::exception_class)
+/// of thrown exception.
+/// @param exceptionObject thrown _Unwind_Exception instance.
+/// @param context unwind system context
+/// @returns minimally supported unwinding control indicator
+static _Unwind_Reason_Code handleLsda(int version,
+ const uint8_t* lsda,
+ _Unwind_Action actions,
+ uint64_t exceptionClass,
+ struct _Unwind_Exception* exceptionObject,
+ _Unwind_Context_t context) {
+ _Unwind_Reason_Code ret = _URC_CONTINUE_UNWIND;
+
+ if (!lsda)
+ return(ret);
+
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleLsda(...):lsda is non-zero.\n");
+#endif
+
+ // Get the current instruction pointer and offset it before next
+ // instruction in the current frame which threw the exception.
+ uintptr_t pc = _Unwind_GetIP(context)-1;
+
+ // Get beginning current frame's code (as defined by the
+ // emitted dwarf code)
+ uintptr_t funcStart = _Unwind_GetRegionStart(context);
+ uintptr_t pcOffset = pc - funcStart;
+ struct OurExceptionType_t** classInfo = NULL;
+
+ // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
+ // dwarf emission
+
+ // Parse LSDA header.
+ uint8_t lpStartEncoding = *lsda++;
+
+ if (lpStartEncoding != llvm::dwarf::DW_EH_PE_omit) {
+ readEncodedPointer(&lsda, lpStartEncoding);
+ }
+
+ uint8_t ttypeEncoding = *lsda++;
+ uintptr_t classInfoOffset;
+
+ if (ttypeEncoding != llvm::dwarf::DW_EH_PE_omit) {
+ // Calculate type info locations in emitted dwarf code which
+ // were flagged by type info arguments to llvm.eh.selector
+ // intrinsic
+ classInfoOffset = readULEB128(&lsda);
+ classInfo = (struct OurExceptionType_t**) (lsda + classInfoOffset);
+ }
+
+ // Walk call-site table looking for range that
+ // includes current PC.
+
+ uint8_t callSiteEncoding = *lsda++;
+ uint32_t callSiteTableLength = readULEB128(&lsda);
+ const uint8_t* callSiteTableStart = lsda;
+ const uint8_t* callSiteTableEnd = callSiteTableStart +
+ callSiteTableLength;
+ const uint8_t* actionTableStart = callSiteTableEnd;
+ const uint8_t* callSitePtr = callSiteTableStart;
+
+ bool foreignException = false;
+
+ while (callSitePtr < callSiteTableEnd) {
+ uintptr_t start = readEncodedPointer(&callSitePtr,
+ callSiteEncoding);
+ uintptr_t length = readEncodedPointer(&callSitePtr,
+ callSiteEncoding);
+ uintptr_t landingPad = readEncodedPointer(&callSitePtr,
+ callSiteEncoding);
+
+ // Note: Action value
+ uintptr_t actionEntry = readULEB128(&callSitePtr);
+
+ if (exceptionClass != ourBaseExceptionClass) {
+ // We have been notified of a foreign exception being thrown,
+ // and we therefore need to execute cleanup landing pads
+ actionEntry = 0;
+ foreignException = true;
+ }
+
+ if (landingPad == 0) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleLsda(...): No landing pad found.\n");
+#endif
+
+ continue; // no landing pad for this entry
+ }
+
+ if (actionEntry) {
+ actionEntry += ((uintptr_t) actionTableStart) - 1;
+ }
+ else {
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleLsda(...):No action table found.\n");
+#endif
+ }
+
+ bool exceptionMatched = false;
+
+ if ((start <= pcOffset) && (pcOffset < (start + length))) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleLsda(...): Landing pad found.\n");
+#endif
+ int64_t actionValue = 0;
+
+ if (actionEntry) {
+ exceptionMatched = handleActionValue
+ (
+ &actionValue,
+ classInfo,
+ actionEntry,
+ exceptionClass,
+ exceptionObject
+ );
+ }
+
+ if (!(actions & _UA_SEARCH_PHASE)) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleLsda(...): installed landing pad "
+ "context.\n");
+#endif
+
+ // Found landing pad for the PC.
+ // Set Instruction Pointer to so we re-enter function
+ // at landing pad. The landing pad is created by the
+ // compiler to take two parameters in registers.
+ _Unwind_SetGR(context,
+ __builtin_eh_return_data_regno(0),
+ (uintptr_t)exceptionObject);
+
+ // Note: this virtual register directly corresponds
+ // to the return of the llvm.eh.selector intrinsic
+ if (!actionEntry || !exceptionMatched) {
+ // We indicate cleanup only
+ _Unwind_SetGR(context,
+ __builtin_eh_return_data_regno(1),
+ 0);
+ }
+ else {
+ // Matched type info index of llvm.eh.selector intrinsic
+ // passed here.
+ _Unwind_SetGR(context,
+ __builtin_eh_return_data_regno(1),
+ actionValue);
+ }
+
+ // To execute landing pad set here
+ _Unwind_SetIP(context, funcStart + landingPad);
+ ret = _URC_INSTALL_CONTEXT;
+ }
+ else if (exceptionMatched) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleLsda(...): setting handler found.\n");
+#endif
+ ret = _URC_HANDLER_FOUND;
+ }
+ else {
+ // Note: Only non-clean up handlers are marked as
+ // found. Otherwise the clean up handlers will be
+ // re-found and executed during the clean up
+ // phase.
+#ifdef DEBUG
+ fprintf(stderr,
+ "handleLsda(...): cleanup handler found.\n");
+#endif
+ }
+
+ break;
+ }
+ }
+
+ return(ret);
+}
+
+
+/// This is the personality function which is embedded (dwarf emitted), in the
+/// dwarf unwind info block. Again see: JITDwarfEmitter.cpp.
+/// See @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
+/// @param version unsupported (ignored), unwind version
+/// @param _Unwind_Action actions minimally supported unwind stage
+/// (forced specifically not supported)
+/// @param exceptionClass exception class (_Unwind_Exception::exception_class)
+/// of thrown exception.
+/// @param exceptionObject thrown _Unwind_Exception instance.
+/// @param context unwind system context
+/// @returns minimally supported unwinding control indicator
+_Unwind_Reason_Code ourPersonality(int version,
+ _Unwind_Action actions,
+ uint64_t exceptionClass,
+ struct _Unwind_Exception* exceptionObject,
+ _Unwind_Context_t context) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "We are in ourPersonality(...):actions is <%d>.\n",
+ actions);
+
+ if (actions & _UA_SEARCH_PHASE) {
+ fprintf(stderr, "ourPersonality(...):In search phase.\n");
+ }
+ else {
+ fprintf(stderr, "ourPersonality(...):In non-search phase.\n");
+ }
+#endif
+
+ const uint8_t* lsda = (uint8_t*)
+ _Unwind_GetLanguageSpecificData(context);
+
+#ifdef DEBUG
+ fprintf(stderr,
+ "ourPersonality(...):lsda = <%p>.\n",
+ lsda);
+#endif
+
+ // The real work of the personality function is captured here
+ return(handleLsda(version,
+ lsda,
+ actions,
+ exceptionClass,
+ exceptionObject,
+ context));
+}
+
+
+/// Generates our _Unwind_Exception class from a given character array.
+/// thereby handling arbitrary lengths (not in standard), and handling
+/// embedded \0s.
+/// See @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
+/// @param classChars char array to encode. NULL values not checkedf
+/// @param classCharsSize number of chars in classChars. Value is not checked.
+/// @returns class value
+uint64_t genClass(const unsigned char classChars[], size_t classCharsSize)
+{
+ uint64_t ret = classChars[0];
+
+ for (unsigned i = 1; i < classCharsSize; ++i) {
+ ret <<= 8;
+ ret += classChars[i];
+ }
+
+ return(ret);
+}
+
+} // extern "C"
+
+//
+// Runtime C Library functions End
+//
+
+//
+// Code generation functions
+//
+
+/// Generates code to print given constant string
+/// @param context llvm context
+/// @param module code for module instance
+/// @param builder builder instance
+/// @param toPrint string to print
+/// @param useGlobal A value of true (default) indicates a GlobalValue is
+/// generated, and is used to hold the constant string. A value of
+/// false indicates that the constant string will be stored on the
+/// stack.
+void generateStringPrint(llvm::LLVMContext& context,
+ llvm::Module& module,
+ llvm::IRBuilder<>& builder,
+ std::string toPrint,
+ bool useGlobal = true) {
+ llvm::Function *printFunct = module.getFunction("printStr");
+
+ llvm::Value *stringVar;
+ llvm::Constant* stringConstant =
+ llvm::ConstantArray::get(context, toPrint);
+
+ if (useGlobal) {
+ // Note: Does not work without allocation
+ stringVar =
+ new llvm::GlobalVariable(module,
+ stringConstant->getType(),
+ true,
+ llvm::GlobalValue::LinkerPrivateLinkage,
+ stringConstant,
+ "");
+ }
+ else {
+ stringVar = builder.CreateAlloca(stringConstant->getType());
+ builder.CreateStore(stringConstant, stringVar);
+ }
+
+ llvm::Value* cast =
+ builder.CreatePointerCast(stringVar,
+ builder.getInt8Ty()->getPointerTo());
+ builder.CreateCall(printFunct, cast);
+}
+
+
+/// Generates code to print given runtime integer according to constant
+/// string format, and a given print function.
+/// @param context llvm context
+/// @param module code for module instance
+/// @param builder builder instance
+/// @param printFunct function used to "print" integer
+/// @param toPrint string to print
+/// @param format printf like formating string for print
+/// @param useGlobal A value of true (default) indicates a GlobalValue is
+/// generated, and is used to hold the constant string. A value of
+/// false indicates that the constant string will be stored on the
+/// stack.
+void generateIntegerPrint(llvm::LLVMContext& context,
+ llvm::Module& module,
+ llvm::IRBuilder<>& builder,
+ llvm::Function& printFunct,
+ llvm::Value& toPrint,
+ std::string format,
+ bool useGlobal = true) {
+ llvm::Constant *stringConstant = llvm::ConstantArray::get(context, format);
+ llvm::Value *stringVar;
+
+ if (useGlobal) {
+ // Note: Does not seem to work without allocation
+ stringVar =
+ new llvm::GlobalVariable(module,
+ stringConstant->getType(),
+ true,
+ llvm::GlobalValue::LinkerPrivateLinkage,
+ stringConstant,
+ "");
+ }
+ else {
+ stringVar = builder.CreateAlloca(stringConstant->getType());
+ builder.CreateStore(stringConstant, stringVar);
+ }
+
+ llvm::Value* cast =
+ builder.CreateBitCast(stringVar,
+ builder.getInt8Ty()->getPointerTo());
+ builder.CreateCall2(&printFunct, &toPrint, cast);
+}
+
+
+/// Generates code to handle finally block type semantics: always runs
+/// regardless of whether a thrown exception is passing through or the
+/// parent function is simply exiting. In addition to printing some state
+/// to stderr, this code will resume the exception handling--runs the
+/// unwind resume block, if the exception has not been previously caught
+/// by a catch clause, and will otherwise execute the end block (terminator
+/// block). In addition this function creates the corresponding function's
+/// stack storage for the exception pointer and catch flag status.
+/// @param context llvm context
+/// @param module code for module instance
+/// @param builder builder instance
+/// @param toAddTo parent function to add block to
+/// @param blockName block name of new "finally" block.
+/// @param functionId output id used for printing
+/// @param terminatorBlock terminator "end" block
+/// @param unwindResumeBlock unwind resume block
+/// @param exceptionCaughtFlag reference exception caught/thrown status storage
+/// @param exceptionStorage reference to exception pointer storage
+/// @returns newly created block
+static llvm::BasicBlock* createFinallyBlock(llvm::LLVMContext& context,
+ llvm::Module& module,
+ llvm::IRBuilder<>& builder,
+ llvm::Function& toAddTo,
+ std::string& blockName,
+ std::string& functionId,
+ llvm::BasicBlock& terminatorBlock,
+ llvm::BasicBlock& unwindResumeBlock,
+ llvm::Value** exceptionCaughtFlag,
+ llvm::Value** exceptionStorage) {
+ assert(exceptionCaughtFlag &&
+ "ExceptionDemo::createFinallyBlock(...):exceptionCaughtFlag "
+ "is NULL");
+ assert(exceptionStorage &&
+ "ExceptionDemo::createFinallyBlock(...):exceptionStorage "
+ "is NULL");
+
+ *exceptionCaughtFlag =
+ createEntryBlockAlloca(toAddTo,
+ "exceptionCaught",
+ ourExceptionNotThrownState->getType(),
+ ourExceptionNotThrownState);
+
+ const llvm::PointerType* exceptionStorageType =
+ builder.getInt8Ty()->getPointerTo();
+ *exceptionStorage =
+ createEntryBlockAlloca(toAddTo,
+ "exceptionStorage",
+ exceptionStorageType,
+ llvm::ConstantPointerNull::get(
+ exceptionStorageType));
+
+ llvm::BasicBlock *ret = llvm::BasicBlock::Create(context,
+ blockName,
+ &toAddTo);
+
+ builder.SetInsertPoint(ret);
+
+ std::ostringstream bufferToPrint;
+ bufferToPrint << "Gen: Executing finally block "
+ << blockName
+ << " in "
+ << functionId
+ << std::endl;
+ generateStringPrint(context,
+ module,
+ builder,
+ bufferToPrint.str(),
+ USE_GLOBAL_STR_CONSTS);
+
+ llvm::SwitchInst* theSwitch =
+ builder.CreateSwitch(builder.CreateLoad(*exceptionCaughtFlag),
+ &terminatorBlock,
+ 2);
+ theSwitch->addCase(ourExceptionCaughtState, &terminatorBlock);
+ theSwitch->addCase(ourExceptionThrownState, &unwindResumeBlock);
+
+ return(ret);
+}
+
+
+/// Generates catch block semantics which print a string to indicate type of
+/// catch executed, sets an exception caught flag, and executes passed in
+/// end block (terminator block).
+/// @param context llvm context
+/// @param module code for module instance
+/// @param builder builder instance
+/// @param toAddTo parent function to add block to
+/// @param blockName block name of new "catch" block.
+/// @param functionId output id used for printing
+/// @param terminatorBlock terminator "end" block
+/// @param exceptionCaughtFlag exception caught/thrown status
+/// @returns newly created block
+static llvm::BasicBlock* createCatchBlock(llvm::LLVMContext& context,
+ llvm::Module& module,
+ llvm::IRBuilder<>& builder,
+ llvm::Function& toAddTo,
+ std::string& blockName,
+ std::string& functionId,
+ llvm::BasicBlock& terminatorBlock,
+ llvm::Value& exceptionCaughtFlag) {
+
+ llvm::BasicBlock *ret = llvm::BasicBlock::Create(context,
+ blockName,
+ &toAddTo);
+
+ builder.SetInsertPoint(ret);
+
+ std::ostringstream bufferToPrint;
+ bufferToPrint << "Gen: Executing catch block "
+ << blockName
+ << " in "
+ << functionId
+ << std::endl;
+ generateStringPrint(context,
+ module,
+ builder,
+ bufferToPrint.str(),
+ USE_GLOBAL_STR_CONSTS);
+ builder.CreateStore(ourExceptionCaughtState, &exceptionCaughtFlag);
+ builder.CreateBr(&terminatorBlock);
+
+ return(ret);
+}
+
+
+/// Generates a function which invokes a function (toInvoke) and, whose
+/// unwind block will "catch" the type info types correspondingly held in the
+/// exceptionTypesToCatch argument. If the toInvoke function throws an
+/// exception which does not match any type info types contained in
+/// exceptionTypesToCatch, the generated code will call _Unwind_Resume
+/// with the raised exception. On the other hand the generated code will
+/// normally exit if the toInvoke function does not throw an exception.
+/// The generated "finally" block is always run regardless of the cause of
+/// the generated function exit.
+/// The generated function is returned after being verified.
+/// @param module code for module instance
+/// @param builder builder instance
+/// @param fpm a function pass manager holding optional IR to IR
+/// transformations
+/// @param toInvoke inner function to invoke
+/// @param ourId id used to printing purposes
+/// @param numExceptionsToCatch length of exceptionTypesToCatch array
+/// @param exceptionTypesToCatch array of type info types to "catch"
+/// @returns generated function
+static
+llvm::Function* createCatchWrappedInvokeFunction(llvm::Module& module,
+ llvm::IRBuilder<>& builder,
+ llvm::FunctionPassManager& fpm,
+ llvm::Function& toInvoke,
+ std::string ourId,
+ unsigned numExceptionsToCatch,
+ unsigned exceptionTypesToCatch[]) {
+
+ llvm::LLVMContext& context = module.getContext();
+ llvm::Function *toPrint32Int = module.getFunction("print32Int");
+
+ ArgTypes argTypes;
+ argTypes.push_back(builder.getInt32Ty());
+
+ ArgNames argNames;
+ argNames.push_back("exceptTypeToThrow");
+
+ llvm::Function* ret = createFunction(module,
+ builder.getVoidTy(),
+ argTypes,
+ argNames,
+ ourId,
+ llvm::Function::ExternalLinkage,
+ false,
+ false);
+
+ // Block which calls invoke
+ llvm::BasicBlock *entryBlock = llvm::BasicBlock::Create(context,
+ "entry",
+ ret);
+ // Normal block for invoke
+ llvm::BasicBlock *normalBlock = llvm::BasicBlock::Create(context,
+ "normal",
+ ret);
+ // Unwind block for invoke
+ llvm::BasicBlock *exceptionBlock =
+ llvm::BasicBlock::Create(context, "exception", ret);
+
+ // Block which routes exception to correct catch handler block
+ llvm::BasicBlock *exceptionRouteBlock =
+ llvm::BasicBlock::Create(context, "exceptionRoute", ret);
+
+ // Foreign exception handler
+ llvm::BasicBlock *externalExceptionBlock =
+ llvm::BasicBlock::Create(context, "externalException", ret);
+
+ // Block which calls _Unwind_Resume
+ llvm::BasicBlock *unwindResumeBlock =
+ llvm::BasicBlock::Create(context, "unwindResume", ret);
+
+ // Clean up block which delete exception if needed
+ llvm::BasicBlock *endBlock =
+ llvm::BasicBlock::Create(context, "end", ret);
+
+ std::string nextName;
+ std::vector<llvm::BasicBlock*> catchBlocks(numExceptionsToCatch);
+ llvm::Value* exceptionCaughtFlag = NULL;
+ llvm::Value* exceptionStorage = NULL;
+
+ // Finally block which will branch to unwindResumeBlock if
+ // exception is not caught. Initializes/allocates stack locations.
+ llvm::BasicBlock* finallyBlock = createFinallyBlock(context,
+ module,
+ builder,
+ *ret,
+ nextName = "finally",
+ ourId,
+ *endBlock,
+ *unwindResumeBlock,
+ &exceptionCaughtFlag,
+ &exceptionStorage);
+
+ for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
+ nextName = ourTypeInfoNames[exceptionTypesToCatch[i]];
+
+ // One catch block per type info to be caught
+ catchBlocks[i] = createCatchBlock(context,
+ module,
+ builder,
+ *ret,
+ nextName,
+ ourId,
+ *finallyBlock,
+ *exceptionCaughtFlag);
+ }
+
+ // Entry Block
+
+ builder.SetInsertPoint(entryBlock);
+
+ std::vector<llvm::Value*> args;
+ args.push_back(namedValues["exceptTypeToThrow"]);
+ builder.CreateInvoke(&toInvoke,
+ normalBlock,
+ exceptionBlock,
+ args.begin(),
+ args.end());
+
+ // End Block
+
+ builder.SetInsertPoint(endBlock);
+
+ generateStringPrint(context,
+ module,
+ builder,
+ "Gen: In end block: exiting in " + ourId + ".\n",
+ USE_GLOBAL_STR_CONSTS);
+ llvm::Function *deleteOurException =
+ module.getFunction("deleteOurException");
+
+ // Note: function handles NULL exceptions
+ builder.CreateCall(deleteOurException,
+ builder.CreateLoad(exceptionStorage));
+ builder.CreateRetVoid();
+
+ // Normal Block
+
+ builder.SetInsertPoint(normalBlock);
+
+ generateStringPrint(context,
+ module,
+ builder,
+ "Gen: No exception in " + ourId + "!\n",
+ USE_GLOBAL_STR_CONSTS);
+
+ // Finally block is always called
+ builder.CreateBr(finallyBlock);
+
+ // Unwind Resume Block
+
+ builder.SetInsertPoint(unwindResumeBlock);
+
+ llvm::Function *resumeOurException =
+ module.getFunction("_Unwind_Resume");
+ builder.CreateCall(resumeOurException,
+ builder.CreateLoad(exceptionStorage));
+ builder.CreateUnreachable();
+
+ // Exception Block
+
+ builder.SetInsertPoint(exceptionBlock);
+
+ llvm::Function *ehException = module.getFunction("llvm.eh.exception");
+
+ // Retrieve thrown exception
+ llvm::Value* unwindException = builder.CreateCall(ehException);
+
+ // Store exception and flag
+ builder.CreateStore(unwindException, exceptionStorage);
+ builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag);
+ llvm::Function *personality = module.getFunction("ourPersonality");
+ llvm::Value* functPtr =
+ builder.CreatePointerCast(personality,
+ builder.getInt8Ty()->getPointerTo());
+
+ args.clear();
+ args.push_back(unwindException);
+ args.push_back(functPtr);
+
+ // Note: Skipping index 0
+ for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
+ // Set up type infos to be caught
+ args.push_back(
+ module.getGlobalVariable(
+ ourTypeInfoNames[exceptionTypesToCatch[i]]));
+ }
+
+ args.push_back(llvm::ConstantInt::get(builder.getInt32Ty(), 0));
+
+ llvm::Function *ehSelector = module.getFunction("llvm.eh.selector");
+
+ // Set up this exeption block as the landing pad which will handle
+ // given type infos. See case Intrinsic::eh_selector in
+ // SelectionDAGBuilder::visitIntrinsicCall(...) and AddCatchInfo(...)
+ // implemented in FunctionLoweringInfo.cpp to see how the implementation
+ // handles this call. This landing pad (this exception block), will be
+ // called either because it nees to cleanup (call finally) or a type
+ // info was found which matched the thrown exception.
+ llvm::Value* retTypeInfoIndex = builder.CreateCall(ehSelector,
+ args.begin(),
+ args.end());
+
+ // Retrieve exception_class member from thrown exception
+ // (_Unwind_Exception instance). This member tells us whether or not
+ // the exception is foreign.
+ llvm::Value* unwindExceptionClass =
+ builder.CreateLoad(
+ builder.CreateStructGEP(
+ builder.CreatePointerCast(
+ unwindException,
+ ourUnwindExceptionType->getPointerTo()),
+ 0));
+
+ // Branch to the externalExceptionBlock if the exception is foreign or
+ // to a catch router if not. Either way the finally block will be run.
+ builder.CreateCondBr(
+ builder.CreateICmpEQ(unwindExceptionClass,
+ llvm::ConstantInt::get(builder.getInt64Ty(),
+ ourBaseExceptionClass)),
+ exceptionRouteBlock,
+ externalExceptionBlock);
+
+ // External Exception Block
+
+ builder.SetInsertPoint(externalExceptionBlock);
+
+ generateStringPrint(context,
+ module,
+ builder,
+ "Gen: Foreign exception received.\n",
+ USE_GLOBAL_STR_CONSTS);
+
+ // Branch to the finally block
+ builder.CreateBr(finallyBlock);
+
+ // Exception Route Block
+
+ builder.SetInsertPoint(exceptionRouteBlock);
+
+ // Casts exception pointer (_Unwind_Exception instance) to parent
+ // (OurException instance).
+ //
+ // Note: ourBaseFromUnwindOffset is usually negative
+ llvm::Value* typeInfoThrown =
+ builder.CreatePointerCast(
+ builder.CreateConstGEP1_64(unwindException,
+ ourBaseFromUnwindOffset),
+ ourExceptionType->getPointerTo());
+
+ // Retrieve thrown exception type info type
+ //
+ // Note: Index is not relative to pointer but instead to structure
+ // unlike a true getelementptr (GEP) instruction
+ typeInfoThrown = builder.CreateStructGEP(typeInfoThrown, 0);
+
+ llvm::Value* typeInfoThrownType =
+ builder.CreateStructGEP(typeInfoThrown, 0);
+
+ generateIntegerPrint(context,
+ module,
+ builder,
+ *toPrint32Int,
+ *(builder.CreateLoad(typeInfoThrownType)),
+ "Gen: Exception type <%d> received (stack unwound) "
+ " in " +
+ ourId +
+ ".\n",
+ USE_GLOBAL_STR_CONSTS);
+
+ // Route to matched type info catch block or run cleanup finally block
+ llvm::SwitchInst* switchToCatchBlock =
+ builder.CreateSwitch(retTypeInfoIndex,
+ finallyBlock,
+ numExceptionsToCatch);
+
+ unsigned nextTypeToCatch;
+
+ for (unsigned i = 1; i <= numExceptionsToCatch; ++i) {
+ nextTypeToCatch = i - 1;
+ switchToCatchBlock->addCase(llvm::ConstantInt::get(
+ llvm::Type::getInt32Ty(context),
+ i),
+ catchBlocks[nextTypeToCatch]);
+ }
+
+ llvm::verifyFunction(*ret);
+ fpm.run(*ret);
+
+ return(ret);
+}
+
+
+/// Generates function which throws either an exception matched to a runtime
+/// determined type info type (argument to generated function), or if this
+/// runtime value matches nativeThrowType, throws a foreign exception by
+/// calling nativeThrowFunct.
+/// @param module code for module instance
+/// @param builder builder instance
+/// @param fpm a function pass manager holding optional IR to IR
+/// transformations
+/// @param ourId id used to printing purposes
+/// @param nativeThrowType a runtime argument of this value results in
+/// nativeThrowFunct being called to generate/throw exception.
+/// @param nativeThrowFunct function which will throw a foreign exception
+/// if the above nativeThrowType matches generated function's arg.
+/// @returns generated function
+static
+llvm::Function* createThrowExceptionFunction(llvm::Module& module,
+ llvm::IRBuilder<>& builder,
+ llvm::FunctionPassManager& fpm,
+ std::string ourId,
+ int32_t nativeThrowType,
+ llvm::Function& nativeThrowFunct) {
+ llvm::LLVMContext& context = module.getContext();
+ namedValues.clear();
+ ArgTypes unwindArgTypes;
+ unwindArgTypes.push_back(builder.getInt32Ty());
+ ArgNames unwindArgNames;
+ unwindArgNames.push_back("exceptTypeToThrow");
+
+ llvm::Function *ret = createFunction(module,
+ builder.getVoidTy(),
+ unwindArgTypes,
+ unwindArgNames,
+ ourId,
+ llvm::Function::ExternalLinkage,
+ false,
+ false);
+
+ // Throws either one of our exception or a native C++ exception depending
+ // on a runtime argument value containing a type info type.
+ llvm::BasicBlock *entryBlock = llvm::BasicBlock::Create(context,
+ "entry",
+ ret);
+ // Throws a foreign exception
+ llvm::BasicBlock *nativeThrowBlock =
+ llvm::BasicBlock::Create(context,
+ "nativeThrow",
+ ret);
+ // Throws one of our Exceptions
+ llvm::BasicBlock *generatedThrowBlock =
+ llvm::BasicBlock::Create(context,
+ "generatedThrow",
+ ret);
+ // Retrieved runtime type info type to throw
+ llvm::Value* exceptionType = namedValues["exceptTypeToThrow"];
+
+ // nativeThrowBlock block
+
+ builder.SetInsertPoint(nativeThrowBlock);
+
+ // Throws foreign exception
+ builder.CreateCall(&nativeThrowFunct, exceptionType);
+ builder.CreateUnreachable();
+
+ // entry block
+
+ builder.SetInsertPoint(entryBlock);
+
+ llvm::Function *toPrint32Int = module.getFunction("print32Int");
+ generateIntegerPrint(context,
+ module,
+ builder,
+ *toPrint32Int,
+ *exceptionType,
+ "\nGen: About to throw exception type <%d> in " +
+ ourId +
+ ".\n",
+ USE_GLOBAL_STR_CONSTS);
+
+ // Switches on runtime type info type value to determine whether or not
+ // a foreign exception is thrown. Defaults to throwing one of our
+ // generated exceptions.
+ llvm::SwitchInst* theSwitch = builder.CreateSwitch(exceptionType,
+ generatedThrowBlock,
+ 1);
+
+ theSwitch->addCase(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context),
+ nativeThrowType),
+ nativeThrowBlock);
+
+ // generatedThrow block
+
+ builder.SetInsertPoint(generatedThrowBlock);
+
+ llvm::Function *createOurException =
+ module.getFunction("createOurException");
+ llvm::Function *raiseOurException =
+ module.getFunction("_Unwind_RaiseException");
+
+ // Creates exception to throw with runtime type info type.
+ llvm::Value* exception =
+ builder.CreateCall(createOurException,
+ namedValues["exceptTypeToThrow"]);
+
+ // Throw generated Exception
+ builder.CreateCall(raiseOurException, exception);
+ builder.CreateUnreachable();
+
+ llvm::verifyFunction(*ret);
+ fpm.run(*ret);
+
+ return(ret);
+}
+
+static void createStandardUtilityFunctions(unsigned numTypeInfos,
+ llvm::Module& module,
+ llvm::IRBuilder<>& builder);
+
+/// Creates test code by generating and organizing these functions into the
+/// test case. The test case consists of an outer function setup to invoke
+/// an inner function within an environment having multiple catch and single
+/// finally blocks. This inner function is also setup to invoke a throw
+/// function within an evironment similar in nature to the outer function's
+/// catch and finally blocks. Each of these two functions catch mutually
+/// exclusive subsets (even or odd) of the type info types configured
+/// for this this. All generated functions have a runtime argument which
+/// holds a type info type to throw that each function takes and passes it
+/// to the inner one if such a inner function exists. This type info type is
+/// looked at by the generated throw function to see whether or not it should
+/// throw a generated exception with the same type info type, or instead call
+/// a supplied a function which in turn will throw a foreign exception.
+/// @param module code for module instance
+/// @param builder builder instance
+/// @param fpm a function pass manager holding optional IR to IR
+/// transformations
+/// @param nativeThrowFunctName name of external function which will throw
+/// a foreign exception
+/// @returns outermost generated test function.
+llvm::Function* createUnwindExceptionTest(llvm::Module& module,
+ llvm::IRBuilder<>& builder,
+ llvm::FunctionPassManager& fpm,
+ std::string nativeThrowFunctName) {
+ // Number of type infos to generate
+ unsigned numTypeInfos = 6;
+
+ // Initialze intrisics and external functions to use along with exception
+ // and type info globals.
+ createStandardUtilityFunctions(numTypeInfos,
+ module,
+ builder);
+ llvm::Function *nativeThrowFunct =
+ module.getFunction(nativeThrowFunctName);
+
+ // Create exception throw function using the value ~0 to cause
+ // foreign exceptions to be thrown.
+ llvm::Function* throwFunct =
+ createThrowExceptionFunction(module,
+ builder,
+ fpm,
+ "throwFunct",
+ ~0,
+ *nativeThrowFunct);
+ // Inner function will catch even type infos
+ unsigned innerExceptionTypesToCatch[] = {6, 2, 4};
+ size_t numExceptionTypesToCatch = sizeof(innerExceptionTypesToCatch) /
+ sizeof(unsigned);
+
+ // Generate inner function.
+ llvm::Function* innerCatchFunct =
+ createCatchWrappedInvokeFunction(module,
+ builder,
+ fpm,
+ *throwFunct,
+ "innerCatchFunct",
+ numExceptionTypesToCatch,
+ innerExceptionTypesToCatch);
+
+ // Outer function will catch odd type infos
+ unsigned outerExceptionTypesToCatch[] = {3, 1, 5};
+ numExceptionTypesToCatch = sizeof(outerExceptionTypesToCatch) /
+ sizeof(unsigned);
+
+ // Generate outer function
+ llvm::Function* outerCatchFunct =
+ createCatchWrappedInvokeFunction(module,
+ builder,
+ fpm,
+ *innerCatchFunct,
+ "outerCatchFunct",
+ numExceptionTypesToCatch,
+ outerExceptionTypesToCatch);
+
+ // Return outer function to run
+ return(outerCatchFunct);
+}
+
+
+/// Represents our foreign exceptions
+class OurCppRunException : public std::runtime_error {
+public:
+ OurCppRunException(const std::string reason) :
+ std::runtime_error(reason) {}
+
+ OurCppRunException (const OurCppRunException& toCopy) :
+ std::runtime_error(toCopy) {}
+
+ OurCppRunException& operator = (const OurCppRunException& toCopy) {
+ return(reinterpret_cast<OurCppRunException&>(
+ std::runtime_error::operator = (toCopy)
+ ));
+ }
+
+ ~OurCppRunException (void) throw () {};
+};
+
+
+/// Throws foreign C++ exception.
+/// @param ignoreIt unused parameter that allows function to match implied
+/// generated function contract.
+extern "C"
+void throwCppException (int32_t ignoreIt) {
+ throw(OurCppRunException("thrown by throwCppException(...)"));
+}
+
+typedef void (*OurExceptionThrowFunctType) (int32_t typeToThrow);
+
+/// This is a test harness which runs test by executing generated
+/// function with a type info type to throw. Harness wraps the excecution
+/// of generated function in a C++ try catch clause.
+/// @param engine execution engine to use for executing generated function.
+/// This demo program expects this to be a JIT instance for demo
+/// purposes.
+/// @param function generated test function to run
+/// @param typeToThrow type info type of generated exception to throw, or
+/// indicator to cause foreign exception to be thrown.
+static
+void runExceptionThrow(llvm::ExecutionEngine* engine,
+ llvm::Function* function,
+ int32_t typeToThrow) {
+
+ // Find test's function pointer
+ OurExceptionThrowFunctType functPtr =
+ reinterpret_cast<OurExceptionThrowFunctType>(
+ reinterpret_cast<intptr_t>(
+ engine->getPointerToFunction(function)
+ )
+ );
+
+ try {
+ // Run test
+ (*functPtr)(typeToThrow);
+ }
+ catch (OurCppRunException exc) {
+ // Catch foreign C++ exception
+ fprintf(stderr,
+ "\nrunExceptionThrow(...):In C++ catch OurCppRunException "
+ "with reason: %s.\n",
+ exc.what());
+ }
+ catch (...) {
+ // Catch all exceptions including our generated ones. I'm not sure
+ // why this latter functionality should work, as it seems that
+ // our exceptions should be foreign to C++ (the _Unwind_Exception::
+ // exception_class should be different from the one used by C++), and
+ // therefore C++ should ignore the generated exceptions.
+
+ fprintf(stderr,
+ "\nrunExceptionThrow(...):In C++ catch all.\n");
+ }
+}
+
+//
+// End test functions
+//
+
+/// This initialization routine creates type info globals and
+/// adds external function declarations to module.
+/// @param numTypeInfos number of linear type info associated type info types
+/// to create as GlobalVariable instances, starting with the value 1.
+/// @param module code for module instance
+/// @param builder builder instance
+static void createStandardUtilityFunctions(unsigned numTypeInfos,
+ llvm::Module& module,
+ llvm::IRBuilder<>& builder) {
+
+ llvm::LLVMContext& context = module.getContext();
+
+ // Exception initializations
+
+ // Setup exception catch state
+ ourExceptionNotThrownState =
+ llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 0),
+ ourExceptionThrownState =
+ llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 1),
+ ourExceptionCaughtState =
+ llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 2),
+
+
+ // Create our type info type
+ ourTypeInfoType = llvm::StructType::get(context,
+ builder.getInt32Ty(),
+ NULL);
+
+ // Create OurException type
+ ourExceptionType = llvm::StructType::get(context,
+ ourTypeInfoType,
+ NULL);
+
+ // Create portion of _Unwind_Exception type
+ //
+ // Note: Declaring only a portion of the _Unwind_Exception struct.
+ // Does this cause problems?
+ ourUnwindExceptionType = llvm::StructType::get(context,
+ builder.getInt64Ty(),
+ NULL);
+ struct OurBaseException_t dummyException;
+
+ // Calculate offset of OurException::unwindException member.
+ ourBaseFromUnwindOffset = ((uintptr_t) &dummyException) -
+ ((uintptr_t) &(dummyException.unwindException));
+
+#ifdef DEBUG
+ fprintf(stderr,
+ "createStandardUtilityFunctions(...):ourBaseFromUnwindOffset "
+ "= %lld, sizeof(struct OurBaseException_t) - "
+ "sizeof(struct _Unwind_Exception) = %lu.\n",
+ ourBaseFromUnwindOffset,
+ sizeof(struct OurBaseException_t) -
+ sizeof(struct _Unwind_Exception));
+#endif
+
+ size_t numChars = sizeof(ourBaseExcpClassChars) / sizeof(char);
+
+ // Create our _Unwind_Exception::exception_class value
+ ourBaseExceptionClass = genClass(ourBaseExcpClassChars, numChars);
+
+ // Type infos
+
+ std::string baseStr = "typeInfo", typeInfoName;
+ std::ostringstream typeInfoNameBuilder;
+ std::vector<llvm::Constant*> structVals;
+
+ llvm::Constant *nextStruct;
+ llvm::GlobalVariable* nextGlobal = NULL;
+
+ // Generate each type info
+ //
+ // Note: First type info is not used.
+ for (unsigned i = 0; i <= numTypeInfos; ++i) {
+ structVals.clear();
+ structVals.push_back(llvm::ConstantInt::get(builder.getInt32Ty(), i));
+ nextStruct = llvm::ConstantStruct::get(ourTypeInfoType, structVals);
+
+ typeInfoNameBuilder.str("");
+ typeInfoNameBuilder << baseStr << i;
+ typeInfoName = typeInfoNameBuilder.str();
+
+ // Note: Does not seem to work without allocation
+ nextGlobal =
+ new llvm::GlobalVariable(module,
+ ourTypeInfoType,
+ true,
+ llvm::GlobalValue::ExternalLinkage,
+ nextStruct,
+ typeInfoName);
+
+ ourTypeInfoNames.push_back(typeInfoName);
+ ourTypeInfoNamesIndex[i] = typeInfoName;
+ }
+
+ ArgNames argNames;
+ ArgTypes argTypes;
+ llvm::Function* funct = NULL;
+
+ // print32Int
+
+ const llvm::Type* retType = builder.getVoidTy();
+
+ argTypes.clear();
+ argTypes.push_back(builder.getInt32Ty());
+ argTypes.push_back(builder.getInt8Ty()->getPointerTo());
+
+ argNames.clear();
+
+ createFunction(module,
+ retType,
+ argTypes,
+ argNames,
+ "print32Int",
+ llvm::Function::ExternalLinkage,
+ true,
+ false);
+
+ // print64Int
+
+ retType = builder.getVoidTy();
+
+ argTypes.clear();
+ argTypes.push_back(builder.getInt64Ty());
+ argTypes.push_back(builder.getInt8Ty()->getPointerTo());
+
+ argNames.clear();
+
+ createFunction(module,
+ retType,
+ argTypes,
+ argNames,
+ "print64Int",
+ llvm::Function::ExternalLinkage,
+ true,
+ false);
+
+ // printStr
+
+ retType = builder.getVoidTy();
+
+ argTypes.clear();
+ argTypes.push_back(builder.getInt8Ty()->getPointerTo());
+
+ argNames.clear();
+
+ createFunction(module,
+ retType,
+ argTypes,
+ argNames,
+ "printStr",
+ llvm::Function::ExternalLinkage,
+ true,
+ false);
+
+ // throwCppException
+
+ retType = builder.getVoidTy();
+
+ argTypes.clear();
+ argTypes.push_back(builder.getInt32Ty());
+
+ argNames.clear();
+
+ createFunction(module,
+ retType,
+ argTypes,
+ argNames,
+ "throwCppException",
+ llvm::Function::ExternalLinkage,
+ true,
+ false);
+
+ // deleteOurException
+
+ retType = builder.getVoidTy();
+
+ argTypes.clear();
+ argTypes.push_back(builder.getInt8Ty()->getPointerTo());
+
+ argNames.clear();
+
+ createFunction(module,
+ retType,
+ argTypes,
+ argNames,
+ "deleteOurException",
+ llvm::Function::ExternalLinkage,
+ true,
+ false);
+
+ // createOurException
+
+ retType = builder.getInt8Ty()->getPointerTo();
+
+ argTypes.clear();
+ argTypes.push_back(builder.getInt32Ty());
+
+ argNames.clear();
+
+ createFunction(module,
+ retType,
+ argTypes,
+ argNames,
+ "createOurException",
+ llvm::Function::ExternalLinkage,
+ true,
+ false);
+
+ // _Unwind_RaiseException
+
+ retType = builder.getInt32Ty();
+
+ argTypes.clear();
+ argTypes.push_back(builder.getInt8Ty()->getPointerTo());
+
+ argNames.clear();
+
+ funct = createFunction(module,
+ retType,
+ argTypes,
+ argNames,
+ "_Unwind_RaiseException",
+ llvm::Function::ExternalLinkage,
+ true,
+ false);
+
+ funct->addFnAttr(llvm::Attribute::NoReturn);
+
+ // _Unwind_Resume
+
+ retType = builder.getInt32Ty();
+
+ argTypes.clear();
+ argTypes.push_back(builder.getInt8Ty()->getPointerTo());
+
+ argNames.clear();
+
+ funct = createFunction(module,
+ retType,
+ argTypes,
+ argNames,
+ "_Unwind_Resume",
+ llvm::Function::ExternalLinkage,
+ true,
+ false);
+
+ funct->addFnAttr(llvm::Attribute::NoReturn);
+
+ // ourPersonality
+
+ retType = builder.getInt32Ty();
+
+ argTypes.clear();
+ argTypes.push_back(builder.getInt32Ty());
+ argTypes.push_back(builder.getInt32Ty());
+ argTypes.push_back(builder.getInt64Ty());
+ argTypes.push_back(builder.getInt8Ty()->getPointerTo());
+ argTypes.push_back(builder.getInt8Ty()->getPointerTo());
+
+ argNames.clear();
+
+ createFunction(module,
+ retType,
+ argTypes,
+ argNames,
+ "ourPersonality",
+ llvm::Function::ExternalLinkage,
+ true,
+ false);
+
+ // llvm.eh.selector intrinsic
+
+ getDeclaration(&module, llvm::Intrinsic::eh_selector);
+
+ // llvm.eh.exception intrinsic
+
+ getDeclaration(&module, llvm::Intrinsic::eh_exception);
+
+ // llvm.eh.typeid.for intrinsic
+
+ getDeclaration(&module, llvm::Intrinsic::eh_typeid_for);
+}
+
+
+//===---------------------------------------------------------------------===//
+// Main test driver code.
+//===---------------------------------------------------------------------===//
+
+/// Demo main routine which takes the type info types to throw. A test will
+/// be run for each given type info type. While type info types with the value
+/// of -1 will trigger a foreign C++ exception to be thrown; type info types
+/// <= 6 and >= 1 will be caught by test functions; and type info types > 6
+/// will result in exceptions which pass through to the test harness. All other
+/// type info types are not supported and could cause a crash.
+int main(int argc, char* argv[]) {
+ if (argc == 1) {
+ fprintf(stderr,
+ "\nUsage: ExceptionDemo <exception type to throw> "
+ "[<type 2>...<type n>].\n"
+ " Each type must have the value of 1 - 6 for "
+ "generated exceptions to be caught;\n"
+ " the value -1 for foreign C++ exceptions to be "
+ "generated and thrown;\n"
+ " or the values > 6 for exceptions to be ignored.\n"
+ "\nTry: ExceptionDemo 2 3 7 -1\n"
+ " for a full test.\n\n");
+ return(0);
+ }
+
+ // If not set, exception handling will not be turned on
+ llvm::DwarfExceptionHandling = true;
+
+ llvm::InitializeNativeTarget();
+ llvm::LLVMContext& context = llvm::getGlobalContext();
+ llvm::IRBuilder<> theBuilder(context);
+
+ // Make the module, which holds all the code.
+ llvm::Module* module = new llvm::Module("my cool jit", context);
+
+ // Build engine with JIT
+ llvm::EngineBuilder factory(module);
+ factory.setEngineKind(llvm::EngineKind::JIT);
+ factory.setAllocateGVsWithCode(false);
+ llvm::ExecutionEngine* executionEngine = factory.create();
+
+ {
+ llvm::FunctionPassManager fpm(module);
+
+ // Set up the optimizer pipeline.
+ // Start with registering info about how the
+ // target lays out data structures.
+ fpm.add(new llvm::TargetData(*executionEngine->getTargetData()));
+
+ // Optimizations turned on
+#ifdef ADD_OPT_PASSES
+
+ // Promote allocas to registers.
+ fpm.add(llvm::createPromoteMemoryToRegisterPass());
+
+ // Do simple "peephole" optimizations and bit-twiddling optzns.
+ fpm.add(llvm::createInstructionCombiningPass());
+
+ // Reassociate expressions.
+ fpm.add(llvm::createReassociatePass());
+
+ // Eliminate Common SubExpressions.
+ fpm.add(llvm::createGVNPass());
+
+ // Simplify the control flow graph (deleting unreachable
+ // blocks, etc).
+ fpm.add(llvm::createCFGSimplificationPass());
+#endif // ADD_OPT_PASSES
+
+ fpm.doInitialization();
+
+ // Generate test code using function throwCppException(...) as
+ // the function which throws foreign exceptions.
+ llvm::Function* toRun =
+ createUnwindExceptionTest(*module,
+ theBuilder,
+ fpm,
+ "throwCppException");
+
+ fprintf(stderr, "\nBegin module dump:\n\n");
+
+ module->dump();
+
+ fprintf(stderr, "\nEnd module dump:\n");
+
+ fprintf(stderr, "\n\nBegin Test:\n");
+
+ for (int i = 1; i < argc; ++i) {
+ // Run test for each argument whose value is the exception
+ // type to throw.
+ runExceptionThrow(executionEngine,
+ toRun,
+ (unsigned) strtoul(argv[i], NULL, 10));
+ }
+
+ fprintf(stderr, "\nEnd Test:\n\n");
+ }
+
+ delete executionEngine;
+
+ return 0;
+}
+
diff --git a/examples/ExceptionDemo/Makefile b/examples/ExceptionDemo/Makefile
new file mode 100644
index 0000000..06bba66
--- /dev/null
+++ b/examples/ExceptionDemo/Makefile
@@ -0,0 +1,17 @@
+##===- examples/ExceptionDemo/Makefile --------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===---------------------------------------------------------------------===##
+LEVEL = ../..
+TOOLNAME = ExceptionDemo
+EXAMPLE_TOOL = 1
+
+LINK_COMPONENTS := jit interpreter nativecodegen
+
+include $(LEVEL)/Makefile.common
+
+CXXFLAGS += -fexceptions
diff --git a/examples/Fibonacci/fibonacci.cpp b/examples/Fibonacci/fibonacci.cpp
index 077cdd0..353e173 100644
--- a/examples/Fibonacci/fibonacci.cpp
+++ b/examples/Fibonacci/fibonacci.cpp
@@ -28,7 +28,6 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/Interpreter.h"
diff --git a/examples/HowToUseJIT/HowToUseJIT.cpp b/examples/HowToUseJIT/HowToUseJIT.cpp
index ec9c2e6..8e3b6dc 100644
--- a/examples/HowToUseJIT/HowToUseJIT.cpp
+++ b/examples/HowToUseJIT/HowToUseJIT.cpp
@@ -12,7 +12,7 @@
//
// Goal:
// The goal of this snippet is to create in the memory
-// the LLVM module consisting of two functions as follow:
+// the LLVM module consisting of two functions as follow:
//
// int add1(int x) {
// return x+1;
@@ -39,7 +39,6 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
diff --git a/examples/Kaleidoscope/Chapter4/Makefile b/examples/Kaleidoscope/Chapter4/Makefile
index 7bc742f..30162d9 100644
--- a/examples/Kaleidoscope/Chapter4/Makefile
+++ b/examples/Kaleidoscope/Chapter4/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../..
TOOLNAME = Kaleidoscope-Ch4
EXAMPLE_TOOL = 1
-LINK_COMPONENTS := core jit interpreter native
+LINK_COMPONENTS := core jit native
include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter4/toy.cpp b/examples/Kaleidoscope/Chapter4/toy.cpp
index d136635..a2ddda2 100644
--- a/examples/Kaleidoscope/Chapter4/toy.cpp
+++ b/examples/Kaleidoscope/Chapter4/toy.cpp
@@ -1,10 +1,8 @@
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
@@ -573,13 +571,15 @@ int main() {
// Make the module, which holds all the code.
TheModule = new Module("my cool jit", Context);
- ExistingModuleProvider *OurModuleProvider =
- new ExistingModuleProvider(TheModule);
-
- // Create the JIT. This takes ownership of the module and module provider.
- TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
+ // Create the JIT. This takes ownership of the module.
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
- FunctionPassManager OurFPM(OurModuleProvider);
+ FunctionPassManager OurFPM(TheModule);
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
diff --git a/examples/Kaleidoscope/Chapter5/Makefile b/examples/Kaleidoscope/Chapter5/Makefile
index 5a8355d..d1f5e20 100644
--- a/examples/Kaleidoscope/Chapter5/Makefile
+++ b/examples/Kaleidoscope/Chapter5/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../..
TOOLNAME = Kaleidoscope-Ch5
EXAMPLE_TOOL = 1
-LINK_COMPONENTS := core jit interpreter native
+LINK_COMPONENTS := core jit native
include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter5/toy.cpp b/examples/Kaleidoscope/Chapter5/toy.cpp
index c2613e3..da64b7e 100644
--- a/examples/Kaleidoscope/Chapter5/toy.cpp
+++ b/examples/Kaleidoscope/Chapter5/toy.cpp
@@ -1,10 +1,8 @@
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
@@ -818,13 +816,15 @@ int main() {
// Make the module, which holds all the code.
TheModule = new Module("my cool jit", Context);
- ExistingModuleProvider *OurModuleProvider =
- new ExistingModuleProvider(TheModule);
-
- // Create the JIT. This takes ownership of the module and module provider.
- TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
+ // Create the JIT. This takes ownership of the module.
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
- FunctionPassManager OurFPM(OurModuleProvider);
+ FunctionPassManager OurFPM(TheModule);
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
diff --git a/examples/Kaleidoscope/Chapter6/Makefile b/examples/Kaleidoscope/Chapter6/Makefile
index de2d758..a5fbcbd 100644
--- a/examples/Kaleidoscope/Chapter6/Makefile
+++ b/examples/Kaleidoscope/Chapter6/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../..
TOOLNAME = Kaleidoscope-Ch6
EXAMPLE_TOOL = 1
-LINK_COMPONENTS := core jit interpreter native
+LINK_COMPONENTS := core jit native
include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp
index 638a340..4e719e3 100644
--- a/examples/Kaleidoscope/Chapter6/toy.cpp
+++ b/examples/Kaleidoscope/Chapter6/toy.cpp
@@ -1,10 +1,8 @@
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
@@ -936,13 +934,15 @@ int main() {
// Make the module, which holds all the code.
TheModule = new Module("my cool jit", Context);
- ExistingModuleProvider *OurModuleProvider =
- new ExistingModuleProvider(TheModule);
-
- // Create the JIT. This takes ownership of the module and module provider.
- TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
+ // Create the JIT. This takes ownership of the module.
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
- FunctionPassManager OurFPM(OurModuleProvider);
+ FunctionPassManager OurFPM(TheModule);
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
diff --git a/examples/Kaleidoscope/Chapter7/Makefile b/examples/Kaleidoscope/Chapter7/Makefile
index 9d2df6f..6cec323 100644
--- a/examples/Kaleidoscope/Chapter7/Makefile
+++ b/examples/Kaleidoscope/Chapter7/Makefile
@@ -9,7 +9,8 @@
LEVEL = ../../..
TOOLNAME = Kaleidoscope-Ch7
EXAMPLE_TOOL = 1
+REQUIRES_RTTI := 1
-LINK_COMPONENTS := core jit interpreter native
+LINK_COMPONENTS := core jit native
include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter7/toy.cpp b/examples/Kaleidoscope/Chapter7/toy.cpp
index 8b0c321..7dd9eae 100644
--- a/examples/Kaleidoscope/Chapter7/toy.cpp
+++ b/examples/Kaleidoscope/Chapter7/toy.cpp
@@ -1,10 +1,8 @@
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
@@ -1100,13 +1098,15 @@ int main() {
// Make the module, which holds all the code.
TheModule = new Module("my cool jit", Context);
- ExistingModuleProvider *OurModuleProvider =
- new ExistingModuleProvider(TheModule);
-
- // Create the JIT. This takes ownership of the module and module provider.
- TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
+ // Create the JIT. This takes ownership of the module.
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
- FunctionPassManager OurFPM(OurModuleProvider);
+ FunctionPassManager OurFPM(TheModule);
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
diff --git a/examples/Makefile b/examples/Makefile
index eb5dabd..fc3a7d4 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -16,4 +16,8 @@ ifeq ($(HAVE_PTHREAD),1)
PARALLEL_DIRS += ParallelJIT
endif
+ifeq ($(LLVM_ON_UNIX),1)
+PARALLEL_DIRS += ExceptionDemo
+endif
+
include $(LEVEL)/Makefile.common
diff --git a/examples/ParallelJIT/ParallelJIT.cpp b/examples/ParallelJIT/ParallelJIT.cpp
index be40a28..9231abf 100644
--- a/examples/ParallelJIT/ParallelJIT.cpp
+++ b/examples/ParallelJIT/ParallelJIT.cpp
@@ -23,7 +23,6 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index d57c250..063ab91 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -78,8 +78,9 @@ typedef struct LLVMOpaqueValue *LLVMValueRef;
typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
-/* Used to provide a module to JIT or interpreter.
- * See the llvm::ModuleProvider class.
+/* Interface used to provide a module to JIT or interpreter. This is now just a
+ * synonym for llvm::Module, but we have to keep using the different type to
+ * keep binary compatibility.
*/
typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
@@ -117,63 +118,76 @@ typedef enum {
LLVMNoCaptureAttribute = 1<<21,
LLVMNoRedZoneAttribute = 1<<22,
LLVMNoImplicitFloatAttribute = 1<<23,
- LLVMNakedAttribute = 1<<24
+ LLVMNakedAttribute = 1<<24,
+ LLVMInlineHintAttribute = 1<<25
} LLVMAttribute;
typedef enum {
+ /* Terminator Instructions */
LLVMRet = 1,
LLVMBr = 2,
LLVMSwitch = 3,
- LLVMInvoke = 4,
- LLVMUnwind = 5,
- LLVMUnreachable = 6,
- LLVMAdd = 7,
- LLVMFAdd = 8,
- LLVMSub = 9,
- LLVMFSub = 10,
- LLVMMul = 11,
- LLVMFMul = 12,
- LLVMUDiv = 13,
- LLVMSDiv = 14,
- LLVMFDiv = 15,
- LLVMURem = 16,
- LLVMSRem = 17,
- LLVMFRem = 18,
- LLVMShl = 19,
- LLVMLShr = 20,
- LLVMAShr = 21,
- LLVMAnd = 22,
- LLVMOr = 23,
- LLVMXor = 24,
- LLVMMalloc = 25,
- LLVMFree = 26,
- LLVMAlloca = 27,
- LLVMLoad = 28,
- LLVMStore = 29,
- LLVMGetElementPtr = 30,
- LLVMTrunk = 31,
- LLVMZExt = 32,
- LLVMSExt = 33,
- LLVMFPToUI = 34,
- LLVMFPToSI = 35,
- LLVMUIToFP = 36,
- LLVMSIToFP = 37,
- LLVMFPTrunc = 38,
- LLVMFPExt = 39,
- LLVMPtrToInt = 40,
- LLVMIntToPtr = 41,
- LLVMBitCast = 42,
- LLVMICmp = 43,
- LLVMFCmp = 44,
- LLVMPHI = 45,
- LLVMCall = 46,
- LLVMSelect = 47,
- LLVMVAArg = 50,
- LLVMExtractElement = 51,
- LLVMInsertElement = 52,
- LLVMShuffleVector = 53,
- LLVMExtractValue = 54,
- LLVMInsertValue = 55
+ LLVMIndirectBr = 4,
+ LLVMInvoke = 5,
+ LLVMUnwind = 6,
+ LLVMUnreachable = 7,
+
+ /* Standard Binary Operators */
+ LLVMAdd = 8,
+ LLVMFAdd = 9,
+ LLVMSub = 10,
+ LLVMFSub = 11,
+ LLVMMul = 12,
+ LLVMFMul = 13,
+ LLVMUDiv = 14,
+ LLVMSDiv = 15,
+ LLVMFDiv = 16,
+ LLVMURem = 17,
+ LLVMSRem = 18,
+ LLVMFRem = 19,
+
+ /* Logical Operators */
+ LLVMShl = 20,
+ LLVMLShr = 21,
+ LLVMAShr = 22,
+ LLVMAnd = 23,
+ LLVMOr = 24,
+ LLVMXor = 25,
+
+ /* Memory Operators */
+ LLVMAlloca = 26,
+ LLVMLoad = 27,
+ LLVMStore = 28,
+ LLVMGetElementPtr = 29,
+
+ /* Cast Operators */
+ LLVMTrunc = 30,
+ LLVMZExt = 31,
+ LLVMSExt = 32,
+ LLVMFPToUI = 33,
+ LLVMFPToSI = 34,
+ LLVMUIToFP = 35,
+ LLVMSIToFP = 36,
+ LLVMFPTrunc = 37,
+ LLVMFPExt = 38,
+ LLVMPtrToInt = 39,
+ LLVMIntToPtr = 40,
+ LLVMBitCast = 41,
+
+ /* Other Operators */
+ LLVMICmp = 42,
+ LLVMFCmp = 43,
+ LLVMPHI = 44,
+ LLVMCall = 45,
+ LLVMSelect = 46,
+ /* UserOp1 */
+ /* UserOp2 */
+ LLVMVAArg = 49,
+ LLVMExtractElement = 50,
+ LLVMInsertElement = 51,
+ LLVMShuffleVector = 52,
+ LLVMExtractValue = 53,
+ LLVMInsertValue = 54
} LLVMOpcode;
typedef enum {
@@ -191,7 +205,8 @@ typedef enum {
LLVMPointerTypeKind, /**< Pointers */
LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */
LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
- LLVMMetadataTypeKind /**< Metadata */
+ LLVMMetadataTypeKind, /**< Metadata */
+ LLVMUnionTypeKind /**< Unions */
} LLVMTypeKind;
typedef enum {
@@ -210,8 +225,7 @@ typedef enum {
LLVMDLLImportLinkage, /**< Function to be imported from DLL */
LLVMDLLExportLinkage, /**< Function to be accessible from DLL */
LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */
- LLVMGhostLinkage, /**< Stand-in functions for streaming fns from
- bitcode */
+ LLVMGhostLinkage, /**< Obsolete */
LLVMCommonLinkage, /**< Tentative definitions */
LLVMLinkerPrivateLinkage /**< Like Private, but linker removes. */
} LLVMLinkage;
@@ -371,6 +385,13 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy);
+/* Operations on union types */
+LLVMTypeRef LLVMUnionTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
+ unsigned ElementCount);
+LLVMTypeRef LLVMUnionType(LLVMTypeRef *ElementTypes, unsigned ElementCount);
+unsigned LLVMCountUnionElementTypes(LLVMTypeRef UnionTy);
+void LLVMGetUnionElementTypes(LLVMTypeRef UnionTy, LLVMTypeRef *Dest);
+
/* Operations on array, pointer, and vector types (sequence types) */
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace);
@@ -914,17 +935,15 @@ LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS,
/*===-- Module providers --------------------------------------------------===*/
-/* Encapsulates the module M in a module provider, taking ownership of the
- * module.
- * See the constructor llvm::ExistingModuleProvider::ExistingModuleProvider.
+/* Changes the type of M so it can be passed to FunctionPassManagers and the
+ * JIT. They take ModuleProviders for historical reasons.
*/
LLVMModuleProviderRef
LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M);
-/* Destroys the module provider MP as well as the contained module.
- * See the destructor llvm::ModuleProvider::~ModuleProvider.
+/* Destroys the module M.
*/
-void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP);
+void LLVMDisposeModuleProvider(LLVMModuleProviderRef M);
/*===-- Memory buffers ----------------------------------------------------===*/
@@ -981,7 +1000,6 @@ void LLVMDisposePassManager(LLVMPassManagerRef PM);
}
namespace llvm {
- class ModuleProvider;
class MemoryBuffer;
class PassManagerBase;
@@ -1018,11 +1036,16 @@ namespace llvm {
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef )
- DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ModuleProvider, LLVMModuleProviderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseIteratorRef )
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef )
+ /* LLVMModuleProviderRef exists for historical reasons, but now just holds a
+ * Module.
+ */
+ inline Module *unwrap(LLVMModuleProviderRef MP) {
+ return reinterpret_cast<Module*>(MP);
+ }
#undef DEFINE_STDCXX_CONVERSION_FUNCTIONS
#undef DEFINE_ISA_CONVERSION_FUNCTIONS
diff --git a/include/llvm-c/EnhancedDisassembly.h b/include/llvm-c/EnhancedDisassembly.h
new file mode 100644
index 0000000..9cd1e1f
--- /dev/null
+++ b/include/llvm-c/EnhancedDisassembly.h
@@ -0,0 +1,515 @@
+/*===-- llvm-c/EnhancedDisassembly.h - Disassembler C Interface ---*- C -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This header declares the C interface to EnhancedDisassembly.so, which *|
+|* implements a disassembler with the ability to extract operand values and *|
+|* individual tokens from assembly instructions. *|
+|* *|
+|* The header declares additional interfaces if the host compiler supports *|
+|* the blocks API. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_ENHANCEDDISASSEMBLY_H
+#define LLVM_C_ENHANCEDDISASSEMBLY_H
+
+#include "llvm/System/DataTypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ @typedef EDByteReaderCallback
+ Interface to memory from which instructions may be read.
+ @param byte A pointer whose target should be filled in with the data returned.
+ @param address The address of the byte to be read.
+ @param arg An anonymous argument for client use.
+ @result 0 on success; -1 otherwise.
+ */
+typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg);
+
+/*!
+ @typedef EDRegisterReaderCallback
+ Interface to registers from which registers may be read.
+ @param value A pointer whose target should be filled in with the value of the
+ register.
+ @param regID The LLVM register identifier for the register to read.
+ @param arg An anonymous argument for client use.
+ @result 0 if the register could be read; -1 otherwise.
+ */
+typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
+ void* arg);
+
+/*!
+ @typedef EDAssemblySyntax_t
+ An assembly syntax for use in tokenizing instructions.
+ */
+typedef enum {
+/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
+ kEDAssemblySyntaxX86Intel = 0,
+/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
+ kEDAssemblySyntaxX86ATT = 1
+} EDAssemblySyntax_t;
+
+/*!
+ @typedef EDDisassemblerRef
+ Encapsulates a disassembler for a single CPU architecture.
+ */
+struct EDDisassembler;
+typedef struct EDDisassembler *EDDisassemblerRef;
+
+/*!
+ @typedef EDInstRef
+ Encapsulates a single disassembled instruction in one assembly syntax.
+ */
+struct EDInst;
+typedef struct EDInst *EDInstRef;
+
+/*!
+ @typedef EDTokenRef
+ Encapsulates a token from the disassembly of an instruction.
+ */
+struct EDToken;
+typedef struct EDToken *EDTokenRef;
+
+/*!
+ @typedef EDOperandRef
+ Encapsulates an operand of an instruction.
+ */
+struct EDOperand;
+typedef struct EDOperand *EDOperandRef;
+
+/*!
+ @functiongroup Getting a disassembler
+ */
+
+/*!
+ @function EDGetDisassembler
+ Gets the disassembler for a given target.
+ @param disassembler A pointer whose target will be filled in with the
+ disassembler.
+ @param triple Identifies the target. Example: "x86_64-apple-darwin10"
+ @param syntax The assembly syntax to use when decoding instructions.
+ @result 0 on success; -1 otherwise.
+ */
+int EDGetDisassembler(EDDisassemblerRef *disassembler,
+ const char *triple,
+ EDAssemblySyntax_t syntax);
+
+/*!
+ @functiongroup Generic architectural queries
+ */
+
+/*!
+ @function EDGetRegisterName
+ Gets the human-readable name for a given register.
+ @param regName A pointer whose target will be pointed at the name of the
+ register. The name does not need to be deallocated and will be
+ @param disassembler The disassembler to query for the name.
+ @param regID The register identifier, as returned by EDRegisterTokenValue.
+ @result 0 on success; -1 otherwise.
+ */
+int EDGetRegisterName(const char** regName,
+ EDDisassemblerRef disassembler,
+ unsigned regID);
+
+/*!
+ @function EDRegisterIsStackPointer
+ Determines if a register is one of the platform's stack-pointer registers.
+ @param disassembler The disassembler to query.
+ @param regID The register identifier, as returned by EDRegisterTokenValue.
+ @result 1 if true; 0 otherwise.
+ */
+int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
+ unsigned regID);
+
+/*!
+ @function EDRegisterIsProgramCounter
+ Determines if a register is one of the platform's stack-pointer registers.
+ @param disassembler The disassembler to query.
+ @param regID The register identifier, as returned by EDRegisterTokenValue.
+ @result 1 if true; 0 otherwise.
+ */
+int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
+ unsigned regID);
+
+/*!
+ @functiongroup Creating and querying instructions
+ */
+
+/*!
+ @function EDCreateInst
+ Gets a set of contiguous instructions from a disassembler.
+ @param insts A pointer to an array that will be filled in with the
+ instructions. Must have at least count entries. Entries not filled in will
+ be set to NULL.
+ @param count The maximum number of instructions to fill in.
+ @param disassembler The disassembler to use when decoding the instructions.
+ @param byteReader The function to use when reading the instruction's machine
+ code.
+ @param address The address of the first byte of the instruction.
+ @param arg An anonymous argument to be passed to byteReader.
+ @result The number of instructions read on success; 0 otherwise.
+ */
+unsigned int EDCreateInsts(EDInstRef *insts,
+ unsigned int count,
+ EDDisassemblerRef disassembler,
+ EDByteReaderCallback byteReader,
+ uint64_t address,
+ void *arg);
+
+/*!
+ @function EDReleaseInst
+ Frees the memory for an instruction. The instruction can no longer be accessed
+ after this call.
+ @param inst The instruction to be freed.
+ */
+void EDReleaseInst(EDInstRef inst);
+
+/*!
+ @function EDInstByteSize
+ @param inst The instruction to be queried.
+ @result The number of bytes in the instruction's machine-code representation.
+ */
+int EDInstByteSize(EDInstRef inst);
+
+/*!
+ @function EDGetInstString
+ Gets the disassembled text equivalent of the instruction.
+ @param buf A pointer whose target will be filled in with a pointer to the
+ string. (The string becomes invalid when the instruction is released.)
+ @param inst The instruction to be queried.
+ @result 0 on success; -1 otherwise.
+ */
+int EDGetInstString(const char **buf,
+ EDInstRef inst);
+
+/*!
+ @function EDInstID
+ @param instID A pointer whose target will be filled in with the LLVM identifier
+ for the instruction.
+ @param inst The instruction to be queried.
+ @result 0 on success; -1 otherwise.
+ */
+int EDInstID(unsigned *instID, EDInstRef inst);
+
+/*!
+ @function EDInstIsBranch
+ @param inst The instruction to be queried.
+ @result 1 if the instruction is a branch instruction; 0 if it is some other
+ type of instruction; -1 if there was an error.
+ */
+int EDInstIsBranch(EDInstRef inst);
+
+/*!
+ @function EDInstIsMove
+ @param inst The instruction to be queried.
+ @result 1 if the instruction is a move instruction; 0 if it is some other
+ type of instruction; -1 if there was an error.
+ */
+int EDInstIsMove(EDInstRef inst);
+
+/*!
+ @function EDBranchTargetID
+ @param inst The instruction to be queried.
+ @result The ID of the branch target operand, suitable for use with
+ EDCopyOperand. -1 if no such operand exists.
+ */
+int EDBranchTargetID(EDInstRef inst);
+
+/*!
+ @function EDMoveSourceID
+ @param inst The instruction to be queried.
+ @result The ID of the move source operand, suitable for use with
+ EDCopyOperand. -1 if no such operand exists.
+ */
+int EDMoveSourceID(EDInstRef inst);
+
+/*!
+ @function EDMoveTargetID
+ @param inst The instruction to be queried.
+ @result The ID of the move source operand, suitable for use with
+ EDCopyOperand. -1 if no such operand exists.
+ */
+int EDMoveTargetID(EDInstRef inst);
+
+/*!
+ @functiongroup Creating and querying tokens
+ */
+
+/*!
+ @function EDNumTokens
+ @param inst The instruction to be queried.
+ @result The number of tokens in the instruction, or -1 on error.
+ */
+int EDNumTokens(EDInstRef inst);
+
+/*!
+ @function EDGetToken
+ Retrieves a token from an instruction. The token is valid until the
+ instruction is released.
+ @param token A pointer to be filled in with the token.
+ @param inst The instruction to be queried.
+ @param index The index of the token in the instruction.
+ @result 0 on success; -1 otherwise.
+ */
+int EDGetToken(EDTokenRef *token,
+ EDInstRef inst,
+ int index);
+
+/*!
+ @function EDGetTokenString
+ Gets the disassembled text for a token.
+ @param buf A pointer whose target will be filled in with a pointer to the
+ string. (The string becomes invalid when the token is released.)
+ @param token The token to be queried.
+ @result 0 on success; -1 otherwise.
+ */
+int EDGetTokenString(const char **buf,
+ EDTokenRef token);
+
+/*!
+ @function EDOperandIndexForToken
+ Returns the index of the operand to which a token belongs.
+ @param token The token to be queried.
+ @result The operand index on success; -1 otherwise
+ */
+int EDOperandIndexForToken(EDTokenRef token);
+
+/*!
+ @function EDTokenIsWhitespace
+ @param token The token to be queried.
+ @result 1 if the token is whitespace; 0 if not; -1 on error.
+ */
+int EDTokenIsWhitespace(EDTokenRef token);
+
+/*!
+ @function EDTokenIsPunctuation
+ @param token The token to be queried.
+ @result 1 if the token is punctuation; 0 if not; -1 on error.
+ */
+int EDTokenIsPunctuation(EDTokenRef token);
+
+/*!
+ @function EDTokenIsOpcode
+ @param token The token to be queried.
+ @result 1 if the token is opcode; 0 if not; -1 on error.
+ */
+int EDTokenIsOpcode(EDTokenRef token);
+
+/*!
+ @function EDTokenIsLiteral
+ @param token The token to be queried.
+ @result 1 if the token is a numeric literal; 0 if not; -1 on error.
+ */
+int EDTokenIsLiteral(EDTokenRef token);
+
+/*!
+ @function EDTokenIsRegister
+ @param token The token to be queried.
+ @result 1 if the token identifies a register; 0 if not; -1 on error.
+ */
+int EDTokenIsRegister(EDTokenRef token);
+
+/*!
+ @function EDTokenIsNegativeLiteral
+ @param token The token to be queried.
+ @result 1 if the token is a negative signed literal; 0 if not; -1 on error.
+ */
+int EDTokenIsNegativeLiteral(EDTokenRef token);
+
+/*!
+ @function EDLiteralTokenAbsoluteValue
+ @param value A pointer whose target will be filled in with the absolute value
+ of the literal.
+ @param token The token to be queried.
+ @result 0 on success; -1 otherwise.
+ */
+int EDLiteralTokenAbsoluteValue(uint64_t *value,
+ EDTokenRef token);
+
+/*!
+ @function EDRegisterTokenValue
+ @param registerID A pointer whose target will be filled in with the LLVM
+ register identifier for the token.
+ @param token The token to be queried.
+ @result 0 on success; -1 otherwise.
+ */
+int EDRegisterTokenValue(unsigned *registerID,
+ EDTokenRef token);
+
+/*!
+ @functiongroup Creating and querying operands
+ */
+
+/*!
+ @function EDNumOperands
+ @param inst The instruction to be queried.
+ @result The number of operands in the instruction, or -1 on error.
+ */
+int EDNumOperands(EDInstRef inst);
+
+/*!
+ @function EDGetOperand
+ Retrieves an operand from an instruction. The operand is valid until the
+ instruction is released.
+ @param operand A pointer to be filled in with the operand.
+ @param inst The instruction to be queried.
+ @param index The index of the operand in the instruction.
+ @result 0 on success; -1 otherwise.
+ */
+int EDGetOperand(EDOperandRef *operand,
+ EDInstRef inst,
+ int index);
+
+/*!
+ @function EDOperandIsRegister
+ @param operand The operand to be queried.
+ @result 1 if the operand names a register; 0 if not; -1 on error.
+ */
+int EDOperandIsRegister(EDOperandRef operand);
+
+/*!
+ @function EDOperandIsImmediate
+ @param operand The operand to be queried.
+ @result 1 if the operand specifies an immediate value; 0 if not; -1 on error.
+ */
+int EDOperandIsImmediate(EDOperandRef operand);
+
+/*!
+ @function EDOperandIsMemory
+ @param operand The operand to be queried.
+ @result 1 if the operand specifies a location in memory; 0 if not; -1 on error.
+ */
+int EDOperandIsMemory(EDOperandRef operand);
+
+/*!
+ @function EDRegisterOperandValue
+ @param value A pointer whose target will be filled in with the LLVM register ID
+ of the register named by the operand.
+ @param operand The operand to be queried.
+ @result 0 on success; -1 otherwise.
+ */
+int EDRegisterOperandValue(unsigned *value,
+ EDOperandRef operand);
+
+/*!
+ @function EDImmediateOperandValue
+ @param value A pointer whose target will be filled in with the value of the
+ immediate.
+ @param operand The operand to be queried.
+ @result 0 on success; -1 otherwise.
+ */
+int EDImmediateOperandValue(uint64_t *value,
+ EDOperandRef operand);
+
+/*!
+ @function EDEvaluateOperand
+ Evaluates an operand using a client-supplied register state accessor. Register
+ operands are evaluated by reading the value of the register; immediate operands
+ are evaluated by reporting the immediate value; memory operands are evaluated
+ by computing the target address (with only those relocations applied that were
+ already applied to the original bytes).
+ @param result A pointer whose target is to be filled with the result of
+ evaluating the operand.
+ @param operand The operand to be evaluated.
+ @param regReader The function to use when reading registers from the register
+ state.
+ @param arg An anonymous argument for client use.
+ @result 0 if the operand could be evaluated; -1 otherwise.
+ */
+int EDEvaluateOperand(uint64_t *result,
+ EDOperandRef operand,
+ EDRegisterReaderCallback regReader,
+ void *arg);
+
+#ifdef __BLOCKS__
+
+/*!
+ @typedef EDByteBlock_t
+ Block-based interface to memory from which instructions may be read.
+ @param byte A pointer whose target should be filled in with the data returned.
+ @param address The address of the byte to be read.
+ @result 0 on success; -1 otherwise.
+ */
+typedef int (^EDByteBlock_t)(uint8_t *byte, uint64_t address);
+
+/*!
+ @typedef EDRegisterBlock_t
+ Block-based interface to registers from which registers may be read.
+ @param value A pointer whose target should be filled in with the value of the
+ register.
+ @param regID The LLVM register identifier for the register to read.
+ @result 0 if the register could be read; -1 otherwise.
+ */
+typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID);
+
+/*!
+ @typedef EDTokenVisitor_t
+ Block-based handler for individual tokens.
+ @param token The current token being read.
+ @result 0 to continue; 1 to stop normally; -1 on error.
+ */
+typedef int (^EDTokenVisitor_t)(EDTokenRef token);
+
+/*! @functiongroup Block-based interfaces */
+
+/*!
+ @function EDBlockCreateInsts
+ Gets a set of contiguous instructions from a disassembler, using a block to
+ read memory.
+ @param insts A pointer to an array that will be filled in with the
+ instructions. Must have at least count entries. Entries not filled in will
+ be set to NULL.
+ @param count The maximum number of instructions to fill in.
+ @param disassembler The disassembler to use when decoding the instructions.
+ @param byteBlock The block to use when reading the instruction's machine
+ code.
+ @param address The address of the first byte of the instruction.
+ @result The number of instructions read on success; 0 otherwise.
+ */
+unsigned int EDBlockCreateInsts(EDInstRef *insts,
+ int count,
+ EDDisassemblerRef disassembler,
+ EDByteBlock_t byteBlock,
+ uint64_t address);
+
+/*!
+ @function EDBlockEvaluateOperand
+ Evaluates an operand using a block to read registers.
+ @param result A pointer whose target is to be filled with the result of
+ evaluating the operand.
+ @param operand The operand to be evaluated.
+ @param regBlock The block to use when reading registers from the register
+ state.
+ @result 0 if the operand could be evaluated; -1 otherwise.
+ */
+int EDBlockEvaluateOperand(uint64_t *result,
+ EDOperandRef operand,
+ EDRegisterBlock_t regBlock);
+
+/*!
+ @function EDBlockVisitTokens
+ Visits every token with a visitor.
+ @param inst The instruction with the tokens to be visited.
+ @param visitor The visitor.
+ @result 0 if the visit ended normally; -1 if the visitor encountered an error
+ or there was some other error.
+ */
+int EDBlockVisitTokens(EDInstRef inst,
+ EDTokenVisitor_t visitor);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index 45108c8..b9f2d83 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -307,15 +307,17 @@ public:
}
BitVector &operator|=(const BitVector &RHS) {
- assert(Size == RHS.Size && "Illegal operation!");
- for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (size() < RHS.size())
+ resize(RHS.size());
+ for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
Bits[i] |= RHS.Bits[i];
return *this;
}
BitVector &operator^=(const BitVector &RHS) {
- assert(Size == RHS.Size && "Illegal operation!");
- for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (size() < RHS.size())
+ resize(RHS.size());
+ for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
Bits[i] ^= RHS.Bits[i];
return *this;
}
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 8b161ea..7350906 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -359,7 +359,7 @@ private:
BucketT *OldBuckets = Buckets;
// Double the number of buckets.
- while (NumBuckets <= AtLeast)
+ while (NumBuckets < AtLeast)
NumBuckets <<= 1;
NumTombstones = 0;
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
index 89f55ca..0898b96 100644
--- a/include/llvm/ADT/DenseSet.h
+++ b/include/llvm/ADT/DenseSet.h
@@ -41,8 +41,8 @@ public:
return TheMap.count(V);
}
- void erase(const ValueT &V) {
- TheMap.erase(V);
+ bool erase(const ValueT &V) {
+ return TheMap.erase(V);
}
DenseSet &operator=(const DenseSet &RHS) {
diff --git a/include/llvm/ADT/ImmutableIntervalMap.h b/include/llvm/ADT/ImmutableIntervalMap.h
new file mode 100644
index 0000000..f33fb1e
--- /dev/null
+++ b/include/llvm/ADT/ImmutableIntervalMap.h
@@ -0,0 +1,238 @@
+//===--- ImmutableIntervalMap.h - Immutable (functional) map ---*- 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 ImmutableIntervalMap class.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/ADT/ImmutableMap.h"
+
+namespace llvm {
+
+class Interval {
+private:
+ uint64_t Start;
+ uint64_t End;
+
+public:
+ Interval(uint64_t S, uint64_t E) : Start(S), End(E) {}
+
+ uint64_t getStart() const { return Start; }
+ uint64_t getEnd() const { return End; }
+};
+
+template <typename T>
+struct ImutIntervalInfo {
+ typedef const std::pair<Interval, T> value_type;
+ typedef const value_type &value_type_ref;
+ typedef const Interval key_type;
+ typedef const Interval &key_type_ref;
+ typedef const T data_type;
+ typedef const T &data_type_ref;
+
+ static key_type_ref KeyOfValue(value_type_ref V) {
+ return V.first;
+ }
+
+ static data_type_ref DataOfValue(value_type_ref V) {
+ return V.second;
+ }
+
+ static bool isEqual(key_type_ref L, key_type_ref R) {
+ return L.getStart() == R.getStart() && L.getEnd() == R.getEnd();
+ }
+
+ static bool isDataEqual(data_type_ref L, data_type_ref R) {
+ return ImutContainerInfo<T>::isEqual(L,R);
+ }
+
+ static bool isLess(key_type_ref L, key_type_ref R) {
+ // Assume L and R does not overlap.
+ if (L.getStart() < R.getStart()) {
+ assert(L.getEnd() < R.getStart());
+ return true;
+ } else if (L.getStart() == R.getStart()) {
+ assert(L.getEnd() == R.getEnd());
+ return false;
+ } else {
+ assert(L.getStart() > R.getEnd());
+ return false;
+ }
+ }
+
+ static bool isContainedIn(key_type_ref K, key_type_ref L) {
+ if (K.getStart() >= L.getStart() && K.getEnd() <= L.getEnd())
+ return true;
+ else
+ return false;
+ }
+
+ static void Profile(FoldingSetNodeID &ID, value_type_ref V) {
+ ID.AddInteger(V.first.getStart());
+ ID.AddInteger(V.first.getEnd());
+ ImutProfileInfo<T>::Profile(ID, V.second);
+ }
+};
+
+template <typename ImutInfo>
+class ImutIntervalAVLFactory : public ImutAVLFactory<ImutInfo> {
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef typename ImutInfo::value_type value_type;
+ typedef typename ImutInfo::value_type_ref value_type_ref;
+ typedef typename ImutInfo::key_type key_type;
+ typedef typename ImutInfo::key_type_ref key_type_ref;
+ typedef typename ImutInfo::data_type data_type;
+ typedef typename ImutInfo::data_type_ref data_type_ref;
+
+public:
+ ImutIntervalAVLFactory(BumpPtrAllocator &Alloc)
+ : ImutAVLFactory<ImutInfo>(Alloc) {}
+
+ TreeTy *Add(TreeTy *T, value_type_ref V) {
+ T = Add_internal(V,T);
+ this->MarkImmutable(T);
+ return T;
+ }
+
+ TreeTy *Find(TreeTy *T, key_type_ref K) {
+ if (!T)
+ return NULL;
+
+ key_type_ref CurrentKey = ImutInfo::KeyOfValue(this->Value(T));
+
+ if (ImutInfo::isContainedIn(K, CurrentKey))
+ return T;
+ else if (ImutInfo::isLess(K, CurrentKey))
+ return Find(this->Left(T), K);
+ else
+ return Find(this->Right(T), K);
+ }
+
+private:
+ TreeTy *Add_internal(value_type_ref V, TreeTy *T) {
+ key_type_ref K = ImutInfo::KeyOfValue(V);
+ T = RemoveAllOverlaps(T, K);
+ if (this->isEmpty(T))
+ return this->CreateNode(NULL, V, NULL);
+
+ assert(!T->isMutable());
+
+ key_type_ref KCurrent = ImutInfo::KeyOfValue(this->Value(T));
+
+ if (ImutInfo::isLess(K, KCurrent))
+ return this->Balance(Add_internal(V, this->Left(T)), this->Value(T), this->Right(T));
+ else
+ return this->Balance(this->Left(T), this->Value(T), Add_internal(V, this->Right(T)));
+ }
+
+ // Remove all overlaps from T.
+ TreeTy *RemoveAllOverlaps(TreeTy *T, key_type_ref K) {
+ bool Changed;
+ do {
+ Changed = false;
+ T = RemoveOverlap(T, K, Changed);
+ this->MarkImmutable(T);
+ } while (Changed);
+
+ return T;
+ }
+
+ // Remove one overlap from T.
+ TreeTy *RemoveOverlap(TreeTy *T, key_type_ref K, bool &Changed) {
+ if (!T)
+ return NULL;
+ Interval CurrentK = ImutInfo::KeyOfValue(this->Value(T));
+
+ // If current key does not overlap the inserted key.
+ if (CurrentK.getStart() > K.getEnd())
+ return this->Balance(RemoveOverlap(this->Left(T), K, Changed), this->Value(T), this->Right(T));
+ else if (CurrentK.getEnd() < K.getStart())
+ return this->Balance(this->Left(T), this->Value(T), RemoveOverlap(this->Right(T), K, Changed));
+
+ // Current key overlaps with the inserted key.
+ // Remove the current key.
+ Changed = true;
+ data_type_ref OldData = ImutInfo::DataOfValue(this->Value(T));
+ T = this->Remove_internal(CurrentK, T);
+ // Add back the unoverlapped part of the current key.
+ if (CurrentK.getStart() < K.getStart()) {
+ if (CurrentK.getEnd() <= K.getEnd()) {
+ Interval NewK(CurrentK.getStart(), K.getStart()-1);
+ return Add_internal(std::make_pair(NewK, OldData), T);
+ } else {
+ Interval NewK1(CurrentK.getStart(), K.getStart()-1);
+ T = Add_internal(std::make_pair(NewK1, OldData), T);
+
+ Interval NewK2(K.getEnd()+1, CurrentK.getEnd());
+ return Add_internal(std::make_pair(NewK2, OldData), T);
+ }
+ } else {
+ if (CurrentK.getEnd() > K.getEnd()) {
+ Interval NewK(K.getEnd()+1, CurrentK.getEnd());
+ return Add_internal(std::make_pair(NewK, OldData), T);
+ } else
+ return T;
+ }
+ }
+};
+
+/// ImmutableIntervalMap maps an interval [start, end] to a value. The intervals
+/// in the map are guaranteed to be disjoint.
+template <typename ValT>
+class ImmutableIntervalMap
+ : public ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> > {
+
+ typedef typename ImutIntervalInfo<ValT>::value_type value_type;
+ typedef typename ImutIntervalInfo<ValT>::value_type_ref value_type_ref;
+ typedef typename ImutIntervalInfo<ValT>::key_type key_type;
+ typedef typename ImutIntervalInfo<ValT>::key_type_ref key_type_ref;
+ typedef typename ImutIntervalInfo<ValT>::data_type data_type;
+ typedef typename ImutIntervalInfo<ValT>::data_type_ref data_type_ref;
+ typedef ImutAVLTree<ImutIntervalInfo<ValT> > TreeTy;
+
+public:
+ explicit ImmutableIntervalMap(TreeTy *R)
+ : ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> >(R) {}
+
+ class Factory {
+ ImutIntervalAVLFactory<ImutIntervalInfo<ValT> > F;
+
+ public:
+ Factory(BumpPtrAllocator& Alloc) : F(Alloc) {}
+
+ ImmutableIntervalMap GetEmptyMap() {
+ return ImmutableIntervalMap(F.GetEmptyTree());
+ }
+
+ ImmutableIntervalMap Add(ImmutableIntervalMap Old,
+ key_type_ref K, data_type_ref D) {
+ TreeTy *T = F.Add(Old.Root, std::make_pair<key_type, data_type>(K, D));
+ return ImmutableIntervalMap(F.GetCanonicalTree(T));
+ }
+
+ ImmutableIntervalMap Remove(ImmutableIntervalMap Old, key_type_ref K) {
+ TreeTy *T = F.Remove(Old.Root, K);
+ return ImmutableIntervalMap(F.GetCanonicalTree(T));
+ }
+
+ data_type *Lookup(ImmutableIntervalMap M, key_type_ref K) {
+ TreeTy *T = F.Find(M.getRoot(), K);
+ if (T)
+ return &T->getValue().second;
+ else
+ return 0;
+ }
+ };
+
+private:
+ // For ImmutableIntervalMap, the lookup operation has to be done by the
+ // factory.
+ data_type* lookup(key_type_ref K) const;
+};
+
+} // end namespace llvm
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
index 1b3f1a9..8af128e 100644
--- a/include/llvm/ADT/ImmutableMap.h
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -68,7 +68,7 @@ public:
typedef typename ValInfo::data_type_ref data_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy;
-private:
+protected:
TreeTy* Root;
public:
@@ -106,13 +106,10 @@ public:
void operator=(const Factory& RHS); // DO NOT IMPLEMENT
};
- friend class Factory;
-
bool contains(key_type_ref K) const {
return Root ? Root->contains(K) : false;
}
-
bool operator==(ImmutableMap RHS) const {
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
}
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
index ac06a40..65e70e2 100644
--- a/include/llvm/ADT/ImmutableSet.h
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -27,6 +27,7 @@ namespace llvm {
//===----------------------------------------------------------------------===//
template <typename ImutInfo> class ImutAVLFactory;
+template <typename ImutInfo> class ImutIntervalAVLFactory;
template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
template <typename ImutInfo> class ImutAVLTreeGenericIterator;
@@ -39,6 +40,7 @@ public:
typedef ImutAVLFactory<ImutInfo> Factory;
friend class ImutAVLFactory<ImutInfo>;
+ friend class ImutIntervalAVLFactory<ImutInfo>;
friend class ImutAVLTreeGenericIterator<ImutInfo>;
friend class FoldingSet<ImutAVLTree>;
@@ -389,7 +391,7 @@ public:
// These have succinct names so that the balancing code
// is as terse (and readable) as possible.
//===--------------------------------------------------===//
-private:
+protected:
bool isEmpty(TreeTy* T) const { return !T; }
unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; }
@@ -581,25 +583,14 @@ public:
continue;
// We found a collision. Perform a comparison of Contents('T')
- // with Contents('L')+'V'+Contents('R').
+ // with Contents('TNew')
typename TreeTy::iterator TI = T->begin(), TE = T->end();
- // First compare Contents('L') with the (initial) contents of T.
- if (!CompareTreeWithSection(TNew->getLeft(), TI, TE))
- continue;
-
- // Now compare the new data element.
- if (TI == TE || !TI->ElementEqual(TNew->getValue()))
- continue;
-
- ++TI;
-
- // Now compare the remainder of 'T' with 'R'.
- if (!CompareTreeWithSection(TNew->getRight(), TI, TE))
+ if (!CompareTreeWithSection(TNew, TI, TE))
continue;
if (TI != TE)
- continue; // Contents('R') did not match suffix of 'T'.
+ continue; // T has more contents than TNew.
// Trees did match! Return 'T'.
return T;
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index 346fb1c..5c774b9 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -310,11 +310,47 @@ public:
}
// Intersection, union, disjoint union.
- BitVector &operator&=(const SmallBitVector &RHS); // TODO: implement
+ SmallBitVector &operator&=(const SmallBitVector &RHS) {
+ resize(std::max(size(), RHS.size()));
+ if (isSmall())
+ setSmallBits(getSmallBits() & RHS.getSmallBits());
+ else if (!RHS.isSmall())
+ X.getPointer()->operator&=(*RHS.X.getPointer());
+ else {
+ SmallBitVector Copy = RHS;
+ Copy.resize(size());
+ X.getPointer()->operator&=(*Copy.X.getPointer());
+ }
+ return *this;
+ }
- BitVector &operator|=(const SmallBitVector &RHS); // TODO: implement
+ SmallBitVector &operator|=(const SmallBitVector &RHS) {
+ resize(std::max(size(), RHS.size()));
+ if (isSmall())
+ setSmallBits(getSmallBits() | RHS.getSmallBits());
+ else if (!RHS.isSmall())
+ X.getPointer()->operator|=(*RHS.X.getPointer());
+ else {
+ SmallBitVector Copy = RHS;
+ Copy.resize(size());
+ X.getPointer()->operator|=(*Copy.X.getPointer());
+ }
+ return *this;
+ }
- BitVector &operator^=(const SmallBitVector &RHS); // TODO: implement
+ SmallBitVector &operator^=(const SmallBitVector &RHS) {
+ resize(std::max(size(), RHS.size()));
+ if (isSmall())
+ setSmallBits(getSmallBits() ^ RHS.getSmallBits());
+ else if (!RHS.isSmall())
+ X.getPointer()->operator^=(*RHS.X.getPointer());
+ else {
+ SmallBitVector Copy = RHS;
+ Copy.resize(size());
+ X.getPointer()->operator^=(*Copy.X.getPointer());
+ }
+ return *this;
+ }
// Assignment operator.
const SmallBitVector &operator=(const SmallBitVector &RHS) {
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index c29fc9f..ef08125 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -225,7 +225,7 @@ struct NextPowerOfTwo {
};
-/// SmallPtrSet - This class implements a set which is optimizer for holding
+/// SmallPtrSet - This class implements a set which is optimized for holding
/// SmallSize or less elements. This internally rounds up SmallSize to the next
/// power of two if it is not already a power of two. See the comments above
/// SmallPtrSetImpl for details of the algorithm.
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index fe39324..8798b0e 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -66,6 +66,7 @@ public:
ppc, // PPC: powerpc
ppc64, // PPC64: powerpc64, ppu
sparc, // Sparc: sparc
+ sparcv9, // Sparcv9: Sparcv9
systemz, // SystemZ: s390x
tce, // TCE (http://tce.cs.tut.fi/): tce
thumb, // Thumb: thumb, thumbv.*
diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h
index 06951c7..e2675eb 100644
--- a/include/llvm/Analysis/ConstantFolding.h
+++ b/include/llvm/Analysis/ConstantFolding.h
@@ -37,7 +37,7 @@ Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0);
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
/// using the specified TargetData. If successful, the constant result is
/// result is returned, if not, null is returned.
-Constant *ConstantFoldConstantExpression(ConstantExpr *CE,
+Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
const TargetData *TD = 0);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h
index 150d3ee..ccf0105 100644
--- a/include/llvm/Analysis/DebugInfo.h
+++ b/include/llvm/Analysis/DebugInfo.h
@@ -193,7 +193,9 @@ namespace llvm {
FlagFwdDecl = 1 << 2,
FlagAppleBlock = 1 << 3,
FlagBlockByrefStruct = 1 << 4,
- FlagVirtual = 1 << 5
+ FlagVirtual = 1 << 5,
+ FlagArtificial = 1 << 6 // To identify artificial arguments in
+ // a subroutine type. e.g. "this" in c++.
};
protected:
@@ -241,6 +243,9 @@ namespace llvm {
bool isVirtual() const {
return (getFlags() & FlagVirtual) != 0;
}
+ bool isArtificial() const {
+ return (getFlags() & FlagArtificial) != 0;
+ }
/// dump - print type.
void dump() const;
@@ -298,6 +303,9 @@ namespace llvm {
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
unsigned getRunTimeLang() const { return getUnsignedField(11); }
+ DICompositeType getContainingType() const {
+ return getFieldAs<DICompositeType>(12);
+ }
/// Verify - Verify that a composite type descriptor is well formed.
bool Verify() const;
@@ -372,6 +380,7 @@ namespace llvm {
DICompositeType getContainingType() const {
return getFieldAs<DICompositeType>(13);
}
+ unsigned isArtificial() const { return getUnsignedField(14); }
StringRef getFilename() const { return getCompileUnit().getFilename();}
StringRef getDirectory() const { return getCompileUnit().getDirectory();}
@@ -567,7 +576,11 @@ namespace llvm {
uint64_t OffsetInBits, unsigned Flags,
DIType DerivedFrom,
DIArray Elements,
- unsigned RunTimeLang = 0);
+ unsigned RunTimeLang = 0,
+ MDNode *ContainingType = 0);
+
+ /// CreateArtificialType - Create a new DIType with "artificial" flag set.
+ DIType CreateArtificialType(DIType Ty);
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
@@ -591,7 +604,8 @@ namespace llvm {
bool isDefinition,
unsigned VK = 0,
unsigned VIndex = 0,
- DIType = DIType());
+ DIType = DIType(),
+ bool isArtificial = 0);
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
/// given declaration.
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index 50f7d45..e6e9c71 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -16,29 +16,27 @@
#define LLVM_ANALYSIS_IVUSERS_H
#include "llvm/Analysis/LoopPass.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/ADT/SmallVector.h"
-#include <map>
+#include "llvm/Support/ValueHandle.h"
namespace llvm {
class DominatorTree;
class Instruction;
class Value;
-struct IVUsersOfOneStride;
-
-/// IVStrideUse - Keep track of one use of a strided induction variable, where
-/// the stride is stored externally. The Offset member keeps track of the
-/// offset from the IV, User is the actual user of the operand, and
-/// 'OperandValToReplace' is the operand of the User that is the use.
+class IVUsers;
+class ScalarEvolution;
+class SCEV;
+
+/// IVStrideUse - Keep track of one use of a strided induction variable.
+/// The Expr member keeps track of the expression, User is the actual user
+/// instruction of the operand, and 'OperandValToReplace' is the operand of
+/// the User that is the use.
class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
public:
- IVStrideUse(IVUsersOfOneStride *parent,
- const SCEV *offset,
+ IVStrideUse(IVUsers *P, const SCEV *S, const SCEV *Off,
Instruction* U, Value *O)
- : CallbackVH(U), Parent(parent), Offset(offset),
- OperandValToReplace(O),
- IsUseOfPostIncrementedValue(false) {
+ : CallbackVH(U), Parent(P), Stride(S), Offset(Off),
+ OperandValToReplace(O), IsUseOfPostIncrementedValue(false) {
}
/// getUser - Return the user instruction for this use.
@@ -51,9 +49,17 @@ public:
setValPtr(NewUser);
}
- /// getParent - Return a pointer to the IVUsersOfOneStride that owns
+ /// getParent - Return a pointer to the IVUsers that owns
/// this IVStrideUse.
- IVUsersOfOneStride *getParent() const { return Parent; }
+ IVUsers *getParent() const { return Parent; }
+
+ /// getStride - Return the expression for the stride for the use.
+ const SCEV *getStride() const { return Stride; }
+
+ /// setStride - Assign a new stride to this use.
+ void setStride(const SCEV *Val) {
+ Stride = Val;
+ }
/// getOffset - Return the offset to add to a theoeretical induction
/// variable that starts at zero and counts up by the stride to compute
@@ -92,8 +98,11 @@ public:
}
private:
- /// Parent - a pointer to the IVUsersOfOneStride that owns this IVStrideUse.
- IVUsersOfOneStride *Parent;
+ /// Parent - a pointer to the IVUsers that owns this IVStrideUse.
+ IVUsers *Parent;
+
+ /// Stride - The stride for this use.
+ const SCEV *Stride;
/// Offset - The offset to add to the base induction expression.
const SCEV *Offset;
@@ -138,37 +147,8 @@ private:
mutable ilist_node<IVStrideUse> Sentinel;
};
-/// IVUsersOfOneStride - This structure keeps track of all instructions that
-/// have an operand that is based on the trip count multiplied by some stride.
-struct IVUsersOfOneStride : public ilist_node<IVUsersOfOneStride> {
-private:
- IVUsersOfOneStride(const IVUsersOfOneStride &I); // do not implement
- void operator=(const IVUsersOfOneStride &I); // do not implement
-
-public:
- IVUsersOfOneStride() : Stride(0) {}
-
- explicit IVUsersOfOneStride(const SCEV *stride) : Stride(stride) {}
-
- /// Stride - The stride for all the contained IVStrideUses. This is
- /// a constant for affine strides.
- const SCEV *Stride;
-
- /// Users - Keep track of all of the users of this stride as well as the
- /// initial value and the operand that uses the IV.
- ilist<IVStrideUse> Users;
-
- void addUser(const SCEV *Offset, Instruction *User, Value *Operand) {
- Users.push_back(new IVStrideUse(this, Offset, User, Operand));
- }
-
- void removeUser(IVStrideUse *User) {
- Users.erase(User);
- }
-};
-
class IVUsers : public LoopPass {
- friend class IVStrideUserVH;
+ friend class IVStrideUse;
Loop *L;
LoopInfo *LI;
DominatorTree *DT;
@@ -177,19 +157,8 @@ class IVUsers : public LoopPass {
/// IVUses - A list of all tracked IV uses of induction variable expressions
/// we are interested in.
- ilist<IVUsersOfOneStride> IVUses;
-
-public:
- /// IVUsesByStride - A mapping from the strides in StrideOrder to the
- /// uses in IVUses.
- std::map<const SCEV *, IVUsersOfOneStride*> IVUsesByStride;
+ ilist<IVStrideUse> IVUses;
- /// StrideOrder - An ordering of the keys in IVUsesByStride that is stable:
- /// We use this to iterate over the IVUsesByStride collection without being
- /// dependent on random ordering of pointers in the process.
- SmallVector<const SCEV *, 16> StrideOrder;
-
-private:
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
@@ -205,8 +174,8 @@ public:
/// return true. Otherwise, return false.
bool AddUsersIfInteresting(Instruction *I);
- void AddUser(const SCEV *Stride, const SCEV *Offset,
- Instruction *User, Value *Operand);
+ IVStrideUse &AddUser(const SCEV *Stride, const SCEV *Offset,
+ Instruction *User, Value *Operand);
/// getReplacementExpr - Return a SCEV expression which computes the
/// value of the OperandValToReplace of the given IVStrideUse.
@@ -217,6 +186,14 @@ public:
/// isUseOfPostIncrementedValue flag.
const SCEV *getCanonicalExpr(const IVStrideUse &U) const;
+ typedef ilist<IVStrideUse>::iterator iterator;
+ typedef ilist<IVStrideUse>::const_iterator const_iterator;
+ iterator begin() { return IVUses.begin(); }
+ iterator end() { return IVUses.end(); }
+ const_iterator begin() const { return IVUses.begin(); }
+ const_iterator end() const { return IVUses.end(); }
+ bool empty() const { return IVUses.empty(); }
+
void print(raw_ostream &OS, const Module* = 0) const;
/// dump - This method is used for debugging.
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
index 7ce49d7..84acd7d 100644
--- a/include/llvm/Analysis/InlineCost.h
+++ b/include/llvm/Analysis/InlineCost.h
@@ -34,7 +34,7 @@ namespace llvm {
/// NeverInline - True if this callee should never be inlined into a
/// caller.
bool NeverInline;
-
+
/// usesDynamicAlloca - True if this function calls alloca (in the C sense).
bool usesDynamicAlloca;
@@ -42,17 +42,20 @@ namespace llvm {
/// is used to estimate the code size cost of inlining it.
unsigned NumInsts, NumBlocks;
+ /// NumCalls - Keep track of the number of calls to 'big' functions.
+ unsigned NumCalls;
+
/// NumVectorInsts - Keep track of how many instructions produce vector
/// values. The inliner is being more aggressive with inlining vector
/// kernels.
unsigned NumVectorInsts;
-
+
/// NumRets - Keep track of how many Ret instructions the block contains.
unsigned NumRets;
CodeMetrics() : NeverInline(false), usesDynamicAlloca(false), NumInsts(0),
- NumBlocks(0), NumVectorInsts(0), NumRets(0) {}
-
+ NumBlocks(0), NumCalls(0), NumVectorInsts(0), NumRets(0) {}
+
/// analyzeBasicBlock - Add information about the specified basic block
/// to the current structure.
void analyzeBasicBlock(const BasicBlock *BB);
@@ -64,7 +67,9 @@ namespace llvm {
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
- const int CallPenalty = 5;
+ const int InstrCost = 5;
+ const int IndirectCallBonus = 500;
+ const int CallPenalty = 25;
const int LastCallToStaticBonus = -15000;
const int ColdccPenalty = 2000;
const int NoreturnPenalty = 10000;
@@ -119,18 +124,18 @@ namespace llvm {
return getCost();
}
};
-
+
/// InlineCostAnalyzer - Cost analyzer used by inliner.
class InlineCostAnalyzer {
struct ArgInfo {
public:
unsigned ConstantWeight;
unsigned AllocaWeight;
-
+
ArgInfo(unsigned CWeight, unsigned AWeight)
: ConstantWeight(CWeight), AllocaWeight(AWeight) {}
};
-
+
struct FunctionInfo {
CodeMetrics Metrics;
@@ -139,12 +144,12 @@ namespace llvm {
/// would reduce the code size. If so, we add some value to the argument
/// entry here.
std::vector<ArgInfo> ArgumentWeights;
-
+
/// CountCodeReductionForConstant - Figure out an approximation for how
/// many instructions will be constant folded if the specified value is
/// constant.
unsigned CountCodeReductionForConstant(Value *V);
-
+
/// CountCodeReductionForAlloca - Figure out an approximation of how much
/// smaller the function will be if it is inlined into a context where an
/// argument becomes an alloca.
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 33bf0b0..d5e4d51 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -553,6 +553,10 @@ public:
/// normal unsigned value, if possible. Returns 0 if the trip count is unknown
/// of not constant. Will also return 0 if the trip count is very large
/// (>= 2^32)
+ ///
+ /// The IndVarSimplify pass transforms loops to have a form that this
+ /// function easily understands.
+ ///
unsigned getSmallConstantTripCount() const;
/// getSmallConstantTripMultiple - Returns the largest constant divisor of the
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index f6fa0c8..a7f42c9 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -72,7 +72,7 @@ Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
// free Call Utility Functions.
//
-/// isFreeCall - Returns true if the the value is a call to the builtin free()
+/// isFreeCall - Returns true if the value is a call to the builtin free()
bool isFreeCall(const Value *I);
} // End llvm namespace
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index e281971..383ee88 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -452,11 +452,25 @@ namespace llvm {
const SCEV *getUMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
const SCEV *getSMinExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getUMinExpr(const SCEV *LHS, const SCEV *RHS);
- const SCEV *getFieldOffsetExpr(const StructType *STy, unsigned FieldNo);
- const SCEV *getAllocSizeExpr(const Type *AllocTy);
const SCEV *getUnknown(Value *V);
const SCEV *getCouldNotCompute();
+ /// getSizeOfExpr - Return an expression for sizeof on the given type.
+ ///
+ const SCEV *getSizeOfExpr(const Type *AllocTy);
+
+ /// getAlignOfExpr - Return an expression for alignof on the given type.
+ ///
+ const SCEV *getAlignOfExpr(const Type *AllocTy);
+
+ /// getOffsetOfExpr - Return an expression for offsetof on the given field.
+ ///
+ const SCEV *getOffsetOfExpr(const StructType *STy, unsigned FieldNo);
+
+ /// getOffsetOfExpr - Return an expression for offsetof on the given field.
+ ///
+ const SCEV *getOffsetOfExpr(const Type *CTy, Constant *FieldNo);
+
/// getNegativeSCEV - Return the SCEV object corresponding to -V.
///
const SCEV *getNegativeSCEV(const SCEV *V);
@@ -503,7 +517,7 @@ namespace llvm {
/// getIntegerSCEV - Given a SCEVable type, create a constant for the
/// specified signed integer value and return a SCEV for the constant.
- const SCEV *getIntegerSCEV(int Val, const Type *Ty);
+ const SCEV *getIntegerSCEV(int64_t Val, const Type *Ty);
/// getUMaxFromMismatchedTypes - Promote the operands to the wider of
/// the types using zero-extension, and then perform a umax operation
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index 01df503..26dc0c4 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -27,10 +27,7 @@ namespace llvm {
/// and destroy it when finished to allow the release of the associated
/// memory.
class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
- public:
ScalarEvolution &SE;
-
- private:
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
InsertedExpressions;
std::set<Value*> InsertedValues;
@@ -57,11 +54,11 @@ namespace llvm {
/// in a more literal form.
bool CanonicalMode;
- protected:
typedef IRBuilder<true, TargetFolder> BuilderType;
BuilderType Builder;
friend struct SCEVVisitor<SCEVExpander, Value*>;
+
public:
/// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
explicit SCEVExpander(ScalarEvolution &se)
@@ -167,17 +164,13 @@ namespace llvm {
Value *visitUMaxExpr(const SCEVUMaxExpr *S);
- Value *visitFieldOffsetExpr(const SCEVFieldOffsetExpr *S);
-
- Value *visitAllocSizeExpr(const SCEVAllocSizeExpr *S);
-
Value *visitUnknown(const SCEVUnknown *S) {
return S->getValue();
}
- void rememberInstruction(Value *I) {
- if (!PostIncLoop) InsertedValues.insert(I);
- }
+ void rememberInstruction(Value *I);
+
+ void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I);
Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index 64b8b0b..0ab3b3f 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -27,7 +27,7 @@ namespace llvm {
// folders simpler.
scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr,
- scFieldOffset, scAllocSize, scUnknown, scCouldNotCompute
+ scUnknown, scCouldNotCompute
};
//===--------------------------------------------------------------------===//
@@ -412,12 +412,15 @@ namespace llvm {
}
virtual bool hasComputableLoopEvolution(const Loop *QL) const {
- if (L == QL) return true;
- return false;
+ return L == QL;
}
virtual bool isLoopInvariant(const Loop *QueryLoop) const;
+ bool dominates(BasicBlock *BB, DominatorTree *DT) const;
+
+ bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
+
/// isAffine - Return true if this is an affine AddRec (i.e., it represents
/// an expressions A+B*x where A and B are loop invariant values.
bool isAffine() const {
@@ -512,95 +515,6 @@ namespace llvm {
};
//===--------------------------------------------------------------------===//
- /// SCEVTargetDataConstant - This node is the base class for representing
- /// target-dependent values in a target-independent way.
- ///
- class SCEVTargetDataConstant : public SCEV {
- protected:
- const Type *Ty;
- SCEVTargetDataConstant(const FoldingSetNodeID &ID, enum SCEVTypes T,
- const Type *ty) :
- SCEV(ID, T), Ty(ty) {}
-
- public:
- virtual bool isLoopInvariant(const Loop *) const { return true; }
- virtual bool hasComputableLoopEvolution(const Loop *) const {
- return false; // not computable
- }
-
- virtual bool hasOperand(const SCEV *) const {
- return false;
- }
-
- bool dominates(BasicBlock *, DominatorTree *) const {
- return true;
- }
-
- bool properlyDominates(BasicBlock *, DominatorTree *) const {
- return true;
- }
-
- virtual const Type *getType() const { return Ty; }
-
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVTargetDataConstant *S) { return true; }
- static inline bool classof(const SCEV *S) {
- return S->getSCEVType() == scFieldOffset ||
- S->getSCEVType() == scAllocSize;
- }
- };
-
- //===--------------------------------------------------------------------===//
- /// SCEVFieldOffsetExpr - This node represents an offsetof expression.
- ///
- class SCEVFieldOffsetExpr : public SCEVTargetDataConstant {
- friend class ScalarEvolution;
-
- const StructType *STy;
- unsigned FieldNo;
- SCEVFieldOffsetExpr(const FoldingSetNodeID &ID, const Type *ty,
- const StructType *sty, unsigned fieldno) :
- SCEVTargetDataConstant(ID, scFieldOffset, ty),
- STy(sty), FieldNo(fieldno) {}
-
- public:
- const StructType *getStructType() const { return STy; }
- unsigned getFieldNo() const { return FieldNo; }
-
- virtual void print(raw_ostream &OS) const;
-
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVFieldOffsetExpr *S) { return true; }
- static inline bool classof(const SCEV *S) {
- return S->getSCEVType() == scFieldOffset;
- }
- };
-
- //===--------------------------------------------------------------------===//
- /// SCEVAllocSize - This node represents a sizeof expression.
- ///
- class SCEVAllocSizeExpr : public SCEVTargetDataConstant {
- friend class ScalarEvolution;
-
- const Type *AllocTy;
- SCEVAllocSizeExpr(const FoldingSetNodeID &ID,
- const Type *ty, const Type *allocty) :
- SCEVTargetDataConstant(ID, scAllocSize, ty),
- AllocTy(allocty) {}
-
- public:
- const Type *getAllocType() const { return AllocTy; }
-
- virtual void print(raw_ostream &OS) const;
-
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SCEVAllocSizeExpr *S) { return true; }
- static inline bool classof(const SCEV *S) {
- return S->getSCEVType() == scAllocSize;
- }
- };
-
- //===--------------------------------------------------------------------===//
/// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV
/// value, and only represent it as its LLVM Value. This is the "bottom"
/// value for the analysis.
@@ -615,6 +529,16 @@ namespace llvm {
public:
Value *getValue() const { return V; }
+ /// isSizeOf, isAlignOf, isOffsetOf - Test whether this is a special
+ /// constant representing a type size, alignment, or field offset in
+ /// a target-independent manner, and hasn't happened to have been
+ /// folded with other operations into something unrecognizable. This
+ /// is mainly only useful for pretty-printing and other situations
+ /// where it isn't absolutely required for these to succeed.
+ bool isSizeOf(const Type *&AllocTy) const;
+ bool isAlignOf(const Type *&AllocTy) const;
+ bool isOffsetOf(const Type *&STy, Constant *&FieldNo) const;
+
virtual bool isLoopInvariant(const Loop *L) const;
virtual bool hasComputableLoopEvolution(const Loop *QL) const {
return false; // not computable
@@ -665,10 +589,6 @@ namespace llvm {
return ((SC*)this)->visitSMaxExpr((const SCEVSMaxExpr*)S);
case scUMaxExpr:
return ((SC*)this)->visitUMaxExpr((const SCEVUMaxExpr*)S);
- case scFieldOffset:
- return ((SC*)this)->visitFieldOffsetExpr((const SCEVFieldOffsetExpr*)S);
- case scAllocSize:
- return ((SC*)this)->visitAllocSizeExpr((const SCEVAllocSizeExpr*)S);
case scUnknown:
return ((SC*)this)->visitUnknown((const SCEVUnknown*)S);
case scCouldNotCompute:
diff --git a/include/llvm/Assembly/AsmAnnotationWriter.h b/include/llvm/Assembly/AsmAnnotationWriter.h
index 6c3ddaf..6d75720 100644
--- a/include/llvm/Assembly/AsmAnnotationWriter.h
+++ b/include/llvm/Assembly/AsmAnnotationWriter.h
@@ -23,29 +23,34 @@ class Function;
class BasicBlock;
class Instruction;
class raw_ostream;
+class formatted_raw_ostream;
class AssemblyAnnotationWriter {
public:
virtual ~AssemblyAnnotationWriter();
- // emitFunctionAnnot - This may be implemented to emit a string right before
- // the start of a function.
+ /// emitFunctionAnnot - This may be implemented to emit a string right before
+ /// the start of a function.
virtual void emitFunctionAnnot(const Function *F, raw_ostream &OS) {}
- // emitBasicBlockStartAnnot - This may be implemented to emit a string right
- // after the basic block label, but before the first instruction in the block.
+ /// emitBasicBlockStartAnnot - This may be implemented to emit a string right
+ /// after the basic block label, but before the first instruction in the block.
virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, raw_ostream &OS){
}
- // emitBasicBlockEndAnnot - This may be implemented to emit a string right
- // after the basic block.
+ /// emitBasicBlockEndAnnot - This may be implemented to emit a string right
+ /// after the basic block.
virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, raw_ostream &OS){
}
- // emitInstructionAnnot - This may be implemented to emit a string right
- // before an instruction is emitted.
+ /// emitInstructionAnnot - This may be implemented to emit a string right
+ /// before an instruction is emitted.
virtual void emitInstructionAnnot(const Instruction *I, raw_ostream &OS) {}
+
+ /// printInfoComment - This may be implemented to emit a comment to the
+ /// right of an instruction or global value.
+ virtual void printInfoComment(const Value &V, formatted_raw_ostream &OS) {}
};
} // End llvm namespace
diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h
index 7fa5d4a..126c290 100644
--- a/include/llvm/Attributes.h
+++ b/include/llvm/Attributes.h
@@ -58,6 +58,13 @@ const Attributes NoRedZone = 1<<22; /// disable redzone
const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
/// instructions.
const Attributes Naked = 1<<24; ///< Naked function
+const Attributes InlineHint = 1<<25; ///< source said inlining was
+ ///desirable
+const Attributes StackAlignment = 31<<26; ///< Alignment of stack for
+ ///function (5 bits) stored as log2
+ ///of alignment with +1 bias
+ ///0 means unaligned (different from
+ ///alignstack(1))
/// @brief Attributes that only apply to function parameters.
const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
@@ -66,7 +73,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
/// be used on return values or function parameters.
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
- NoRedZone | NoImplicitFloat | Naked;
+ NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment;
/// @brief Parameter attributes that do not apply to vararg call arguments.
const Attributes VarArgsIncompatible = StructRet;
@@ -103,6 +110,28 @@ inline unsigned getAlignmentFromAttrs(Attributes A) {
return 1U << ((Align >> 16) - 1);
}
+/// This turns an int stack alignment (which must be a power of 2) into
+/// the form used internally in Attributes.
+inline Attributes constructStackAlignmentFromInt(unsigned i) {
+ // Default alignment, allow the target to define how to align it.
+ if (i == 0)
+ return 0;
+
+ assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
+ assert(i <= 0x40000000 && "Alignment too large.");
+ return (Log2_32(i)+1) << 26;
+}
+
+/// This returns the stack alignment field of an attribute as a byte alignment
+/// value.
+inline unsigned getStackAlignmentFromAttrs(Attributes A) {
+ Attributes StackAlign = A & Attribute::StackAlignment;
+ if (StackAlign == 0)
+ return 0;
+
+ return 1U << ((StackAlign >> 26) - 1);
+}
+
/// The set of Attributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out
diff --git a/include/llvm/Bitcode/Archive.h b/include/llvm/Bitcode/Archive.h
index e19e4c0..67f2a4a 100644
--- a/include/llvm/Bitcode/Archive.h
+++ b/include/llvm/Bitcode/Archive.h
@@ -27,7 +27,6 @@ namespace llvm {
class MemoryBuffer;
// Forward declare classes
-class ModuleProvider; // From VMCore
class Module; // From VMCore
class Archive; // Declared below
class ArchiveMemberHeader; // Internal implementation class
@@ -374,14 +373,14 @@ class Archive {
/// returns the associated module that defines that symbol. This method can
/// be called as many times as necessary. This is handy for linking the
/// archive into another module based on unresolved symbols. Note that the
- /// ModuleProvider returned by this accessor should not be deleted by the
- /// caller. It is managed internally by the Archive class. It is possible
- /// that multiple calls to this accessor will return the same ModuleProvider
- /// instance because the associated module defines multiple symbols.
- /// @returns The ModuleProvider* found or null if the archive does not
- /// contain a module that defines the \p symbol.
+ /// Module returned by this accessor should not be deleted by the caller. It
+ /// is managed internally by the Archive class. It is possible that multiple
+ /// calls to this accessor will return the same Module instance because the
+ /// associated module defines multiple symbols.
+ /// @returns The Module* found or null if the archive does not contain a
+ /// module that defines the \p symbol.
/// @brief Look up a module by symbol name.
- ModuleProvider* findModuleDefiningSymbol(
+ Module* findModuleDefiningSymbol(
const std::string& symbol, ///< Symbol to be sought
std::string* ErrMessage ///< Error message storage, if non-zero
);
@@ -397,7 +396,7 @@ class Archive {
/// @brief Look up multiple symbols in the archive.
bool findModulesDefiningSymbols(
std::set<std::string>& symbols, ///< Symbols to be sought
- std::set<ModuleProvider*>& modules, ///< The modules matching \p symbols
+ std::set<Module*>& modules, ///< The modules matching \p symbols
std::string* ErrMessage ///< Error msg storage, if non-zero
);
@@ -513,9 +512,9 @@ class Archive {
/// This type is used to keep track of bitcode modules loaded from the
/// symbol table. It maps the file offset to a pair that consists of the
- /// associated ArchiveMember and the ModuleProvider.
+ /// associated ArchiveMember and the Module.
/// @brief Module mapping type
- typedef std::map<unsigned,std::pair<ModuleProvider*,ArchiveMember*> >
+ typedef std::map<unsigned,std::pair<Module*,ArchiveMember*> >
ModuleMap;
diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h
index 2b1b85e..31d513c 100644
--- a/include/llvm/Bitcode/BitstreamWriter.h
+++ b/include/llvm/Bitcode/BitstreamWriter.h
@@ -291,7 +291,7 @@ private:
/// EmitRecordWithAbbrevImpl - This is the core implementation of the record
/// emission code. If BlobData is non-null, then it specifies an array of
/// data that should be emitted as part of the Blob or Array operand that is
- /// known to exist at the end of the the record.
+ /// known to exist at the end of the record.
template<typename uintty>
void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
StringRef Blob) {
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index 9bb50d4..a980df8 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -94,7 +94,8 @@ namespace bitc {
TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa)
TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles)
- TYPE_CODE_METADATA = 16 // METADATA
+ TYPE_CODE_METADATA = 16, // METADATA
+ TYPE_CODE_UNION = 17 // UNION: [eltty x N]
};
// The type symbol table only has one code (TST_ENTRY_CODE).
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h
index 7b74bdf..45eb801 100644
--- a/include/llvm/Bitcode/ReaderWriter.h
+++ b/include/llvm/Bitcode/ReaderWriter.h
@@ -18,21 +18,20 @@
namespace llvm {
class Module;
- class ModuleProvider;
class MemoryBuffer;
class ModulePass;
class BitstreamWriter;
class LLVMContext;
class raw_ostream;
- /// getBitcodeModuleProvider - Read the header of the specified bitcode buffer
+ /// getLazyBitcodeModule - Read the header of the specified bitcode buffer
/// and prepare for lazy deserialization of function bodies. If successful,
/// this takes ownership of 'buffer' and returns a non-null pointer. On
/// error, this returns null, *does not* take ownership of Buffer, and fills
/// in *ErrMsg with an error description if ErrMsg is non-null.
- ModuleProvider *getBitcodeModuleProvider(MemoryBuffer *Buffer,
- LLVMContext& Context,
- std::string *ErrMsg = 0);
+ Module *getLazyBitcodeModule(MemoryBuffer *Buffer,
+ LLVMContext& Context,
+ std::string *ErrMsg = 0);
/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
/// If an error occurs, this returns null and fills in *ErrMsg if it is
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 377096c..28a1a3e 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -19,7 +19,6 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/ADT/DenseMap.h"
namespace llvm {
class BlockAddress;
@@ -62,13 +61,6 @@ namespace llvm {
class AsmPrinter : public MachineFunctionPass {
static char ID;
- /// FunctionNumber - This provides a unique ID for each function emitted in
- /// this translation unit. It is autoincremented by SetupMachineFunction,
- /// and can be accessed with getFunctionNumber() and
- /// IncrementFunctionNumber().
- ///
- unsigned FunctionNumber;
-
// GCMetadataPrinters - The garbage collection metadata printer table.
typedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type;
typedef gcp_map_type::iterator gcp_iterator;
@@ -88,13 +80,6 @@ namespace llvm {
DwarfWriter *DW;
public:
- /// Flags to specify different kinds of comments to output in
- /// assembly code. These flags carry semantic information not
- /// otherwise easily derivable from the IR text.
- ///
- enum CommentFlag {
- ReloadReuse = 0x1
- };
/// Output stream on which we're printing assembly code.
///
@@ -157,7 +142,8 @@ namespace llvm {
protected:
explicit AsmPrinter(formatted_raw_ostream &o, TargetMachine &TM,
- const MCAsmInfo *T, bool V);
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T);
public:
virtual ~AsmPrinter();
@@ -168,7 +154,7 @@ namespace llvm {
/// getFunctionNumber - Return a unique ID for the current function.
///
- unsigned getFunctionNumber() const { return FunctionNumber; }
+ unsigned getFunctionNumber() const;
protected:
/// getAnalysisUsage - Record analysis usage.
@@ -215,26 +201,51 @@ namespace llvm {
unsigned AsmVariant,
const char *ExtraCode);
+ /// runOnMachineFunction - Emit the specified function out to the
+ /// OutStreamer.
+ virtual bool runOnMachineFunction(MachineFunction &MF) {
+ SetupMachineFunction(MF);
+ EmitFunctionHeader();
+ EmitFunctionBody();
+ return false;
+ }
+
/// SetupMachineFunction - This should be called when a new MachineFunction
/// is being processed from runOnMachineFunction.
void SetupMachineFunction(MachineFunction &MF);
- /// IncrementFunctionNumber - Increase Function Number. AsmPrinters should
- /// not normally call this, as the counter is automatically bumped by
- /// SetupMachineFunction.
- void IncrementFunctionNumber() { FunctionNumber++; }
+ /// EmitFunctionHeader - This method emits the header for the current
+ /// function.
+ void EmitFunctionHeader();
+
+ /// EmitFunctionBody - This method emits the body and trailer for a
+ /// function.
+ void EmitFunctionBody();
+
+ /// EmitInstruction - Targets should implement this to emit instructions.
+ virtual void EmitInstruction(const MachineInstr *MI) {
+ assert(0 && "EmitInstruction not implemented");
+ }
+
+ /// EmitFunctionBodyStart - Targets can override this to emit stuff before
+ /// the first basic block in the function.
+ virtual void EmitFunctionBodyStart() {}
+
+ /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
+ /// the last basic block in the function.
+ virtual void EmitFunctionBodyEnd() {}
/// EmitConstantPool - Print to the current output stream assembly
/// representations of the constants in the constant pool MCP. This is
/// used to print out constants which have been "spilled to memory" by
/// the code generator.
///
- void EmitConstantPool(MachineConstantPool *MCP);
-
+ virtual void EmitConstantPool();
+
/// EmitJumpTableInfo - Print assembly representations of the jump tables
/// used by the current function to the current output stream.
///
- void EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF);
+ void EmitJumpTableInfo();
/// EmitGlobalVariable - Emit the specified global variable to the .s file.
virtual void EmitGlobalVariable(const GlobalVariable *GV);
@@ -265,9 +276,6 @@ namespace llvm {
///
void EmitInt64(uint64_t Value) const;
- /// EmitFile - Emit a .file directive.
- void EmitFile(unsigned Number, StringRef Name) const;
-
//===------------------------------------------------------------------===//
/// EmitAlignment - Emit an alignment directive to the specified power of
@@ -292,19 +300,15 @@ namespace llvm {
/// printLabel - This method prints a local label used by debug and
/// exception handling tables.
- void printLabel(const MachineInstr *MI) const;
void printLabel(unsigned Id) const;
/// printDeclare - This method prints a local variable declaration used by
/// debug tables.
void printDeclare(const MachineInstr *MI) const;
- /// EmitComments - Pretty-print comments for instructions
- void EmitComments(const MachineInstr &MI) const;
-
/// GetGlobalValueSymbol - Return the MCSymbol for the specified global
/// value.
- MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
+ virtual MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
/// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with
/// global value name as its base, with the specified suffix, and where the
@@ -317,23 +321,21 @@ namespace llvm {
/// ExternalSymbol.
MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const;
- /// GetMBBSymbol - Return the MCSymbol corresponding to the specified basic
- /// block label.
- MCSymbol *GetMBBSymbol(unsigned MBBID) const;
-
/// GetCPISymbol - Return the symbol for the specified constant pool entry.
MCSymbol *GetCPISymbol(unsigned CPID) const;
/// GetJTISymbol - Return the symbol for the specified jump table entry.
MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const;
+ /// GetJTSetSymbol - Return the symbol for the specified jump table .set
+ /// FIXME: privatize to AsmPrinter.
+ MCSymbol *GetJTSetSymbol(unsigned UID, unsigned MBBID) const;
+
/// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress
/// uses of the specified basic block.
- MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA,
- const char *Suffix = "") const;
+ MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const;
MCSymbol *GetBlockAddressSymbol(const Function *F,
- const BasicBlock *BB,
- const char *Suffix = "") const;
+ const BasicBlock *BB) const;
/// EmitBasicBlockStart - This method prints the label for the specified
/// MachineBasicBlock, an alignment (if present) and a comment describing
@@ -347,12 +349,21 @@ namespace llvm {
void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0);
protected:
+ virtual void EmitFunctionEntryLabel();
+
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
+ /// printOffset - This is just convenient handler for printing offsets.
+ void printOffset(int64_t Offset) const;
+
+ private:
+
/// processDebugLoc - Processes the debug information of each machine
/// instruction's DebugLoc.
void processDebugLoc(const MachineInstr *MI, bool BeforePrintingInsn);
+ void printLabelInst(const MachineInstr *MI) const;
+
/// printInlineAsm - This method formats and prints the specified machine
/// instruction that is an inline asm.
void printInlineAsm(const MachineInstr *MI) const;
@@ -364,24 +375,15 @@ namespace llvm {
/// printKill - This method prints the specified kill machine instruction.
void printKill(const MachineInstr *MI) const;
- /// printPICJumpTableSetLabel - This method prints a set label for the
- /// specified MachineBasicBlock for a jumptable entry.
- virtual void printPICJumpTableSetLabel(unsigned uid,
- const MachineBasicBlock *MBB) const;
- virtual void printPICJumpTableSetLabel(unsigned uid, unsigned uid2,
- const MachineBasicBlock *MBB) const;
- virtual void printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
- const MachineBasicBlock *MBB,
- unsigned uid) const;
-
- /// printVisibility - This prints visibility information about symbol, if
+ /// EmitVisibility - This emits visibility information about symbol, if
/// this is suported by the target.
- void printVisibility(MCSymbol *Sym, unsigned Visibility) const;
+ void EmitVisibility(MCSymbol *Sym, unsigned Visibility) const;
- /// printOffset - This is just convenient handler for printing offsets.
- void printOffset(int64_t Offset) const;
-
- private:
+ void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const;
+
+ void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
+ const MachineBasicBlock *MBB,
+ unsigned uid) const;
void EmitLLVMUsedList(Constant *List);
void EmitXXStructorList(Constant *List);
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h
index 4d50879..7fda6f7 100644
--- a/include/llvm/CodeGen/DAGISelHeader.h
+++ b/include/llvm/CodeGen/DAGISelHeader.h
@@ -132,4 +132,283 @@ void SelectRoot(SelectionDAG &DAG) {
CurDAG->setRoot(Dummy.getValue());
}
+
+/// CheckInteger - Return true if the specified node is not a ConstantSDNode or
+/// if it doesn't have the specified value.
+static bool CheckInteger(SDValue V, int64_t Val) {
+ ConstantSDNode *C = dyn_cast<ConstantSDNode>(V);
+ return C == 0 || C->getSExtValue() != Val;
+}
+
+/// CheckAndImmediate - Check to see if the specified node is an and with an
+/// immediate returning true on failure.
+///
+/// FIXME: Inline this gunk into CheckAndMask.
+bool CheckAndImmediate(SDValue V, int64_t Val) {
+ if (V->getOpcode() == ISD::AND)
+ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1)))
+ if (CheckAndMask(V.getOperand(0), C, Val))
+ return false;
+ return true;
+}
+
+/// CheckOrImmediate - Check to see if the specified node is an or with an
+/// immediate returning true on failure.
+///
+/// FIXME: Inline this gunk into CheckOrMask.
+bool CheckOrImmediate(SDValue V, int64_t Val) {
+ if (V->getOpcode() == ISD::OR)
+ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1)))
+ if (CheckOrMask(V.getOperand(0), C, Val))
+ return false;
+ return true;
+}
+
+// These functions are marked always inline so that Idx doesn't get pinned to
+// the stack.
+ALWAYS_INLINE static int8_t
+GetInt1(const unsigned char *MatcherTable, unsigned &Idx) {
+ return MatcherTable[Idx++];
+}
+
+ALWAYS_INLINE static int16_t
+GetInt2(const unsigned char *MatcherTable, unsigned &Idx) {
+ int16_t Val = GetInt1(MatcherTable, Idx);
+ Val |= int16_t(GetInt1(MatcherTable, Idx)) << 8;
+ return Val;
+}
+
+ALWAYS_INLINE static int32_t
+GetInt4(const unsigned char *MatcherTable, unsigned &Idx) {
+ int32_t Val = GetInt2(MatcherTable, Idx);
+ Val |= int32_t(GetInt2(MatcherTable, Idx)) << 16;
+ return Val;
+}
+
+ALWAYS_INLINE static int64_t
+GetInt8(const unsigned char *MatcherTable, unsigned &Idx) {
+ int64_t Val = GetInt4(MatcherTable, Idx);
+ Val |= int64_t(GetInt4(MatcherTable, Idx)) << 32;
+ return Val;
+}
+
+enum BuiltinOpcodes {
+ OPC_Emit,
+ OPC_Push,
+ OPC_Record,
+ OPC_MoveChild,
+ OPC_MoveParent,
+ OPC_CheckSame,
+ OPC_CheckPatternPredicate,
+ OPC_CheckPredicate,
+ OPC_CheckOpcode,
+ OPC_CheckType,
+ OPC_CheckInteger1, OPC_CheckInteger2, OPC_CheckInteger4, OPC_CheckInteger8,
+ OPC_CheckCondCode,
+ OPC_CheckValueType,
+ OPC_CheckComplexPat,
+ OPC_CheckAndImm1, OPC_CheckAndImm2, OPC_CheckAndImm4, OPC_CheckAndImm8,
+ OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8,
+ OPC_IsProfitableToFold,
+ OPC_IsLegalToFold
+};
+
+struct MatchScope {
+ /// FailIndex - If this match fails, this is the index to continue with.
+ unsigned FailIndex;
+
+ /// NodeStackSize - The size of the node stack when the scope was formed.
+ unsigned NodeStackSize;
+
+ /// NumRecordedNodes - The number of recorded nodes when the scope was formed.
+ unsigned NumRecordedNodes;
+};
+
+SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
+ unsigned TableSize) {
+ switch (NodeToMatch->getOpcode()) {
+ default:
+ break;
+ case ISD::EntryToken: // These nodes remain the same.
+ case ISD::BasicBlock:
+ case ISD::Register:
+ case ISD::HANDLENODE:
+ case ISD::TargetConstant:
+ case ISD::TargetConstantFP:
+ case ISD::TargetConstantPool:
+ case ISD::TargetFrameIndex:
+ case ISD::TargetExternalSymbol:
+ case ISD::TargetBlockAddress:
+ case ISD::TargetJumpTable:
+ case ISD::TargetGlobalTLSAddress:
+ case ISD::TargetGlobalAddress:
+ case ISD::TokenFactor:
+ case ISD::CopyFromReg:
+ case ISD::CopyToReg:
+ return 0;
+ case ISD::AssertSext:
+ case ISD::AssertZext:
+ ReplaceUses(SDValue(NodeToMatch, 0), NodeToMatch->getOperand(0));
+ return 0;
+ case ISD::INLINEASM: return Select_INLINEASM(NodeToMatch);
+ case ISD::EH_LABEL: return Select_EH_LABEL(NodeToMatch);
+ case ISD::UNDEF: return Select_UNDEF(NodeToMatch);
+ }
+
+ assert(!NodeToMatch->isMachineOpcode() && "Node already selected!");
+
+ SmallVector<MatchScope, 8> MatchScopes;
+
+ // RecordedNodes - This is the set of nodes that have been recorded by the
+ // state machine.
+ SmallVector<SDValue, 8> RecordedNodes;
+
+ // Set up the node stack with NodeToMatch as the only node on the stack.
+ SmallVector<SDValue, 8> NodeStack;
+ SDValue N = SDValue(NodeToMatch, 0);
+ NodeStack.push_back(N);
+
+ // Interpreter starts at opcode #0.
+ unsigned MatcherIndex = 0;
+ while (1) {
+ assert(MatcherIndex < TableSize && "Invalid index");
+ switch ((BuiltinOpcodes)MatcherTable[MatcherIndex++]) {
+ case OPC_Emit: {
+ errs() << "EMIT NODE\n";
+ return 0;
+ }
+ case OPC_Push: {
+ unsigned NumToSkip = MatcherTable[MatcherIndex++];
+ MatchScope NewEntry;
+ NewEntry.FailIndex = MatcherIndex+NumToSkip;
+ NewEntry.NodeStackSize = NodeStack.size();
+ NewEntry.NumRecordedNodes = RecordedNodes.size();
+ MatchScopes.push_back(NewEntry);
+ continue;
+ }
+ case OPC_Record:
+ // Remember this node, it may end up being an operand in the pattern.
+ RecordedNodes.push_back(N);
+ continue;
+
+ case OPC_MoveChild: {
+ unsigned Child = MatcherTable[MatcherIndex++];
+ if (Child >= N.getNumOperands())
+ break; // Match fails if out of range child #.
+ N = N.getOperand(Child);
+ NodeStack.push_back(N);
+ continue;
+ }
+
+ case OPC_MoveParent:
+ // Pop the current node off the NodeStack.
+ NodeStack.pop_back();
+ assert(!NodeStack.empty() && "Node stack imbalance!");
+ N = NodeStack.back();
+ continue;
+
+ case OPC_CheckSame: {
+ // Accept if it is exactly the same as a previously recorded node.
+ unsigned RecNo = MatcherTable[MatcherIndex++];
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+ if (N != RecordedNodes[RecNo]) break;
+ continue;
+ }
+ case OPC_CheckPatternPredicate:
+ if (!CheckPatternPredicate(MatcherTable[MatcherIndex++])) break;
+ continue;
+ case OPC_CheckPredicate:
+ if (!CheckNodePredicate(N.getNode(), MatcherTable[MatcherIndex++])) break;
+ continue;
+ case OPC_CheckComplexPat: {
+ unsigned PatNo = MatcherTable[MatcherIndex++];
+ (void)PatNo;
+ // FIXME: CHECK IT.
+ continue;
+ }
+
+ case OPC_CheckOpcode:
+ if (N->getOpcode() != MatcherTable[MatcherIndex++]) break;
+ continue;
+ case OPC_CheckType:
+ if (N.getValueType() !=
+ (MVT::SimpleValueType)MatcherTable[MatcherIndex++]) break;
+ continue;
+ case OPC_CheckCondCode:
+ if (cast<CondCodeSDNode>(N)->get() !=
+ (ISD::CondCode)MatcherTable[MatcherIndex++]) break;
+ continue;
+ case OPC_CheckValueType:
+ if (cast<VTSDNode>(N)->getVT() !=
+ (MVT::SimpleValueType)MatcherTable[MatcherIndex++]) break;
+ continue;
+
+ case OPC_CheckInteger1:
+ if (CheckInteger(N, GetInt1(MatcherTable, MatcherIndex))) break;
+ continue;
+ case OPC_CheckInteger2:
+ if (CheckInteger(N, GetInt2(MatcherTable, MatcherIndex))) break;
+ continue;
+ case OPC_CheckInteger4:
+ if (CheckInteger(N, GetInt4(MatcherTable, MatcherIndex))) break;
+ continue;
+ case OPC_CheckInteger8:
+ if (CheckInteger(N, GetInt8(MatcherTable, MatcherIndex))) break;
+ continue;
+
+ case OPC_CheckAndImm1:
+ if (CheckAndImmediate(N, GetInt1(MatcherTable, MatcherIndex))) break;
+ continue;
+ case OPC_CheckAndImm2:
+ if (CheckAndImmediate(N, GetInt2(MatcherTable, MatcherIndex))) break;
+ continue;
+ case OPC_CheckAndImm4:
+ if (CheckAndImmediate(N, GetInt4(MatcherTable, MatcherIndex))) break;
+ continue;
+ case OPC_CheckAndImm8:
+ if (CheckAndImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break;
+ continue;
+
+ case OPC_CheckOrImm1:
+ if (CheckOrImmediate(N, GetInt1(MatcherTable, MatcherIndex))) break;
+ continue;
+ case OPC_CheckOrImm2:
+ if (CheckOrImmediate(N, GetInt2(MatcherTable, MatcherIndex))) break;
+ continue;
+ case OPC_CheckOrImm4:
+ if (CheckOrImmediate(N, GetInt4(MatcherTable, MatcherIndex))) break;
+ continue;
+ case OPC_CheckOrImm8:
+ if (CheckOrImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break;
+ continue;
+
+ case OPC_IsProfitableToFold:
+ assert(!NodeStack.size() == 1 && "No parent node");
+ if (!IsProfitableToFold(N, NodeStack[NodeStack.size()-2].getNode(),
+ NodeToMatch))
+ break;
+ continue;
+ case OPC_IsLegalToFold:
+ assert(!NodeStack.size() == 1 && "No parent node");
+ if (!IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(),
+ NodeToMatch))
+ break;
+ continue;
+ }
+
+ // If the code reached this point, then the match failed pop out to the next
+ // match scope.
+ if (MatchScopes.empty()) {
+ CannotYetSelect(NodeToMatch);
+ return 0;
+ }
+
+ RecordedNodes.resize(MatchScopes.back().NumRecordedNodes);
+ NodeStack.resize(MatchScopes.back().NodeStackSize);
+ MatcherIndex = MatchScopes.back().FailIndex;
+ MatchScopes.pop_back();
+ }
+}
+
+
#endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */
diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h
index 460c3c7..d59e22a 100644
--- a/include/llvm/CodeGen/DwarfWriter.h
+++ b/include/llvm/CodeGen/DwarfWriter.h
@@ -76,11 +76,11 @@ public:
/// BeginFunction - Gather pre-function debug information. Assumes being
/// emitted immediately after the function entry point.
- void BeginFunction(MachineFunction *MF);
+ void BeginFunction(const MachineFunction *MF);
/// EndFunction - Gather and emit post-function debug information.
///
- void EndFunction(MachineFunction *MF);
+ void EndFunction(const MachineFunction *MF);
/// RecordSourceLine - Register a source line with debug info. Returns a
/// unique label ID used to generate a label and provide correspondence to
diff --git a/include/llvm/CodeGen/FileWriters.h b/include/llvm/CodeGen/FileWriters.h
deleted file mode 100644
index 9dba838..0000000
--- a/include/llvm/CodeGen/FileWriters.h
+++ /dev/null
@@ -1,37 +0,0 @@
-//===-- FileWriters.h - File Writers Creation Functions ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Functions to add the various file writer passes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_FILEWRITERS_H
-#define LLVM_CODEGEN_FILEWRITERS_H
-
-namespace llvm {
-
- class PassManagerBase;
- class ObjectCodeEmitter;
- class TargetMachine;
- class raw_ostream;
- class formatted_raw_ostream;
- class MachineFunctionPass;
- class MCAsmInfo;
- class MCCodeEmitter;
-
- ObjectCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O,
- TargetMachine &TM);
- MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O,
- TargetMachine &TM,
- const MCAsmInfo *T,
- MCCodeEmitter *MCE);
-
-} // end llvm namespace
-
-#endif // LLVM_CODEGEN_FILEWRITERS_H
diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h
index 9c4e5b9..0a1d4f4 100644
--- a/include/llvm/CodeGen/JITCodeEmitter.h
+++ b/include/llvm/CodeGen/JITCodeEmitter.h
@@ -146,7 +146,7 @@ public:
}
}
- /// emitAlignment - Move the CurBufferPtr pointer up the the specified
+ /// emitAlignment - Move the CurBufferPtr pointer up to the specified
/// alignment (saturated to BufferEnd of course).
void emitAlignment(unsigned Alignment) {
if (Alignment == 0) Alignment = 1;
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index e31a7f0..512c94d 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -320,7 +320,7 @@ namespace llvm {
/// advanceTo - Advance the specified iterator to point to the LiveRange
/// containing the specified position, or end() if the position is past the
/// end of the interval. If no LiveRange contains this position, but the
- /// position is in a hole, this method returns an iterator pointing the the
+ /// position is in a hole, this method returns an iterator pointing to the
/// LiveRange immediately after the hole.
iterator advanceTo(iterator I, SlotIndex Pos) {
if (Pos >= endIndex())
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 20644c1..db82ba5 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -21,6 +21,9 @@ namespace llvm {
class BasicBlock;
class MachineFunction;
+class MCContext;
+class MCSymbol;
+class StringRef;
class raw_ostream;
template <>
@@ -338,7 +341,7 @@ public:
bool isCond);
/// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
- /// any DEBUG_VALUE instructions. Return UnknownLoc if there is none.
+ /// any DBG_VALUE instructions. Return UnknownLoc if there is none.
DebugLoc findDebugLoc(MachineBasicBlock::iterator &MBBI);
// Debugging methods.
@@ -352,6 +355,10 @@ public:
int getNumber() const { return Number; }
void setNumber(int N) { Number = N; }
+ /// getSymbol - Return the MCSymbol for this basic block.
+ ///
+ MCSymbol *getSymbol(MCContext &Ctx) const;
+
private: // Methods used to maintain doubly linked list of blocks...
friend struct ilist_traits<MachineBasicBlock>;
diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h
index d598a93..48b4082 100644
--- a/include/llvm/CodeGen/MachineCodeEmitter.h
+++ b/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -155,7 +155,7 @@ public:
}
}
- /// emitAlignment - Move the CurBufferPtr pointer up the the specified
+ /// emitAlignment - Move the CurBufferPtr pointer up to the specified
/// alignment (saturated to BufferEnd of course).
void emitAlignment(unsigned Alignment) {
if (Alignment == 0) Alignment = 1;
diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h
index 8d6c1d1..e6698a5 100644
--- a/include/llvm/CodeGen/MachineConstantPool.h
+++ b/include/llvm/CodeGen/MachineConstantPool.h
@@ -136,7 +136,7 @@ public:
: TD(td), PoolAlignment(1) {}
~MachineConstantPool();
- /// getConstantPoolAlignment - Return the the alignment required by
+ /// getConstantPoolAlignment - Return the alignment required by
/// the whole constant pool, of which the first element must be aligned.
unsigned getConstantPoolAlignment() const { return PoolAlignment; }
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 968e4ea..043e97f 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -276,6 +276,7 @@ public:
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
Objects[ObjectIdx+NumFixedObjects].Alignment = Align;
+ MaxAlignment = std::max(MaxAlignment, Align);
}
/// getObjectOffset - Return the assigned stack offset of the specified object
@@ -328,19 +329,6 @@ public:
///
void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
- /// calculateMaxStackAlignment() - If there is a local object which requires
- /// greater alignment than the current max alignment, adjust accordingly.
- void calculateMaxStackAlignment() {
- for (int i = getObjectIndexBegin(),
- e = getObjectIndexEnd(); i != e; ++i) {
- if (isDeadObjectIndex(i))
- continue;
-
- unsigned Align = getObjectAlignment(i);
- MaxAlignment = std::max(MaxAlignment, Align);
- }
- }
-
/// hasCalls - Return true if the current function has no function calls.
/// This is only valid during or after prolog/epilog code emission.
///
@@ -402,6 +390,7 @@ public:
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS));
int Index = (int)Objects.size()-NumFixedObjects-1;
assert(Index >= 0 && "Bad frame index!");
+ MaxAlignment = std::max(MaxAlignment, Alignment);
return Index;
}
@@ -412,6 +401,7 @@ public:
int CreateSpillStackObject(uint64_t Size, unsigned Alignment) {
CreateStackObject(Size, Alignment, true);
int Index = (int)Objects.size()-NumFixedObjects-1;
+ MaxAlignment = std::max(MaxAlignment, Alignment);
return Index;
}
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index 6ca51bf..3c5b466 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -33,6 +33,7 @@ class MachineRegisterInfo;
class MachineFrameInfo;
class MachineConstantPool;
class MachineJumpTableInfo;
+class Pass;
class TargetMachine;
class TargetRegisterClass;
@@ -112,6 +113,11 @@ class MachineFunction {
// Tracks debug locations.
DebugLocTracker DebugLocInfo;
+ /// FunctionNumber - This provides a unique ID for each function emitted in
+ /// this translation unit.
+ ///
+ unsigned FunctionNumber;
+
// The alignment of the function.
unsigned Alignment;
@@ -119,13 +125,17 @@ class MachineFunction {
void operator=(const MachineFunction&); // intentionally unimplemented
public:
- MachineFunction(Function *Fn, const TargetMachine &TM);
+ MachineFunction(Function *Fn, const TargetMachine &TM, unsigned FunctionNum);
~MachineFunction();
/// getFunction - Return the LLVM function that this machine code represents
///
Function *getFunction() const { return Fn; }
+ /// getFunctionNumber - Return a unique ID for the current function.
+ ///
+ unsigned getFunctionNumber() const { return FunctionNumber; }
+
/// getTarget - Return the target machine this machine code is compiled with
///
const TargetMachine &getTarget() const { return Target; }
@@ -143,11 +153,16 @@ public:
const MachineFrameInfo *getFrameInfo() const { return FrameInfo; }
/// getJumpTableInfo - Return the jump table info object for the current
- /// function. This object contains information about jump tables for switch
- /// instructions in the current function.
- ///
- MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; }
+ /// function. This object contains information about jump tables in the
+ /// current function. If the current function has no jump tables, this will
+ /// return null.
const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; }
+ MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; }
+
+ /// getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it
+ /// does already exist, allocate one.
+ MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind);
+
/// getConstantPool - Return the constant pool object for the current
/// function.
@@ -163,6 +178,11 @@ public:
///
void setAlignment(unsigned A) { Alignment = A; }
+ /// EnsureAlignment - Make sure the function is at least 'A' bits aligned.
+ void EnsureAlignment(unsigned A) {
+ if (Alignment < A) Alignment = A;
+ }
+
/// getInfo - Keep track of various per-function pieces of information for
/// backends that would like to do so.
///
@@ -310,7 +330,7 @@ public:
bool NoImp = false);
/// CloneMachineInstr - Create a new MachineInstr which is a copy of the
- /// 'Orig' instruction, identical in all ways except the the instruction
+ /// 'Orig' instruction, identical in all ways except the instruction
/// has no parent, prev, or next.
///
/// See also TargetInstrInfo::duplicate() for target-specific fixes to cloned
@@ -363,6 +383,17 @@ public:
MachineInstr::mmo_iterator End);
//===--------------------------------------------------------------------===//
+ // Label Manipulation.
+ //
+
+ /// getJTISymbol - Return the MCSymbol for the specified non-empty jump table.
+ /// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a
+ /// normal 'L' label is returned.
+ MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx,
+ bool isLinkerPrivate = false) const;
+
+
+ //===--------------------------------------------------------------------===//
// Debug location.
//
diff --git a/include/llvm/CodeGen/MachineFunctionAnalysis.h b/include/llvm/CodeGen/MachineFunctionAnalysis.h
index aa4cc91..ee2c6dd 100644
--- a/include/llvm/CodeGen/MachineFunctionAnalysis.h
+++ b/include/llvm/CodeGen/MachineFunctionAnalysis.h
@@ -28,7 +28,7 @@ private:
const TargetMachine &TM;
CodeGenOpt::Level OptLevel;
MachineFunction *MF;
-
+ unsigned NextFnNum;
public:
static char ID;
explicit MachineFunctionAnalysis(const TargetMachine &tm,
@@ -39,6 +39,7 @@ public:
CodeGenOpt::Level getOptLevel() const { return OptLevel; }
private:
+ virtual bool doInitialization(Module &) { NextFnNum = 1; return false; }
virtual bool runOnFunction(Function &F);
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index c2a0578..6e33fb3 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -19,9 +19,9 @@
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/Target/TargetInstrDesc.h"
+#include "llvm/Target/TargetOpcodes.h"
#include "llvm/Support/DebugLoc.h"
#include <vector>
@@ -41,6 +41,14 @@ class MachineInstr : public ilist_node<MachineInstr> {
public:
typedef MachineMemOperand **mmo_iterator;
+ /// Flags to specify different kinds of comments to output in
+ /// assembly code. These flags carry semantic information not
+ /// otherwise easily derivable from the IR text.
+ ///
+ enum CommentFlag {
+ ReloadReuse = 0x1
+ };
+
private:
const TargetInstrDesc *TID; // Instruction descriptor.
unsigned short NumImplicitOps; // Number of implicit operands (which
@@ -121,14 +129,14 @@ public:
/// getAsmPrinterFlag - Return whether an AsmPrinter flag is set.
///
- bool getAsmPrinterFlag(AsmPrinter::CommentFlag Flag) const {
+ bool getAsmPrinterFlag(CommentFlag Flag) const {
return AsmPrinterFlags & Flag;
}
/// setAsmPrinterFlag - Set a flag for the AsmPrinter.
///
- void setAsmPrinterFlag(unsigned short Flag) {
- AsmPrinterFlags |= Flag;
+ void setAsmPrinterFlag(CommentFlag Flag) {
+ AsmPrinterFlags |= (unsigned short)Flag;
}
/// getDebugLoc - Returns the debug location id of this MachineInstr.
@@ -193,12 +201,31 @@ public:
/// isLabel - Returns true if the MachineInstr represents a label.
///
- bool isLabel() const;
-
- /// isDebugLabel - Returns true if the MachineInstr represents a debug label.
- ///
- bool isDebugLabel() const;
-
+ bool isLabel() const {
+ return getOpcode() == TargetOpcode::DBG_LABEL ||
+ getOpcode() == TargetOpcode::EH_LABEL ||
+ getOpcode() == TargetOpcode::GC_LABEL;
+ }
+
+ bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; }
+ bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; }
+ bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; }
+ bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
+
+ bool isPHI() const { return getOpcode() == TargetOpcode::PHI; }
+ bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
+ bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
+ bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
+ bool isExtractSubreg() const {
+ return getOpcode() == TargetOpcode::EXTRACT_SUBREG;
+ }
+ bool isInsertSubreg() const {
+ return getOpcode() == TargetOpcode::INSERT_SUBREG;
+ }
+ bool isSubregToReg() const {
+ return getOpcode() == TargetOpcode::SUBREG_TO_REG;
+ }
+
/// readsRegister - Return true if the MachineInstr reads the specified
/// register. If TargetRegisterInfo is passed, then it also checks if there
/// is a read of a super-register.
@@ -320,7 +347,7 @@ public:
/// isInvariantLoad - Return true if this instruction is loading from a
/// location whose value is invariant across the function. For example,
- /// loading a value from the constant pool or from from the argument area of
+ /// loading a value from the constant pool or from the argument area of
/// a function if it does not change. This should only return true of *all*
/// loads the instruction does are invariant (if it does multiple loads).
bool isInvariantLoad(AliasAnalysis *AA) const;
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index 8eb0add..a263a97 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -32,6 +32,7 @@ namespace RegState {
Dead = 0x10,
Undef = 0x20,
EarlyClobber = 0x40,
+ Debug = 0x80,
ImplicitDefine = Implicit | Define,
ImplicitKill = Implicit | Kill
};
@@ -62,7 +63,8 @@ public:
flags & RegState::Dead,
flags & RegState::Undef,
flags & RegState::EarlyClobber,
- SubReg));
+ SubReg,
+ flags & RegState::Debug));
return *this;
}
diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h
index 57c65c8..5a4c9a9fb 100644
--- a/include/llvm/CodeGen/MachineJumpTableInfo.h
+++ b/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -40,13 +40,45 @@ struct MachineJumpTableEntry {
};
class MachineJumpTableInfo {
- unsigned EntrySize;
- unsigned Alignment;
+public:
+ /// JTEntryKind - This enum indicates how each entry of the jump table is
+ /// represented and emitted.
+ enum JTEntryKind {
+ /// EK_BlockAddress - Each entry is a plain address of block, e.g.:
+ /// .word LBB123
+ EK_BlockAddress,
+
+ /// EK_GPRel32BlockAddress - Each entry is an address of block, encoded
+ /// with a relocation as gp-relative, e.g.:
+ /// .gprel32 LBB123
+ EK_GPRel32BlockAddress,
+
+ /// EK_LabelDifference32 - Each entry is the address of the block minus
+ /// the address of the jump table. This is used for PIC jump tables where
+ /// gprel32 is not supported. e.g.:
+ /// .word LBB123 - LJTI1_2
+ /// If the .set directive is supported, this is emitted as:
+ /// .set L4_5_set_123, LBB123 - LJTI1_2
+ /// .word L4_5_set_123
+ EK_LabelDifference32,
+
+ /// EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the
+ /// TargetLowering::LowerCustomJumpTableEntry hook.
+ EK_Custom32
+ };
+private:
+ JTEntryKind EntryKind;
std::vector<MachineJumpTableEntry> JumpTables;
public:
- MachineJumpTableInfo(unsigned Size, unsigned Align)
- : EntrySize(Size), Alignment(Align) {}
+ MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {}
+ JTEntryKind getEntryKind() const { return EntryKind; }
+
+ /// getEntrySize - Return the size of each entry in the jump table.
+ unsigned getEntrySize(const TargetData &TD) const;
+ /// getEntryAlignment - Return the alignment of each entry in the jump table.
+ unsigned getEntryAlignment(const TargetData &TD) const;
+
/// getJumpTableIndex - Create a new jump table or return an existing one.
///
unsigned getJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs);
@@ -58,9 +90,9 @@ public:
const std::vector<MachineJumpTableEntry> &getJumpTables() const {
return JumpTables;
}
-
- /// RemoveJumpTable - Mark the specific index as being dead. This will cause
- /// it to not be emitted.
+
+ /// RemoveJumpTable - Mark the specific index as being dead. This will
+ /// prevent it from being emitted.
void RemoveJumpTable(unsigned Idx) {
JumpTables[Idx].MBBs.clear();
}
@@ -74,13 +106,6 @@ public:
bool ReplaceMBBInJumpTable(unsigned Idx, MachineBasicBlock *Old,
MachineBasicBlock *New);
- /// getEntrySize - Returns the size of an individual field in a jump table.
- ///
- unsigned getEntrySize() const { return EntrySize; }
-
- /// getAlignment - returns the target's preferred alignment for jump tables
- unsigned getAlignment() const { return Alignment; }
-
/// print - Used by the MachineFunction printer to print information about
/// jump tables. Implemented in MachineFunction.cpp
///
diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h
index 5dee199..7272aa5 100644
--- a/include/llvm/CodeGen/MachineMemOperand.h
+++ b/include/llvm/CodeGen/MachineMemOperand.h
@@ -46,7 +46,11 @@ public:
/// The memory access writes data.
MOStore = 2,
/// The memory access is volatile.
- MOVolatile = 4
+ MOVolatile = 4,
+ /// The memory access is non-temporal.
+ MONonTemporal = 8,
+ // This is the number of bits we need to represent flags.
+ MOMaxBits = 4
};
/// MachineMemOperand - Construct an MachineMemOperand object with the
@@ -64,7 +68,7 @@ public:
const Value *getValue() const { return V; }
/// getFlags - Return the raw flags of the source value, \see MemOperandFlags.
- unsigned int getFlags() const { return Flags & 7; }
+ unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); }
/// getOffset - For normal values, this is a byte offset added to the base
/// address. For PseudoSourceValue::FPRel values, this is the FrameIndex
@@ -80,11 +84,12 @@ public:
/// getBaseAlignment - Return the minimum known alignment in bytes of the
/// base address, without the offset.
- uint64_t getBaseAlignment() const { return (1u << (Flags >> 3)) >> 1; }
+ uint64_t getBaseAlignment() const { return (1u << (Flags >> MOMaxBits)) >> 1; }
bool isLoad() const { return Flags & MOLoad; }
bool isStore() const { return Flags & MOStore; }
bool isVolatile() const { return Flags & MOVolatile; }
+ bool isNonTemporal() const { return Flags & MONonTemporal; }
/// refineAlignment - Update this MachineMemOperand to reflect the alignment
/// of MMO, if it has a greater alignment. This must only be used when the
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index d365029..8eeac9f 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -50,6 +50,7 @@ namespace llvm {
//===----------------------------------------------------------------------===//
// Forward declarations.
class Constant;
+class MCSymbol;
class MDNode;
class GlobalVariable;
class MachineBasicBlock;
@@ -66,6 +67,12 @@ class StructType;
class MachineModuleInfoImpl {
public:
virtual ~MachineModuleInfoImpl();
+
+ typedef std::vector<std::pair<MCSymbol*, MCSymbol*> >
+ SymbolListTy;
+protected:
+ static SymbolListTy
+ GetSortedStubs(const DenseMap<MCSymbol*, MCSymbol*> &Map);
};
@@ -113,7 +120,14 @@ class MachineModuleInfo : public ImmutablePass {
// LandingPads - List of LandingPadInfo describing the landing pad information
// in the current function.
std::vector<LandingPadInfo> LandingPads;
-
+
+ // Map of invoke call site index values to associated begin EH_LABEL for
+ // the current function.
+ DenseMap<unsigned, unsigned> CallSiteMap;
+
+ // The current call site index being processed, if any. 0 if none.
+ unsigned CurCallSite;
+
// TypeInfos - List of C++ TypeInfo used in the current function.
//
std::vector<GlobalVariable *> TypeInfos;
@@ -157,10 +171,6 @@ public:
bool doInitialization();
bool doFinalization();
- /// BeginFunction - Begin gathering function meta information.
- ///
- void BeginFunction(MachineFunction *) {}
-
/// EndFunction - Discard function meta information.
///
void EndFunction();
@@ -298,7 +308,26 @@ public:
const std::vector<LandingPadInfo> &getLandingPads() const {
return LandingPads;
}
-
+
+ /// setCallSiteBeginLabel - Map the begin label for a call site
+ void setCallSiteBeginLabel(unsigned BeginLabel, unsigned Site) {
+ CallSiteMap[BeginLabel] = Site;
+ }
+
+ /// getCallSiteBeginLabel - Get the call site number for a begin label
+ unsigned getCallSiteBeginLabel(unsigned BeginLabel) {
+ assert(CallSiteMap.count(BeginLabel) &&
+ "Missing call site number for EH_LABEL!");
+ return CallSiteMap[BeginLabel];
+ }
+
+ /// setCurrentCallSite - Set the call site currently being processed.
+ void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }
+
+ /// getCurrentCallSite - Get the call site currently being processed, if any.
+ /// return zero if none.
+ unsigned getCurrentCallSite(void) { return CurCallSite; }
+
/// getTypeInfos - Return a reference to the C++ typeinfo for the current
/// function.
const std::vector<GlobalVariable *> &getTypeInfos() const {
diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h
index 44813cb..89b8207 100644
--- a/include/llvm/CodeGen/MachineModuleInfoImpls.h
+++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -19,46 +19,43 @@
namespace llvm {
class MCSymbol;
-
+
/// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation
/// for MachO targets.
class MachineModuleInfoMachO : public MachineModuleInfoImpl {
/// FnStubs - Darwin '$stub' stubs. The key is something like "Lfoo$stub",
/// the value is something like "_foo".
- DenseMap<const MCSymbol*, const MCSymbol*> FnStubs;
+ DenseMap<MCSymbol*, MCSymbol*> FnStubs;
/// GVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like
/// "Lfoo$non_lazy_ptr", the value is something like "_foo".
- DenseMap<const MCSymbol*, const MCSymbol*> GVStubs;
+ DenseMap<MCSymbol*, MCSymbol*> GVStubs;
/// HiddenGVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like
/// "Lfoo$non_lazy_ptr", the value is something like "_foo". Unlike GVStubs
/// these are for things with hidden visibility.
- DenseMap<const MCSymbol*, const MCSymbol*> HiddenGVStubs;
+ DenseMap<MCSymbol*, MCSymbol*> HiddenGVStubs;
virtual void Anchor(); // Out of line virtual method.
public:
MachineModuleInfoMachO(const MachineModuleInfo &) {}
- const MCSymbol *&getFnStubEntry(const MCSymbol *Sym) {
+ MCSymbol *&getFnStubEntry(MCSymbol *Sym) {
assert(Sym && "Key cannot be null");
return FnStubs[Sym];
}
- const MCSymbol *&getGVStubEntry(const MCSymbol *Sym) {
+ MCSymbol *&getGVStubEntry(MCSymbol *Sym) {
assert(Sym && "Key cannot be null");
return GVStubs[Sym];
}
- const MCSymbol *&getHiddenGVStubEntry(const MCSymbol *Sym) {
+ MCSymbol *&getHiddenGVStubEntry(MCSymbol *Sym) {
assert(Sym && "Key cannot be null");
return HiddenGVStubs[Sym];
}
-
+
/// Accessor methods to return the set of stubs in sorted order.
- typedef std::vector<std::pair<const MCSymbol*, const MCSymbol*> >
- SymbolListTy;
-
SymbolListTy GetFnStubList() const {
return GetSortedStubs(FnStubs);
}
@@ -68,12 +65,31 @@ namespace llvm {
SymbolListTy GetHiddenGVStubList() const {
return GetSortedStubs(HiddenGVStubs);
}
-
- private:
- static SymbolListTy
- GetSortedStubs(const DenseMap<const MCSymbol*, const MCSymbol*> &Map);
};
-
+
+ /// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation
+ /// for ELF targets.
+ class MachineModuleInfoELF : public MachineModuleInfoImpl {
+ /// GVStubs - These stubs are used to materialize global addresses in PIC
+ /// mode.
+ DenseMap<MCSymbol*, MCSymbol*> GVStubs;
+
+ virtual void Anchor(); // Out of line virtual method.
+ public:
+ MachineModuleInfoELF(const MachineModuleInfo &) {}
+
+ MCSymbol *&getGVStubEntry(MCSymbol *Sym) {
+ assert(Sym && "Key cannot be null");
+ return GVStubs[Sym];
+ }
+
+ /// Accessor methods to return the set of stubs in sorted order.
+
+ SymbolListTy GetGVStubList() const {
+ return GetSortedStubs(GVStubs);
+ }
+ };
+
} // end namespace llvm
#endif
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 07d886d..dac0092 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -87,6 +87,10 @@ private:
/// model the GCC inline asm '&' constraint modifier.
bool IsEarlyClobber : 1;
+ /// IsDebug - True if this MO_Register 'use' operand is in a debug pseudo,
+ /// not a real instruction. Such uses should be ignored during codegen.
+ bool IsDebug : 1;
+
/// ParentMI - This is the instruction that this operand is embedded into.
/// This is valid for all operand types, when the operand is in an instr.
MachineInstr *ParentMI;
@@ -214,6 +218,11 @@ public:
return IsEarlyClobber;
}
+ bool isDebug() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return IsDebug;
+ }
+
/// getNextOperandForReg - Return the next MachineOperand in the function that
/// uses or defines this register.
MachineOperand *getNextOperandForReg() const {
@@ -236,11 +245,13 @@ public:
void setIsUse(bool Val = true) {
assert(isReg() && "Wrong MachineOperand accessor");
+ assert((Val || !isDebug()) && "Marking a debug operation as def");
IsDef = !Val;
}
void setIsDef(bool Val = true) {
assert(isReg() && "Wrong MachineOperand accessor");
+ assert((!Val || !isDebug()) && "Marking a debug operation as def");
IsDef = Val;
}
@@ -251,6 +262,7 @@ public:
void setIsKill(bool Val = true) {
assert(isReg() && !IsDef && "Wrong MachineOperand accessor");
+ assert((!Val || !isDebug()) && "Marking a debug operation as kill");
IsKill = Val;
}
@@ -366,7 +378,7 @@ public:
/// the setReg method should be used.
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
bool isKill = false, bool isDead = false,
- bool isUndef = false);
+ bool isUndef = false, bool isDebug = false);
//===--------------------------------------------------------------------===//
// Construction methods.
@@ -388,7 +400,8 @@ public:
bool isKill = false, bool isDead = false,
bool isUndef = false,
bool isEarlyClobber = false,
- unsigned SubReg = 0) {
+ unsigned SubReg = 0,
+ bool isDebug = false) {
MachineOperand Op(MachineOperand::MO_Register);
Op.IsDef = isDef;
Op.IsImp = isImp;
@@ -396,6 +409,7 @@ public:
Op.IsDead = isDead;
Op.IsUndef = isUndef;
Op.IsEarlyClobber = isEarlyClobber;
+ Op.IsDebug = isDebug;
Op.Contents.Reg.RegNo = Reg;
Op.Contents.Reg.Prev = 0;
Op.Contents.Reg.Next = 0;
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index c55cb32..01dc018 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -78,12 +78,12 @@ public:
/// reg_begin/reg_end - Provide iteration support to walk over all definitions
/// and uses of a register within the MachineFunction that corresponds to this
/// MachineRegisterInfo object.
- template<bool Uses, bool Defs>
+ template<bool Uses, bool Defs, bool SkipDebug>
class defusechain_iterator;
/// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
/// register.
- typedef defusechain_iterator<true,true> reg_iterator;
+ typedef defusechain_iterator<true,true,false> reg_iterator;
reg_iterator reg_begin(unsigned RegNo) const {
return reg_iterator(getRegUseDefListHead(RegNo));
}
@@ -94,7 +94,7 @@ public:
bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); }
/// def_iterator/def_begin/def_end - Walk all defs of the specified register.
- typedef defusechain_iterator<false,true> def_iterator;
+ typedef defusechain_iterator<false,true,false> def_iterator;
def_iterator def_begin(unsigned RegNo) const {
return def_iterator(getRegUseDefListHead(RegNo));
}
@@ -105,7 +105,7 @@ public:
bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
/// use_iterator/use_begin/use_end - Walk all uses of the specified register.
- typedef defusechain_iterator<true,false> use_iterator;
+ typedef defusechain_iterator<true,false,false> use_iterator;
use_iterator use_begin(unsigned RegNo) const {
return use_iterator(getRegUseDefListHead(RegNo));
}
@@ -115,7 +115,20 @@ public:
/// register.
bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); }
+ /// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
+ /// specified register, skipping those marked as Debug.
+ typedef defusechain_iterator<true,false,true> use_nodbg_iterator;
+ use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const {
+ return use_nodbg_iterator(getRegUseDefListHead(RegNo));
+ }
+ static use_nodbg_iterator use_nodbg_end() { return use_nodbg_iterator(0); }
+ /// use_nodbg_empty - Return true if there are no non-Debug instructions
+ /// using the specified register.
+ bool use_nodbg_empty(unsigned RegNo) const {
+ return use_nodbg_begin(RegNo) == use_nodbg_end();
+ }
+
/// replaceRegWith - Replace all instances of FromReg with ToReg in the
/// machine function. This is like llvm-level X->replaceAllUsesWith(Y),
/// except that it also changes any definitions of the register as well.
@@ -258,8 +271,9 @@ public:
/// operands in the function that use or define a specific register. If
/// ReturnUses is true it returns uses of registers, if ReturnDefs is true it
/// returns defs. If neither are true then you are silly and it always
- /// returns end().
- template<bool ReturnUses, bool ReturnDefs>
+ /// returns end(). If SkipDebug is true it skips uses marked Debug
+ /// when incrementing.
+ template<bool ReturnUses, bool ReturnDefs, bool SkipDebug>
class defusechain_iterator
: public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
MachineOperand *Op;
@@ -268,7 +282,8 @@ public:
// we are interested in.
if (op) {
if ((!ReturnUses && op->isUse()) ||
- (!ReturnDefs && op->isDef()))
+ (!ReturnDefs && op->isDef()) ||
+ (SkipDebug && op->isDebug()))
++*this;
}
}
@@ -299,7 +314,8 @@ public:
// If this is an operand we don't care about, skip it.
while (Op && ((!ReturnUses && Op->isUse()) ||
- (!ReturnDefs && Op->isDef())))
+ (!ReturnDefs && Op->isDef()) ||
+ (SkipDebug && Op->isDebug())))
Op = Op->getNextOperandForReg();
return *this;
diff --git a/include/llvm/CodeGen/MachineRelocation.h b/include/llvm/CodeGen/MachineRelocation.h
index 1c15fab..c316785 100644
--- a/include/llvm/CodeGen/MachineRelocation.h
+++ b/include/llvm/CodeGen/MachineRelocation.h
@@ -138,14 +138,15 @@ public:
///
static MachineRelocation getExtSym(uintptr_t offset, unsigned RelocationType,
const char *ES, intptr_t cst = 0,
- bool GOTrelative = 0) {
+ bool GOTrelative = 0,
+ bool NeedStub = true) {
assert((RelocationType & ~63) == 0 && "Relocation type too large!");
MachineRelocation Result;
Result.Offset = offset;
Result.ConstantVal = cst;
Result.TargetReloType = RelocationType;
Result.AddrType = isExtSym;
- Result.MayNeedFarStub = true;
+ Result.MayNeedFarStub = NeedStub;
Result.GOTRelative = GOTrelative;
Result.TargetResolve = false;
Result.Target.ExtSym = ES;
diff --git a/include/llvm/CodeGen/ObjectCodeEmitter.h b/include/llvm/CodeGen/ObjectCodeEmitter.h
index 8252e07..170c0c8 100644
--- a/include/llvm/CodeGen/ObjectCodeEmitter.h
+++ b/include/llvm/CodeGen/ObjectCodeEmitter.h
@@ -81,7 +81,7 @@ public:
/// written to the data stream in big-endian format.
void emitDWordBE(uint64_t W);
- /// emitAlignment - Move the CurBufferPtr pointer up the the specified
+ /// emitAlignment - Move the CurBufferPtr pointer up to the specified
/// alignment (saturated to BufferEnd of course).
void emitAlignment(unsigned Alignment = 0, uint8_t fill = 0);
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 7e0da3f..dbc73cb 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -174,6 +174,10 @@ namespace llvm {
/// optimization by increasing uses of extended values.
FunctionPass *createOptimizeExtsPass();
+ /// createOptimizePHIsPass - This pass optimizes machine instruction PHIs
+ /// to take advantage of opportunities created during DAG legalization.
+ FunctionPass *createOptimizePHIsPass();
+
/// createStackSlotColoringPass - This pass performs stack slot coloring.
FunctionPass *createStackSlotColoringPass(bool);
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 33ebd00..e628603 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -581,18 +581,18 @@ public:
/// determined by their operands, and they produce a value AND a token chain.
///
SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
- const Value *SV, int SVOffset, bool isVolatile=false,
- unsigned Alignment=0);
+ const Value *SV, int SVOffset, bool isVolatile,
+ bool isNonTemporal, unsigned Alignment);
SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT,
- SDValue Chain, SDValue Ptr, const Value *SV,
- int SVOffset, EVT MemVT, bool isVolatile=false,
- unsigned Alignment=0);
+ SDValue Chain, SDValue Ptr, const Value *SV,
+ int SVOffset, EVT MemVT, bool isVolatile,
+ bool isNonTemporal, unsigned Alignment);
SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
SDValue Offset, ISD::MemIndexedMode AM);
SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType,
EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset,
const Value *SV, int SVOffset, EVT MemVT,
- bool isVolatile=false, unsigned Alignment=0);
+ bool isVolatile, bool isNonTemporal, unsigned Alignment);
SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType,
EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset,
EVT MemVT, MachineMemOperand *MMO);
@@ -600,13 +600,14 @@ public:
/// getStore - Helper function to build ISD::STORE nodes.
///
SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
- const Value *SV, int SVOffset, bool isVolatile=false,
- unsigned Alignment=0);
+ const Value *SV, int SVOffset, bool isVolatile,
+ bool isNonTemporal, unsigned Alignment);
SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
MachineMemOperand *MMO);
SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
- const Value *SV, int SVOffset, EVT TVT,
- bool isVolatile=false, unsigned Alignment=0);
+ const Value *SV, int SVOffset, EVT TVT,
+ bool isNonTemporal, bool isVolatile,
+ unsigned Alignment);
SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
EVT TVT, MachineMemOperand *MMO);
SDValue getIndexedStore(SDValue OrigStoe, DebugLoc dl, SDValue Base,
@@ -841,7 +842,7 @@ public:
}
/// AssignOrdering - Assign an order to the SDNode.
- void AssignOrdering(SDNode *SD, unsigned Order);
+ void AssignOrdering(const SDNode *SD, unsigned Order);
/// GetOrdering - Get the order for the SDNode.
unsigned GetOrdering(const SDNode *SD) const;
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index b33b21d..0be91b4 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -85,11 +85,13 @@ public:
return true;
}
- /// IsLegalAndProfitableToFold - Returns true if the specific operand node N of
- /// U can be folded during instruction selection that starts at Root and
- /// folding N is profitable.
- virtual
- bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const;
+ /// IsProfitableToFold - Returns true if it's profitable to fold the specific
+ /// operand node N of U during instruction selection that starts at Root.
+ virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const;
+
+ /// IsLegalToFold - Returns true if the specific operand node N of
+ /// U can be folded during instruction selection that starts at Root.
+ virtual bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const;
/// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
/// to use for this target when scheduling the DAG.
@@ -110,6 +112,25 @@ protected:
bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
int64_t DesiredMaskS) const;
+
+ /// CheckPatternPredicate - This function is generated by tblgen in the
+ /// target. It runs the specified pattern predicate and returns true if it
+ /// succeeds or false if it fails. The number is a private implementation
+ /// detail to the code tblgen produces.
+ virtual bool CheckPatternPredicate(unsigned PredNo) const {
+ assert(0 && "Tblgen should generate the implementation of this!");
+ return 0;
+ }
+
+ /// CheckNodePredicate - This function is generated by tblgen in the
+ /// target. It runs node predicate #PredNo and returns true if it succeeds or
+ /// false if it fails. The number is a private implementation
+ /// detail to the code tblgen produces.
+ virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {
+ assert(0 && "Tblgen should generate the implementation of this!");
+ return 0;
+ }
+
// Calls to these functions are generated by tblgen.
SDNode *Select_INLINEASM(SDNode *N);
SDNode *Select_UNDEF(SDNode *N);
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 45a9d40..df1f91b 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -609,7 +609,7 @@ namespace ISD {
/// which do not reference a specific memory location should be less than
/// this value. Those that do must not be less than this value, and can
/// be used with SelectionDAG::getMemIntrinsicNode.
- static const int FIRST_TARGET_MEMORY_OPCODE = 1 << 14;
+ static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+80;
/// Node predicates
@@ -821,6 +821,8 @@ public:
/// set the SDNode
void setNode(SDNode *N) { Node = N; }
+ inline SDNode *operator->() const { return Node; }
+
bool operator==(const SDValue &O) const {
return Node == O.Node && ResNo == O.ResNo;
}
@@ -1594,6 +1596,7 @@ public:
}
bool isVolatile() const { return (SubclassData >> 5) & 1; }
+ bool isNonTemporal() const { return MMO->isNonTemporal(); }
/// Returns the SrcValue and offset that describes the location of the access
const Value *getSrcValue() const { return MMO->getValue(); }
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
index 163642a..dd4caba 100644
--- a/include/llvm/CodeGen/SlotIndexes.h
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -72,10 +72,13 @@ namespace llvm {
}
}
+ bool isValid() const {
+ return (index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX);
+ }
+
MachineInstr* getInstr() const { return mi; }
void setInstr(MachineInstr *mi) {
- assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
- "Attempt to modify reserved index.");
+ assert(isValid() && "Attempt to modify reserved index.");
this->mi = mi;
}
@@ -83,25 +86,21 @@ namespace llvm {
void setIndex(unsigned index) {
assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
"Attempt to set index to invalid value.");
- assert(this->index != EMPTY_KEY_INDEX &&
- this->index != TOMBSTONE_KEY_INDEX &&
- "Attempt to reset reserved index value.");
+ assert(isValid() && "Attempt to reset reserved index value.");
this->index = index;
}
IndexListEntry* getNext() { return next; }
const IndexListEntry* getNext() const { return next; }
void setNext(IndexListEntry *next) {
- assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
- "Attempt to modify reserved index.");
+ assert(isValid() && "Attempt to modify reserved index.");
this->next = next;
}
IndexListEntry* getPrev() { return prev; }
const IndexListEntry* getPrev() const { return prev; }
void setPrev(IndexListEntry *prev) {
- assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
- "Attempt to modify reserved index.");
+ assert(isValid() && "Attempt to modify reserved index.");
this->prev = prev;
}
@@ -192,7 +191,8 @@ namespace llvm {
/// Returns true if this is a valid index. Invalid indicies do
/// not point into an index table, and cannot be compared.
bool isValid() const {
- return (lie.getPointer() != 0) && (lie.getPointer()->getIndex() != 0);
+ IndexListEntry *entry = lie.getPointer();
+ return ((entry!= 0) && (entry->isValid()));
}
/// Print this index to the given raw_ostream.
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
new file mode 100644
index 0000000..c5aa626
--- /dev/null
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -0,0 +1,202 @@
+//==-- llvm/CodeGen/TargetLoweringObjectFileImpl.h - Object Info -*- 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 classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
+#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+
+namespace llvm {
+ class MachineModuleInfo;
+ class Mangler;
+ class MCAsmInfo;
+ class MCExpr;
+ class MCSection;
+ class MCSectionMachO;
+ class MCSymbol;
+ class MCContext;
+ class GlobalValue;
+ class TargetMachine;
+
+
+class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
+ mutable void *UniquingMap;
+protected:
+ /// TLSDataSection - Section directive for Thread Local data.
+ ///
+ const MCSection *TLSDataSection; // Defaults to ".tdata".
+
+ /// TLSBSSSection - Section directive for Thread Local uninitialized data.
+ /// Null if this target doesn't support a BSS section.
+ ///
+ const MCSection *TLSBSSSection; // Defaults to ".tbss".
+
+ const MCSection *DataRelSection;
+ const MCSection *DataRelLocalSection;
+ const MCSection *DataRelROSection;
+ const MCSection *DataRelROLocalSection;
+
+ const MCSection *MergeableConst4Section;
+ const MCSection *MergeableConst8Section;
+ const MCSection *MergeableConst16Section;
+
+protected:
+ const MCSection *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind Kind,
+ bool IsExplicit = false) const;
+public:
+ TargetLoweringObjectFileELF() : UniquingMap(0) {}
+ ~TargetLoweringObjectFileELF();
+
+ virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+
+ const MCSection *getDataRelSection() const { return DataRelSection; }
+
+ /// getSectionForConstant - Given a constant with the SectionKind, return a
+ /// section that it should be placed in.
+ virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
+
+
+ virtual const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a reference
+ /// to the specified global variable from exception handling information.
+ ///
+ virtual const MCExpr *
+ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding) const;
+};
+
+
+
+class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
+ mutable void *UniquingMap;
+
+ const MCSection *CStringSection;
+ const MCSection *UStringSection;
+ const MCSection *TextCoalSection;
+ const MCSection *ConstTextCoalSection;
+ const MCSection *ConstDataCoalSection;
+ const MCSection *ConstDataSection;
+ const MCSection *DataCoalSection;
+ const MCSection *DataCommonSection;
+ const MCSection *DataBSSSection;
+ const MCSection *FourByteConstantSection;
+ const MCSection *EightByteConstantSection;
+ const MCSection *SixteenByteConstantSection;
+
+ const MCSection *LazySymbolPointerSection;
+ const MCSection *NonLazySymbolPointerSection;
+public:
+ TargetLoweringObjectFileMachO() : UniquingMap(0) {}
+ ~TargetLoweringObjectFileMachO();
+
+ virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+
+ virtual const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
+
+ /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
+ /// decide not to emit the UsedDirective for some symbols in llvm.used.
+ /// FIXME: REMOVE this (rdar://7071300)
+ virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
+ Mangler *) const;
+
+ /// getMachOSection - Return the MCSection for the specified mach-o section.
+ /// This requires the operands to be valid.
+ const MCSectionMachO *getMachOSection(StringRef Segment,
+ StringRef Section,
+ unsigned TypeAndAttributes,
+ SectionKind K) const {
+ return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
+ }
+ const MCSectionMachO *getMachOSection(StringRef Segment,
+ StringRef Section,
+ unsigned TypeAndAttributes,
+ unsigned Reserved2,
+ SectionKind K) const;
+
+ /// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak
+ /// text symbols into.
+ const MCSection *getTextCoalSection() const {
+ return TextCoalSection;
+ }
+
+ /// getConstTextCoalSection - Return the "__TEXT,__const_coal" section
+ /// we put weak read-only symbols into.
+ const MCSection *getConstTextCoalSection() const {
+ return ConstTextCoalSection;
+ }
+
+ /// getLazySymbolPointerSection - Return the section corresponding to
+ /// the .lazy_symbol_pointer directive.
+ const MCSection *getLazySymbolPointerSection() const {
+ return LazySymbolPointerSection;
+ }
+
+ /// getNonLazySymbolPointerSection - Return the section corresponding to
+ /// the .non_lazy_symbol_pointer directive.
+ const MCSection *getNonLazySymbolPointerSection() const {
+ return NonLazySymbolPointerSection;
+ }
+
+ /// getSymbolForDwarfGlobalReference - The mach-o version of this method
+ /// defaults to returning a stub reference.
+ virtual const MCExpr *
+ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding) const;
+};
+
+
+
+class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
+ mutable void *UniquingMap;
+public:
+ TargetLoweringObjectFileCOFF() : UniquingMap(0) {}
+ ~TargetLoweringObjectFileCOFF();
+
+ virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+
+ virtual const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ /// getCOFFSection - Return the MCSection for the specified COFF section.
+ /// FIXME: Switch this to a semantic view eventually.
+ const MCSection *getCOFFSection(StringRef Name, bool isDirective,
+ SectionKind K) const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index 0125190..a7aafc0 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -492,26 +492,31 @@ namespace llvm {
/// bitsEq - Return true if this has the same number of bits as VT.
bool bitsEq(EVT VT) const {
+ if (EVT::operator==(VT)) return true;
return getSizeInBits() == VT.getSizeInBits();
}
/// bitsGT - Return true if this has more bits than VT.
bool bitsGT(EVT VT) const {
+ if (EVT::operator==(VT)) return false;
return getSizeInBits() > VT.getSizeInBits();
}
/// bitsGE - Return true if this has no less bits than VT.
bool bitsGE(EVT VT) const {
+ if (EVT::operator==(VT)) return true;
return getSizeInBits() >= VT.getSizeInBits();
}
/// bitsLT - Return true if this has less bits than VT.
bool bitsLT(EVT VT) const {
+ if (EVT::operator==(VT)) return false;
return getSizeInBits() < VT.getSizeInBits();
}
/// bitsLE - Return true if this has no more bits than VT.
bool bitsLE(EVT VT) const {
+ if (EVT::operator==(VT)) return true;
return getSizeInBits() <= VT.getSizeInBits();
}
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index 8051f55..ce4f374 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -1,13 +1,5 @@
/* include/llvm/Config/config.h.in. Generated from autoconf/configure.ac by autoheader. */
-/* Define if dlopen(0) will open the symbols of the program */
-#undef CAN_DLOPEN_SELF
-
-/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
- systems. This function is required for `alloca.c' support on those systems.
- */
-#undef CRAY_STACKSEG_END
-
/* 32 bit multilib directory. */
#undef CXX_INCLUDE_32BIT_DIR
@@ -20,9 +12,6 @@
/* Directory with the libstdc++ headers. */
#undef CXX_INCLUDE_ROOT
-/* Define to 1 if using `alloca.c'. */
-#undef C_ALLOCA
-
/* Directories clang will search for headers */
#undef C_INCLUDE_DIRS
@@ -35,13 +24,6 @@
/* Define if threads enabled */
#undef ENABLE_THREADS
-/* Define to 1 if you have `alloca', as a function or macro. */
-#undef HAVE_ALLOCA
-
-/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
- */
-#undef HAVE_ALLOCA_H
-
/* Define to 1 if you have the `argz_append' function. */
#undef HAVE_ARGZ_APPEND
@@ -69,9 +51,6 @@
/* Define to 1 if you have the `bcopy' function. */
#undef HAVE_BCOPY
-/* Does not have bi-directional iterator */
-#undef HAVE_BI_ITERATOR
-
/* Define to 1 if you have the `ceilf' function. */
#undef HAVE_CEILF
@@ -148,9 +127,6 @@
/* Define to 1 if you have the `fmodf' function. */
#undef HAVE_FMODF
-/* Does not have forward iterator */
-#undef HAVE_FWD_ITERATOR
-
/* Define to 1 if you have the `getcwd' function. */
#undef HAVE_GETCWD
@@ -276,9 +252,6 @@
/* Define if mmap() can map files into memory */
#undef HAVE_MMAP_FILE
-/* define if the compiler implements namespaces */
-#undef HAVE_NAMESPACES
-
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
@@ -375,9 +348,6 @@
/* Set to 1 if the std::isnan function is found in <cmath> */
#undef HAVE_STD_ISNAN_IN_CMATH
-/* Does not have std namespace iterator */
-#undef HAVE_STD_ITERATOR
-
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
@@ -587,14 +557,6 @@
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
-/* If using the C implementation of alloca, define if you know the
- direction of stack growth for your system; otherwise it will be
- automatically deduced at runtime.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown */
-#undef STACK_DIRECTION
-
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
#undef STAT_MACROS_BROKEN
diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h
index 8072fd9..8647299 100644
--- a/include/llvm/Constant.h
+++ b/include/llvm/Constant.h
@@ -104,8 +104,7 @@ public:
/// type, returns the elements of the vector in the specified smallvector.
/// This handles breaking down a vector undef into undef elements, etc. For
/// constant exprs and other cases we can't handle, we return an empty vector.
- void getVectorElements(LLVMContext &Context,
- SmallVectorImpl<Constant*> &Elts) const;
+ void getVectorElements(SmallVectorImpl<Constant*> &Elts) const;
/// destroyConstant - Called if some element of this constant is no longer
/// valid. At this point only other constants may be on the use_list for this
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index f34f9cb..bd14303d 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -33,6 +33,7 @@ namespace llvm {
class ArrayType;
class IntegerType;
class StructType;
+class UnionType;
class PointerType;
class VectorType;
@@ -453,6 +454,50 @@ struct OperandTraits<ConstantStruct> : public VariadicOperandTraits<> {
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant)
//===----------------------------------------------------------------------===//
+// ConstantUnion - Constant Union Declarations
+//
+class ConstantUnion : public Constant {
+ friend struct ConstantCreator<ConstantUnion, UnionType, Constant*>;
+ ConstantUnion(const ConstantUnion &); // DO NOT IMPLEMENT
+protected:
+ ConstantUnion(const UnionType *T, Constant* Val);
+public:
+ // ConstantUnion accessors
+ static Constant *get(const UnionType *T, Constant* V);
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+ /// getType() specialization - Reduce amount of casting...
+ ///
+ inline const UnionType *getType() const {
+ return reinterpret_cast<const UnionType*>(Value::getType());
+ }
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue. This always returns false because zero structs are always
+ /// created as ConstantAggregateZero objects.
+ virtual bool isNullValue() const {
+ return false;
+ }
+
+ virtual void destroyConstant();
+ virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ConstantUnion *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantUnionVal;
+ }
+};
+
+template <>
+struct OperandTraits<ConstantUnion> : public FixedNumOperandTraits<1> {
+};
+
+DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantUnion, Constant)
+
+//===----------------------------------------------------------------------===//
/// ConstantVector - Constant Vector Declarations
///
class ConstantVector : public Constant {
@@ -644,8 +689,7 @@ public:
///
/// getAlignOf constant expr - computes the alignment of a type in a target
- /// independent way (Note: the return type is an i32; Note: assumes that i8
- /// is byte aligned).
+ /// independent way (Note: the return type is an i64).
static Constant *getAlignOf(const Type* Ty);
/// getSizeOf constant expr - computes the size of a type in a target
@@ -653,10 +697,15 @@ public:
///
static Constant *getSizeOf(const Type* Ty);
- /// getOffsetOf constant expr - computes the offset of a field in a target
- /// independent way (Note: the return type is an i64).
+ /// getOffsetOf constant expr - computes the offset of a struct field in a
+ /// target independent way (Note: the return type is an i64).
+ ///
+ static Constant *getOffsetOf(const StructType* STy, unsigned FieldNo);
+
+ /// getOffsetOf constant expr - This is a generalized form of getOffsetOf,
+ /// which supports any aggregate type, and any Constant index.
///
- static Constant *getOffsetOf(const StructType* Ty, unsigned FieldNo);
+ static Constant *getOffsetOf(const Type* Ty, Constant *FieldNo);
static Constant *getNeg(Constant *C);
static Constant *getFNeg(Constant *C);
@@ -693,9 +742,13 @@ public:
static Constant *getBitCast (Constant *C, const Type *Ty);
static Constant *getNSWNeg(Constant *C);
+ static Constant *getNUWNeg(Constant *C);
static Constant *getNSWAdd(Constant *C1, Constant *C2);
+ static Constant *getNUWAdd(Constant *C1, Constant *C2);
static Constant *getNSWSub(Constant *C1, Constant *C2);
+ static Constant *getNUWSub(Constant *C1, Constant *C2);
static Constant *getNSWMul(Constant *C1, Constant *C2);
+ static Constant *getNUWMul(Constant *C1, Constant *C2);
static Constant *getExactSDiv(Constant *C1, Constant *C2);
/// Transparently provide more efficient getOperand methods.
diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h
index c220608..912bb6d 100644
--- a/include/llvm/DerivedTypes.h
+++ b/include/llvm/DerivedTypes.h
@@ -27,6 +27,7 @@ template<class ValType, class TypeClass> class TypeMap;
class FunctionValType;
class ArrayValType;
class StructValType;
+class UnionValType;
class PointerValType;
class VectorValType;
class IntegerValType;
@@ -229,7 +230,8 @@ public:
return T->getTypeID() == ArrayTyID ||
T->getTypeID() == StructTyID ||
T->getTypeID() == PointerTyID ||
- T->getTypeID() == VectorTyID;
+ T->getTypeID() == VectorTyID ||
+ T->getTypeID() == UnionTyID;
}
};
@@ -301,6 +303,63 @@ public:
};
+/// UnionType - Class to represent union types. A union type is similar to
+/// a structure, except that all member fields begin at offset 0.
+///
+class UnionType : public CompositeType {
+ friend class TypeMap<UnionValType, UnionType>;
+ UnionType(const UnionType &); // Do not implement
+ const UnionType &operator=(const UnionType &); // Do not implement
+ UnionType(LLVMContext &C, const Type* const* Types, unsigned NumTypes);
+public:
+ /// UnionType::get - This static method is the primary way to create a
+ /// UnionType.
+ static UnionType *get(const Type* const* Types, unsigned NumTypes);
+
+ /// UnionType::get - This static method is a convenience method for
+ /// creating union types by specifying the elements as arguments.
+ static UnionType *get(const Type *type, ...) END_WITH_NULL;
+
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(const Type *ElemTy);
+
+ /// Given an element type, return the member index of that type, or -1
+ /// if there is no such member type.
+ int getElementTypeIndex(const Type *ElemTy) const;
+
+ // Iterator access to the elements
+ typedef Type::subtype_iterator element_iterator;
+ element_iterator element_begin() const { return ContainedTys; }
+ element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
+
+ // Random access to the elements
+ unsigned getNumElements() const { return NumContainedTys; }
+ const Type *getElementType(unsigned N) const {
+ assert(N < NumContainedTys && "Element number out of range!");
+ return ContainedTys[N];
+ }
+
+ /// getTypeAtIndex - Given an index value into the type, return the type of
+ /// the element. For a union type, this must be a constant value...
+ ///
+ virtual const Type *getTypeAtIndex(const Value *V) const;
+ virtual const Type *getTypeAtIndex(unsigned Idx) const;
+ virtual bool indexValid(const Value *V) const;
+ virtual bool indexValid(unsigned Idx) const;
+
+ // Implement the AbstractTypeUser interface.
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+ virtual void typeBecameConcrete(const DerivedType *AbsTy);
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const UnionType *) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == UnionTyID;
+ }
+};
+
+
/// SequentialType - This is the superclass of the array, pointer and vector
/// type classes. All of these represent "arrays" in memory. The array type
/// represents a specifically sized array, pointer types are unsized/unknown
@@ -496,6 +555,7 @@ public:
/// OpaqueType - Class to represent abstract types
///
class OpaqueType : public DerivedType {
+ friend class LLVMContextImpl;
OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT
const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT
OpaqueType(LLVMContext &C);
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index d2c547d..c3f1902 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -19,6 +19,7 @@
#include <map>
#include <string>
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ValueMap.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/System/Mutex.h"
@@ -36,7 +37,6 @@ class JITEventListener;
class JITMemoryManager;
class MachineCodeInfo;
class Module;
-class ModuleProvider;
class MutexGuard;
class TargetData;
class Type;
@@ -95,9 +95,9 @@ class ExecutionEngine {
friend class EngineBuilder; // To allow access to JITCtor and InterpCtor.
protected:
- /// Modules - This is a list of ModuleProvider's that we are JIT'ing from. We
- /// use a smallvector to optimize for the case where there is only one module.
- SmallVector<ModuleProvider*, 1> Modules;
+ /// Modules - This is a list of Modules that we are JIT'ing from. We use a
+ /// smallvector to optimize for the case where there is only one module.
+ SmallVector<Module*, 1> Modules;
void setTargetData(const TargetData *td) {
TD = td;
@@ -109,13 +109,17 @@ protected:
// To avoid having libexecutionengine depend on the JIT and interpreter
// libraries, the JIT and Interpreter set these functions to ctor pointers
// at startup time if they are linked in.
- static ExecutionEngine *(*JITCtor)(ModuleProvider *MP,
- std::string *ErrorStr,
- JITMemoryManager *JMM,
- CodeGenOpt::Level OptLevel,
- bool GVsWithCode,
- CodeModel::Model CMM);
- static ExecutionEngine *(*InterpCtor)(ModuleProvider *MP,
+ static ExecutionEngine *(*JITCtor)(
+ Module *M,
+ std::string *ErrorStr,
+ JITMemoryManager *JMM,
+ CodeGenOpt::Level OptLevel,
+ bool GVsWithCode,
+ CodeModel::Model CMM,
+ StringRef MArch,
+ StringRef MCPU,
+ const SmallVectorImpl<std::string>& MAttrs);
+ static ExecutionEngine *(*InterpCtor)(Module *M,
std::string *ErrorStr);
/// LazyFunctionCreator - If an unknown function is needed, this function
@@ -141,8 +145,8 @@ public:
/// create - This is the factory method for creating an execution engine which
/// is appropriate for the current machine. This takes ownership of the
- /// module provider.
- static ExecutionEngine *create(ModuleProvider *MP,
+ /// module.
+ static ExecutionEngine *create(Module *M,
bool ForceInterpreter = false,
std::string *ErrorStr = 0,
CodeGenOpt::Level OptLevel =
@@ -158,18 +162,13 @@ public:
// default freeMachineCodeForFunction works.
bool GVsWithCode = true);
- /// create - This is the factory method for creating an execution engine which
- /// is appropriate for the current machine. This takes ownership of the
- /// module.
- static ExecutionEngine *create(Module *M);
-
/// createJIT - This is the factory method for creating a JIT for the current
/// machine, it does not fall back to the interpreter. This takes ownership
- /// of the ModuleProvider and JITMemoryManager if successful.
+ /// of the Module and JITMemoryManager if successful.
///
/// Clients should make sure to initialize targets prior to calling this
/// function.
- static ExecutionEngine *createJIT(ModuleProvider *MP,
+ static ExecutionEngine *createJIT(Module *M,
std::string *ErrorStr = 0,
JITMemoryManager *JMM = 0,
CodeGenOpt::Level OptLevel =
@@ -178,11 +177,11 @@ public:
CodeModel::Model CMM =
CodeModel::Default);
- /// addModuleProvider - Add a ModuleProvider to the list of modules that we
- /// can JIT from. Note that this takes ownership of the ModuleProvider: when
- /// the ExecutionEngine is destroyed, it destroys the MP as well.
- virtual void addModuleProvider(ModuleProvider *P) {
- Modules.push_back(P);
+ /// addModule - Add a Module to the list of modules that we can JIT from.
+ /// Note that this takes ownership of the Module: when the ExecutionEngine is
+ /// destroyed, it destroys the Module as well.
+ virtual void addModule(Module *M) {
+ Modules.push_back(M);
}
//===----------------------------------------------------------------------===//
@@ -190,16 +189,9 @@ public:
const TargetData *getTargetData() const { return TD; }
- /// removeModuleProvider - Remove a ModuleProvider from the list of modules.
- /// Relases the Module from the ModuleProvider, materializing it in the
- /// process, and returns the materialized Module.
- virtual Module* removeModuleProvider(ModuleProvider *P,
- std::string *ErrInfo = 0);
-
- /// deleteModuleProvider - Remove a ModuleProvider from the list of modules,
- /// and deletes the ModuleProvider and owned Module. Avoids materializing
- /// the underlying module.
- virtual void deleteModuleProvider(ModuleProvider *P,std::string *ErrInfo = 0);
+ /// removeModule - Remove a Module from the list of modules. Returns true if
+ /// M is found.
+ virtual bool removeModule(Module *M);
/// FindFunctionNamed - Search all of the active modules to find the one that
/// defines FnName. This is very slow operation and shouldn't be used for
@@ -393,7 +385,7 @@ public:
}
protected:
- explicit ExecutionEngine(ModuleProvider *P);
+ explicit ExecutionEngine(Module *M);
void emitGlobals();
@@ -422,13 +414,16 @@ namespace EngineKind {
class EngineBuilder {
private:
- ModuleProvider *MP;
+ Module *M;
EngineKind::Kind WhichEngine;
std::string *ErrorStr;
CodeGenOpt::Level OptLevel;
JITMemoryManager *JMM;
bool AllocateGVsWithCode;
CodeModel::Model CMModel;
+ std::string MArch;
+ std::string MCPU;
+ SmallVector<std::string, 4> MAttrs;
/// InitEngine - Does the common initialization of default options.
///
@@ -443,16 +438,11 @@ class EngineBuilder {
public:
/// EngineBuilder - Constructor for EngineBuilder. If create() is called and
- /// is successful, the created engine takes ownership of the module
- /// provider.
- EngineBuilder(ModuleProvider *mp) : MP(mp) {
+ /// is successful, the created engine takes ownership of the module.
+ EngineBuilder(Module *m) : M(m) {
InitEngine();
}
- /// EngineBuilder - Overloaded constructor that automatically creates an
- /// ExistingModuleProvider for an existing module.
- EngineBuilder(Module *m);
-
/// setEngineKind - Controls whether the user wants the interpreter, the JIT,
/// or whichever engine works. This option defaults to EngineKind::Either.
EngineBuilder &setEngineKind(EngineKind::Kind w) {
@@ -502,6 +492,26 @@ class EngineBuilder {
return *this;
}
+ /// setMArch - Override the architecture set by the Module's triple.
+ EngineBuilder &setMArch(StringRef march) {
+ MArch.assign(march.begin(), march.end());
+ return *this;
+ }
+
+ /// setMCPU - Target a specific cpu type.
+ EngineBuilder &setMCPU(StringRef mcpu) {
+ MCPU.assign(mcpu.begin(), mcpu.end());
+ return *this;
+ }
+
+ /// setMAttrs - Set cpu-specific attributes.
+ template<typename StringSequence>
+ EngineBuilder &setMAttrs(const StringSequence &mattrs) {
+ MAttrs.clear();
+ MAttrs.append(mattrs.begin(), mattrs.end());
+ return *this;
+ }
+
ExecutionEngine *create();
};
diff --git a/include/llvm/GVMaterializer.h b/include/llvm/GVMaterializer.h
new file mode 100644
index 0000000..c143552
--- /dev/null
+++ b/include/llvm/GVMaterializer.h
@@ -0,0 +1,66 @@
+//===-- llvm/GVMaterializer.h - Interface for GV materializers --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an abstract interface for loading a module from some
+// place. This interface allows incremental or random access loading of
+// functions from the file. This is useful for applications like JIT compilers
+// or interprocedural optimizers that do not need the entire program in memory
+// at the same time.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef GVMATERIALIZER_H
+#define GVMATERIALIZER_H
+
+#include <string>
+
+namespace llvm {
+
+class Function;
+class GlobalValue;
+class Module;
+
+class GVMaterializer {
+protected:
+ GVMaterializer() {}
+
+public:
+ virtual ~GVMaterializer();
+
+ /// isMaterializable - True if GV can be materialized from whatever backing
+ /// store this GVMaterializer uses and has not been materialized yet.
+ virtual bool isMaterializable(const GlobalValue *GV) const = 0;
+
+ /// isDematerializable - True if GV has been materialized and can be
+ /// dematerialized back to whatever backing store this GVMaterializer uses.
+ virtual bool isDematerializable(const GlobalValue *GV) const = 0;
+
+ /// Materialize - make sure the given GlobalValue is fully read. If the
+ /// module is corrupt, this returns true and fills in the optional string with
+ /// information about the problem. If successful, this returns false.
+ ///
+ virtual bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0) = 0;
+
+ /// Dematerialize - If the given GlobalValue is read in, and if the
+ /// GVMaterializer supports it, release the memory for the GV, and set it up
+ /// to be materialized lazily. If the Materializer doesn't support this
+ /// capability, this method is a noop.
+ ///
+ virtual void Dematerialize(GlobalValue *) {}
+
+ /// MaterializeModule - make sure the entire Module has been completely read.
+ /// On error, this returns true and fills in the optional string with
+ /// information about the problem. If successful, this returns false.
+ ///
+ virtual bool MaterializeModule(Module *M, std::string *ErrInfo = 0) = 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h
index 9875a83..c15b555 100644
--- a/include/llvm/GlobalValue.h
+++ b/include/llvm/GlobalValue.h
@@ -43,7 +43,6 @@ public:
DLLImportLinkage, ///< Function to be imported from DLL
DLLExportLinkage, ///< Function to be accessible from DLL.
ExternalWeakLinkage,///< ExternalWeak linkage description.
- GhostLinkage, ///< Stand-in functions for streaming fns from BC files.
CommonLinkage ///< Tentative definitions.
};
@@ -93,7 +92,7 @@ public:
void setSection(StringRef S) { Section = S; }
/// If the usage is empty (except transitively dead constants), then this
- /// global value can can be safely deleted since the destructor will
+ /// global value can be safely deleted since the destructor will
/// delete the dead constants as well.
/// @brief Determine if the usage of this global value is empty except
/// for transitively dead constants.
@@ -132,7 +131,6 @@ public:
bool hasDLLImportLinkage() const { return Linkage == DLLImportLinkage; }
bool hasDLLExportLinkage() const { return Linkage == DLLExportLinkage; }
bool hasExternalWeakLinkage() const { return Linkage == ExternalWeakLinkage; }
- bool hasGhostLinkage() const { return Linkage == GhostLinkage; }
bool hasCommonLinkage() const { return Linkage == CommonLinkage; }
void setLinkage(LinkageTypes LT) { Linkage = LT; }
@@ -164,12 +162,33 @@ public:
/// create a GlobalValue) from the GlobalValue Src to this one.
virtual void copyAttributesFrom(const GlobalValue *Src);
- /// hasNotBeenReadFromBitcode - If a module provider is being used to lazily
- /// stream in functions from disk, this method can be used to check to see if
- /// the function has been read in yet or not. Unless you are working on the
- /// JIT or something else that streams stuff in lazily, you don't need to
- /// worry about this.
- bool hasNotBeenReadFromBitcode() const { return Linkage == GhostLinkage; }
+/// @name Materialization
+/// Materialization is used to construct functions only as they're needed. This
+/// is useful to reduce memory usage in LLVM or parsing work done by the
+/// BitcodeReader to load the Module.
+/// @{
+
+ /// isMaterializable - If this function's Module is being lazily streamed in
+ /// functions from disk or some other source, this method can be used to check
+ /// to see if the function has been read in yet or not.
+ bool isMaterializable() const;
+
+ /// isDematerializable - Returns true if this function was loaded from a
+ /// GVMaterializer that's still attached to its Module and that knows how to
+ /// dematerialize the function.
+ bool isDematerializable() const;
+
+ /// Materialize - make sure this GlobalValue is fully read. If the module is
+ /// corrupt, this returns true and fills in the optional string with
+ /// information about the problem. If successful, this returns false.
+ bool Materialize(std::string *ErrInfo = 0);
+
+ /// Dematerialize - If this GlobalValue is read in, and if the GVMaterializer
+ /// supports it, release the memory for the function, and set it up to be
+ /// materialized lazily. If !isDematerializable(), this method is a noop.
+ void Dematerialize();
+
+/// @}
/// Override from Constant class. No GlobalValue's are null values so this
/// always returns false.
diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h
index 482e53e..4490ce5 100644
--- a/include/llvm/InlineAsm.h
+++ b/include/llvm/InlineAsm.h
@@ -39,7 +39,7 @@ class InlineAsm : public Value {
virtual ~InlineAsm();
public:
- /// InlineAsm::get - Return the the specified uniqued inline asm string.
+ /// InlineAsm::get - Return the specified uniqued inline asm string.
///
static InlineAsm *get(const FunctionType *Ty, StringRef AsmString,
StringRef Constraints, bool hasSideEffects,
diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h
index b5cc659..49cdd6a 100644
--- a/include/llvm/InstrTypes.h
+++ b/include/llvm/InstrTypes.h
@@ -299,6 +299,27 @@ public:
return BO;
}
+ /// CreateNUWMul - Create a Mul operator with the NUW flag set.
+ ///
+ static BinaryOperator *CreateNUWMul(Value *V1, Value *V2,
+ const Twine &Name = "") {
+ BinaryOperator *BO = CreateMul(V1, V2, Name);
+ BO->setHasNoUnsignedWrap(true);
+ return BO;
+ }
+ static BinaryOperator *CreateNUWMul(Value *V1, Value *V2,
+ const Twine &Name, BasicBlock *BB) {
+ BinaryOperator *BO = CreateMul(V1, V2, Name, BB);
+ BO->setHasNoUnsignedWrap(true);
+ return BO;
+ }
+ static BinaryOperator *CreateNUWMul(Value *V1, Value *V2,
+ const Twine &Name, Instruction *I) {
+ BinaryOperator *BO = CreateMul(V1, V2, Name, I);
+ BO->setHasNoUnsignedWrap(true);
+ return BO;
+ }
+
/// CreateExactSDiv - Create an SDiv operator with the exact flag set.
///
static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
@@ -334,6 +355,10 @@ public:
Instruction *InsertBefore = 0);
static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name,
BasicBlock *InsertAtEnd);
+ static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name = "",
+ Instruction *InsertBefore = 0);
+ static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name,
+ BasicBlock *InsertAtEnd);
static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name = "",
Instruction *InsertBefore = 0);
static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name,
@@ -671,36 +696,36 @@ public:
/// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
/// predicate values are not overlapping between the classes.
enum Predicate {
- // Opcode U L G E Intuitive operation
- FCMP_FALSE = 0, /// 0 0 0 0 Always false (always folded)
- FCMP_OEQ = 1, /// 0 0 0 1 True if ordered and equal
- FCMP_OGT = 2, /// 0 0 1 0 True if ordered and greater than
- FCMP_OGE = 3, /// 0 0 1 1 True if ordered and greater than or equal
- FCMP_OLT = 4, /// 0 1 0 0 True if ordered and less than
- FCMP_OLE = 5, /// 0 1 0 1 True if ordered and less than or equal
- FCMP_ONE = 6, /// 0 1 1 0 True if ordered and operands are unequal
- FCMP_ORD = 7, /// 0 1 1 1 True if ordered (no nans)
- FCMP_UNO = 8, /// 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
- FCMP_UEQ = 9, /// 1 0 0 1 True if unordered or equal
- FCMP_UGT = 10, /// 1 0 1 0 True if unordered or greater than
- FCMP_UGE = 11, /// 1 0 1 1 True if unordered, greater than, or equal
- FCMP_ULT = 12, /// 1 1 0 0 True if unordered or less than
- FCMP_ULE = 13, /// 1 1 0 1 True if unordered, less than, or equal
- FCMP_UNE = 14, /// 1 1 1 0 True if unordered or not equal
- FCMP_TRUE = 15, /// 1 1 1 1 Always true (always folded)
+ // Opcode U L G E Intuitive operation
+ FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded)
+ FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal
+ FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than
+ FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal
+ FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than
+ FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal
+ FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal
+ FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans)
+ FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
+ FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal
+ FCMP_UGT = 10, ///< 1 0 1 0 True if unordered or greater than
+ FCMP_UGE = 11, ///< 1 0 1 1 True if unordered, greater than, or equal
+ FCMP_ULT = 12, ///< 1 1 0 0 True if unordered or less than
+ FCMP_ULE = 13, ///< 1 1 0 1 True if unordered, less than, or equal
+ FCMP_UNE = 14, ///< 1 1 1 0 True if unordered or not equal
+ FCMP_TRUE = 15, ///< 1 1 1 1 Always true (always folded)
FIRST_FCMP_PREDICATE = FCMP_FALSE,
LAST_FCMP_PREDICATE = FCMP_TRUE,
BAD_FCMP_PREDICATE = FCMP_TRUE + 1,
- ICMP_EQ = 32, /// equal
- ICMP_NE = 33, /// not equal
- ICMP_UGT = 34, /// unsigned greater than
- ICMP_UGE = 35, /// unsigned greater or equal
- ICMP_ULT = 36, /// unsigned less than
- ICMP_ULE = 37, /// unsigned less or equal
- ICMP_SGT = 38, /// signed greater than
- ICMP_SGE = 39, /// signed greater or equal
- ICMP_SLT = 40, /// signed less than
- ICMP_SLE = 41, /// signed less or equal
+ ICMP_EQ = 32, ///< equal
+ ICMP_NE = 33, ///< not equal
+ ICMP_UGT = 34, ///< unsigned greater than
+ ICMP_UGE = 35, ///< unsigned greater or equal
+ ICMP_ULT = 36, ///< unsigned less than
+ ICMP_ULE = 37, ///< unsigned less or equal
+ ICMP_SGT = 38, ///< signed greater than
+ ICMP_SGE = 39, ///< signed greater or equal
+ ICMP_SLT = 40, ///< signed less than
+ ICMP_SLE = 41, ///< signed less or equal
FIRST_ICMP_PREDICATE = ICMP_EQ,
LAST_ICMP_PREDICATE = ICMP_SLE,
BAD_ICMP_PREDICATE = ICMP_SLE + 1
diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h
index d45da97..cf9dc44 100644
--- a/include/llvm/Instruction.h
+++ b/include/llvm/Instruction.h
@@ -148,7 +148,7 @@ public:
getAllMetadataImpl(MDs);
}
- /// setMetadata - Set the metadata of of the specified kind to the specified
+ /// setMetadata - Set the metadata of the specified kind to the specified
/// node. This updates/replaces metadata if already present, or removes it if
/// Node is null.
void setMetadata(unsigned KindID, MDNode *Node);
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index c6cdbd5..1ae495f 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -590,7 +590,7 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
- assert((getOperand(0)->getType()->isIntOrIntVector() ||
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
isa<PointerType>(getOperand(0)->getType())) &&
"Invalid operand types for ICmp instruction");
}
@@ -611,7 +611,7 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
- assert((getOperand(0)->getType()->isIntOrIntVector() ||
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
isa<PointerType>(getOperand(0)->getType())) &&
"Invalid operand types for ICmp instruction");
}
@@ -630,7 +630,7 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
- assert((getOperand(0)->getType()->isIntOrIntVector() ||
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
isa<PointerType>(getOperand(0)->getType())) &&
"Invalid operand types for ICmp instruction");
}
@@ -740,7 +740,7 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to FCmp instruction are not of the same type!");
// Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVector() &&
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
"Invalid operand types for FCmp instruction");
}
@@ -759,7 +759,7 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to FCmp instruction are not of the same type!");
// Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVector() &&
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
"Invalid operand types for FCmp instruction");
}
@@ -776,7 +776,7 @@ public:
assert(getOperand(0)->getType() == getOperand(1)->getType() &&
"Both operands to FCmp instruction are not of the same type!");
// Check that the operands are the right type
- assert(getOperand(0)->getType()->isFPOrFPVector() &&
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
"Invalid operand types for FCmp instruction");
}
diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h
index 8f1b1ae..5cfe551 100644
--- a/include/llvm/Intrinsics.h
+++ b/include/llvm/Intrinsics.h
@@ -63,9 +63,9 @@ namespace Intrinsic {
/// declaration for an intrinsic, and return it.
///
/// The Tys and numTys parameters are for intrinsics with overloaded types
- /// (e.g., those using iAny or fAny). For a declaration for an overloaded
- /// intrinsic, Tys should point to an array of numTys pointers to Type,
- /// and must provide exactly one type for each overloaded type in the
+ /// (e.g., those using iAny, fAny, vAny, or iPTRAny). For a declaration for an
+ /// overloaded intrinsic, Tys should point to an array of numTys pointers to
+ /// Type, and must provide exactly one type for each overloaded type in the
/// intrinsic.
Function *getDeclaration(Module *M, ID id, const Type **Tys = 0,
unsigned numTys = 0);
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td
index 684f872..3a0da9c 100644
--- a/include/llvm/Intrinsics.td
+++ b/include/llvm/Intrinsics.td
@@ -309,6 +309,7 @@ let Properties = [IntrNoMem] in {
def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
def int_eh_sjlj_longjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty]>;
def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>;
+ def int_eh_sjlj_callsite: Intrinsic<[llvm_void_ty], [llvm_i32_ty]>;
}
//===---------------- Generic Variable Attribute Intrinsics----------------===//
diff --git a/include/llvm/Linker.h b/include/llvm/Linker.h
index a68a2e0..cc7bf88 100644
--- a/include/llvm/Linker.h
+++ b/include/llvm/Linker.h
@@ -223,7 +223,7 @@ class Linker {
/// the archive that resolve outstanding symbols will be linked in. The
/// library is searched repeatedly until no more modules that resolve
/// symbols can be found. If an error occurs, the error string is set.
- /// To speed up this function, ensure the the archive has been processed
+ /// To speed up this function, ensure the archive has been processed
/// llvm-ranlib or the S option was given to llvm-ar when the archive was
/// created. These tools add a symbol table to the archive which makes the
/// search for undefined symbols much faster.
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 5e31dfe..3effea4 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -47,17 +47,6 @@ namespace llvm {
/// emitted in Static relocation model.
bool HasStaticCtorDtorReferenceInStaticMode; // Default is false.
- /// NeedsSet - True if target asm treats expressions in data directives
- /// as linktime-relocatable. For assembly-time computation, we need to
- /// use a .set. Thus:
- /// .set w, x-y
- /// .long w
- /// is computed at assembly time, while
- /// .long x-y
- /// is relocated if the relative locations of x and y change at linktime.
- /// We want both these things in different places.
- bool NeedsSet; // Defaults to false.
-
/// MaxInstLength - This is the maximum possible length of an instruction,
/// which is needed to compute the size of an inline asm.
unsigned MaxInstLength; // Defaults to 4.
@@ -73,7 +62,7 @@ namespace llvm {
/// CommentColumn - This indicates the comment num (zero-based) at
/// which asm comments should be printed.
- unsigned CommentColumn; // Defaults to 60
+ unsigned CommentColumn; // Defaults to 40
/// CommentString - This indicates the comment character used by the
/// assembler.
@@ -134,6 +123,11 @@ namespace llvm {
const char *Data32bitsDirective; // Defaults to "\t.long\t"
const char *Data64bitsDirective; // Defaults to "\t.quad\t"
+ /// GPRel32Directive - if non-null, a directive that is used to emit a word
+ /// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword
+ /// on Mips or .gprel32 on Alpha.
+ const char *GPRel32Directive; // Defaults to NULL.
+
/// getDataASDirective - Return the directive that should be used to emit
/// data of the specified size to the specified numeric address space.
virtual const char *getDataASDirective(unsigned Size, unsigned AS) const {
@@ -168,14 +162,6 @@ namespace llvm {
/// space created as the result of a alignment directive.
unsigned TextAlignFillValue; // Defaults to 0
- //===--- Section Switching Directives ---------------------------------===//
-
- /// JumpTableDirective - if non-null, the directive to emit before jump
- /// table entries. FIXME: REMOVE THIS.
- const char *JumpTableDirective; // Defaults to NULL.
- const char *PICJumpTableDirective; // Defaults to NULL.
-
-
//===--- Global Variable Emission Directives --------------------------===//
/// GlobalDirective - This is the directive used to declare a global entity.
@@ -187,17 +173,16 @@ namespace llvm {
///
const char *ExternDirective; // Defaults to NULL.
- /// SetDirective - This is the name of a directive that can be used to tell
- /// the assembler to set the value of a variable to some expression.
- const char *SetDirective; // Defaults to null.
+ /// HasSetDirective - True if the assembler supports the .set directive.
+ bool HasSetDirective; // Defaults to true.
/// HasLCOMMDirective - This is true if the target supports the .lcomm
/// directive.
- bool HasLCOMMDirective; // Defaults to false.
+ bool HasLCOMMDirective; // Defaults to false.
- /// COMMDirectiveTakesAlignment - True if COMMDirective take a third
- /// argument that specifies the alignment of the declaration.
- bool COMMDirectiveTakesAlignment; // Defaults to true.
+ /// COMMDirectiveAlignmentIsInBytes - True is COMMDirective's optional
+ /// alignment is to be specified in bytes instead of log2(n).
+ bool COMMDirectiveAlignmentIsInBytes; // Defaults to true;
/// HasDotTypeDotSizeDirective - True if the target has .type and .size
/// directives, this is true for most ELF targets.
@@ -305,6 +290,7 @@ namespace llvm {
const char *getData64bitsDirective(unsigned AS = 0) const {
return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS);
}
+ const char *getGPRel32Directive() const { return GPRel32Directive; }
/// getNonexecutableStackSection - Targets can implement this method to
/// specify a section to switch to if the translation unit doesn't have any
@@ -327,9 +313,6 @@ namespace llvm {
bool hasStaticCtorDtorReferenceInStaticMode() const {
return HasStaticCtorDtorReferenceInStaticMode;
}
- bool needsSet() const {
- return NeedsSet;
- }
unsigned getMaxInstLength() const {
return MaxInstLength;
}
@@ -378,9 +361,6 @@ namespace llvm {
const char *getAscizDirective() const {
return AscizDirective;
}
- const char *getJumpTableDirective(bool isPIC) const {
- return isPIC ? PICJumpTableDirective : JumpTableDirective;
- }
const char *getAlignDirective() const {
return AlignDirective;
}
@@ -396,14 +376,12 @@ namespace llvm {
const char *getExternDirective() const {
return ExternDirective;
}
- const char *getSetDirective() const {
- return SetDirective;
- }
+ bool hasSetDirective() const { return HasSetDirective; }
bool hasLCOMMDirective() const { return HasLCOMMDirective; }
- bool getCOMMDirectiveTakesAlignment() const {
- return COMMDirectiveTakesAlignment;
- }
bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
+ bool getCOMMDirectiveAlignmentIsInBytes() const {
+ return COMMDirectiveAlignmentIsInBytes;
+ }
bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
bool hasNoDeadStrip() const { return HasNoDeadStrip; }
const char *getWeakRefDirective() const { return WeakRefDirective; }
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index be017bf..4527f3c 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -14,6 +14,7 @@
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/Support/Casting.h"
+#include "llvm/MC/MCFixup.h"
#include "llvm/System/DataTypes.h"
#include <vector> // FIXME: Shouldn't be needed.
@@ -22,10 +23,34 @@ class raw_ostream;
class MCAssembler;
class MCContext;
class MCExpr;
+class MCFragment;
class MCSection;
class MCSectionData;
class MCSymbol;
+/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
+/// which needs to be rewritten. This region will either be rewritten by the
+/// assembler or cause a relocation entry to be generated.
+struct MCAsmFixup {
+ /// Offset - The offset inside the fragment which needs to be rewritten.
+ uint64_t Offset;
+
+ /// Value - The expression to eventually write into the fragment.
+ const MCExpr *Value;
+
+ /// Kind - The fixup kind.
+ MCFixupKind Kind;
+
+ /// FixedValue - The value to replace the fix up by.
+ //
+ // FIXME: This should not be here.
+ uint64_t FixedValue;
+
+public:
+ MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind)
+ : Offset(_Offset), Value(&_Value), Kind(_Kind), FixedValue(0) {}
+};
+
class MCFragment : public ilist_node<MCFragment> {
MCFragment(const MCFragment&); // DO NOT IMPLEMENT
void operator=(const MCFragment&); // DO NOT IMPLEMENT
@@ -85,7 +110,7 @@ public:
uint64_t getAddress() const;
- uint64_t getFileSize() const {
+ uint64_t getFileSize() const {
assert(FileSize != ~UINT64_C(0) && "File size not set!");
return FileSize;
}
@@ -103,11 +128,20 @@ public:
/// @}
static bool classof(const MCFragment *O) { return true; }
+
+ virtual void dump();
};
class MCDataFragment : public MCFragment {
SmallString<32> Contents;
+ /// Fixups - The list of fixups in this fragment.
+ std::vector<MCAsmFixup> Fixups;
+
+public:
+ typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
+ typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
+
public:
MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
@@ -123,10 +157,28 @@ public:
/// @}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Data;
+ /// @name Fixup Access
+ /// @{
+
+ std::vector<MCAsmFixup> &getFixups() { return Fixups; }
+ const std::vector<MCAsmFixup> &getFixups() const { return Fixups; }
+
+ fixup_iterator fixup_begin() { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+
+ fixup_iterator fixup_end() {return Fixups.end();}
+ const_fixup_iterator fixup_end() const {return Fixups.end();}
+
+ size_t fixup_size() const { return Fixups.size(); }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Data;
}
static bool classof(const MCDataFragment *) { return true; }
+
+ virtual void dump();
};
class MCAlignFragment : public MCFragment {
@@ -158,7 +210,7 @@ public:
}
unsigned getAlignment() const { return Alignment; }
-
+
int64_t getValue() const { return Value; }
unsigned getValueSize() const { return ValueSize; }
@@ -167,15 +219,17 @@ public:
/// @}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Align;
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Align;
}
static bool classof(const MCAlignFragment *) { return true; }
+
+ virtual void dump();
};
class MCFillFragment : public MCFragment {
/// Value - Value to use for filling bytes.
- const MCExpr *Value;
+ int64_t Value;
/// ValueSize - The size (in bytes) of \arg Value to use when filling.
unsigned ValueSize;
@@ -184,10 +238,10 @@ class MCFillFragment : public MCFragment {
uint64_t Count;
public:
- MCFillFragment(const MCExpr &_Value, unsigned _ValueSize, uint64_t _Count,
- MCSectionData *SD = 0)
+ MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Count,
+ MCSectionData *SD = 0)
: MCFragment(FT_Fill, SD),
- Value(&_Value), ValueSize(_ValueSize), Count(_Count) {}
+ Value(_Value), ValueSize(_ValueSize), Count(_Count) {}
/// @name Accessors
/// @{
@@ -196,25 +250,27 @@ public:
return ValueSize * Count;
}
- const MCExpr &getValue() const { return *Value; }
-
+ int64_t getValue() const { return Value; }
+
unsigned getValueSize() const { return ValueSize; }
uint64_t getCount() const { return Count; }
/// @}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Fill;
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Fill;
}
static bool classof(const MCFillFragment *) { return true; }
+
+ virtual void dump();
};
class MCOrgFragment : public MCFragment {
/// Offset - The offset this fragment should start at.
const MCExpr *Offset;
- /// Value - Value to use for filling bytes.
+ /// Value - Value to use for filling bytes.
int8_t Value;
public:
@@ -231,15 +287,17 @@ public:
}
const MCExpr &getOffset() const { return *Offset; }
-
+
uint8_t getValue() const { return Value; }
/// @}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Org;
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Org;
}
static bool classof(const MCOrgFragment *) { return true; }
+
+ virtual void dump();
};
/// MCZeroFillFragment - Represent data which has a fixed size and alignment,
@@ -265,15 +323,17 @@ public:
}
uint64_t getSize() const { return Size; }
-
+
unsigned getAlignment() const { return Alignment; }
/// @}
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_ZeroFill;
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_ZeroFill;
}
static bool classof(const MCZeroFillFragment *) { return true; }
+
+ virtual void dump();
};
// FIXME: Should this be a separate class, or just merged into MCSection? Since
@@ -284,41 +344,13 @@ class MCSectionData : public ilist_node<MCSectionData> {
void operator=(const MCSectionData&); // DO NOT IMPLEMENT
public:
- /// Fixup - Represent a fixed size region of bytes inside some fragment which
- /// needs to be rewritten. This region will either be rewritten by the
- /// assembler or cause a relocation entry to be generated.
- struct Fixup {
- /// Fragment - The fragment containing the fixup.
- MCFragment *Fragment;
-
- /// Offset - The offset inside the fragment which needs to be rewritten.
- uint64_t Offset;
-
- /// Value - The expression to eventually write into the fragment.
- const MCExpr *Value;
-
- /// Size - The fixup size.
- unsigned Size;
-
- /// FixedValue - The value to replace the fix up by.
- //
- // FIXME: This should not be here.
- uint64_t FixedValue;
-
- public:
- Fixup(MCFragment &_Fragment, uint64_t _Offset, const MCExpr &_Value,
- unsigned _Size)
- : Fragment(&_Fragment), Offset(_Offset), Value(&_Value), Size(_Size),
- FixedValue(0) {}
- };
-
typedef iplist<MCFragment> FragmentListType;
typedef FragmentListType::const_iterator const_iterator;
typedef FragmentListType::iterator iterator;
- typedef std::vector<Fixup>::const_iterator const_fixup_iterator;
- typedef std::vector<Fixup>::iterator fixup_iterator;
+ typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
+ typedef FragmentListType::reverse_iterator reverse_iterator;
private:
iplist<MCFragment> Fragments;
@@ -343,15 +375,13 @@ private:
/// initialized.
uint64_t FileSize;
- /// LastFixupLookup - Cache for the last looked up fixup.
- mutable unsigned LastFixupLookup;
+ /// HasInstructions - Whether this section has had instructions emitted into
+ /// it.
+ unsigned HasInstructions : 1;
- /// Fixups - The list of fixups in this section.
- std::vector<Fixup> Fixups;
-
/// @}
-public:
+public:
// Only for use as sentinel.
MCSectionData();
MCSectionData(const MCSection &Section, MCAssembler *A = 0);
@@ -373,27 +403,15 @@ public:
iterator end() { return Fragments.end(); }
const_iterator end() const { return Fragments.end(); }
- size_t size() const { return Fragments.size(); }
+ reverse_iterator rbegin() { return Fragments.rbegin(); }
+ const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
- bool empty() const { return Fragments.empty(); }
+ reverse_iterator rend() { return Fragments.rend(); }
+ const_reverse_iterator rend() const { return Fragments.rend(); }
- /// @}
- /// @name Fixup Access
- /// @{
-
- std::vector<Fixup> &getFixups() {
- return Fixups;
- }
-
- fixup_iterator fixup_begin() {
- return Fixups.begin();
- }
-
- fixup_iterator fixup_end() {
- return Fixups.end();
- }
+ size_t size() const { return Fragments.size(); }
- size_t fixup_size() const { return Fixups.size(); }
+ bool empty() const { return Fragments.empty(); }
/// @}
/// @name Assembler Backend Support
@@ -401,35 +419,30 @@ public:
//
// FIXME: This could all be kept private to the assembler implementation.
- /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg
- /// Offset.
- ///
- /// If multiple fixups exist for the same fragment and offset it is undefined
- /// which one is returned.
- //
- // FIXME: This isn't horribly slow in practice, but there are much nicer
- // solutions to applying the fixups.
- const Fixup *LookupFixup(const MCFragment *Fragment, uint64_t Offset) const;
-
- uint64_t getAddress() const {
+ uint64_t getAddress() const {
assert(Address != ~UINT64_C(0) && "Address not set!");
return Address;
}
void setAddress(uint64_t Value) { Address = Value; }
- uint64_t getSize() const {
+ uint64_t getSize() const {
assert(Size != ~UINT64_C(0) && "File size not set!");
return Size;
}
void setSize(uint64_t Value) { Size = Value; }
- uint64_t getFileSize() const {
+ uint64_t getFileSize() const {
assert(FileSize != ~UINT64_C(0) && "File size not set!");
return FileSize;
}
- void setFileSize(uint64_t Value) { FileSize = Value; }
+ void setFileSize(uint64_t Value) { FileSize = Value; }
+
+ bool hasInstructions() const { return HasInstructions; }
+ void setHasInstructions(bool Value) { HasInstructions = Value; }
/// @}
+
+ void dump();
};
// FIXME: Same concerns as with SectionData.
@@ -443,7 +456,7 @@ public:
/// Offset - The offset to apply to the fragment address to form this symbol's
/// value.
uint64_t Offset;
-
+
/// IsExternal - True if this symbol is visible outside this translation
/// unit.
unsigned IsExternal : 1;
@@ -489,10 +502,10 @@ public:
/// @}
/// @name Symbol Attributes
/// @{
-
+
bool isExternal() const { return IsExternal; }
void setExternal(bool Value) { IsExternal = Value; }
-
+
bool isPrivateExtern() const { return IsPrivateExtern; }
void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
@@ -525,14 +538,16 @@ public:
/// setFlags - Set the (implementation defined) symbol flags.
void setFlags(uint32_t Value) { Flags = Value; }
-
+
/// getIndex - Get the (implementation defined) index.
uint64_t getIndex() const { return Index; }
/// setIndex - Set the (implementation defined) index.
void setIndex(uint64_t Value) { Index = Value; }
-
- /// @}
+
+ /// @}
+
+ void dump();
};
// FIXME: This really doesn't belong here. See comments below.
@@ -561,7 +576,7 @@ private:
MCContext &Context;
raw_ostream &OS;
-
+
iplist<MCSectionData> Sections;
iplist<MCSymbolData> Symbols;
@@ -605,7 +620,7 @@ public:
/// @{
const SectionDataListType &getSectionList() const { return Sections; }
- SectionDataListType &getSectionList() { return Sections; }
+ SectionDataListType &getSectionList() { return Sections; }
iterator begin() { return Sections.begin(); }
const_iterator begin() const { return Sections.begin(); }
@@ -652,6 +667,8 @@ public:
size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
/// @}
+
+ void dump();
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
index ad42dc2..fe1aff4 100644
--- a/include/llvm/MC/MCCodeEmitter.h
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -10,23 +10,60 @@
#ifndef LLVM_MC_MCCODEEMITTER_H
#define LLVM_MC_MCCODEEMITTER_H
+#include "llvm/MC/MCFixup.h"
+
+#include <cassert>
+
namespace llvm {
+class MCExpr;
class MCInst;
class raw_ostream;
+template<typename T> class SmallVectorImpl;
+
+/// MCFixupKindInfo - Target independent information on a fixup kind.
+struct MCFixupKindInfo {
+ /// A target specific name for the fixup kind. The names will be unique for
+ /// distinct kinds on any given target.
+ const char *Name;
+
+ /// The bit offset to write the relocation into.
+ //
+ // FIXME: These two fields are under-specified and not general enough, but it
+ // is covers many things, and is enough to let the AsmStreamer pretty-print
+ // the encoding.
+ unsigned TargetOffset;
+
+ /// The number of bits written by this fixup. The bits are assumed to be
+ /// contiguous.
+ unsigned TargetSize;
+};
/// MCCodeEmitter - Generic instruction encoding interface.
class MCCodeEmitter {
+private:
MCCodeEmitter(const MCCodeEmitter &); // DO NOT IMPLEMENT
void operator=(const MCCodeEmitter &); // DO NOT IMPLEMENT
protected: // Can only create subclasses.
MCCodeEmitter();
-
+
public:
virtual ~MCCodeEmitter();
+ /// @name Target Independent Fixup Information
+ /// @{
+
+ /// getNumFixupKinds - Get the number of target specific fixup kinds.
+ virtual unsigned getNumFixupKinds() const = 0;
+
+ /// getFixupKindInfo - Get information on a fixup kind.
+ virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
+
+ /// @}
+
/// EncodeInstruction - Encode the given \arg Inst to bytes on the output
/// stream \arg OS.
- virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS) const = 0;
+ virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups) const = 0;
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h
index 57ce75d..1f7364d 100644
--- a/include/llvm/MC/MCDirectives.h
+++ b/include/llvm/MC/MCDirectives.h
@@ -17,26 +17,32 @@
namespace llvm {
enum MCSymbolAttr {
- MCSA_Invalid = 0, /// Not a valid directive.
+ MCSA_Invalid = 0, ///< Not a valid directive.
// Various directives in alphabetical order.
- MCSA_Global, /// .globl
- MCSA_Hidden, /// .hidden (ELF)
- MCSA_IndirectSymbol, /// .indirect_symbol (MachO)
- MCSA_Internal, /// .internal (ELF)
- MCSA_LazyReference, /// .lazy_reference (MachO)
- MCSA_Local, /// .local (ELF)
- MCSA_NoDeadStrip, /// .no_dead_strip (MachO)
- MCSA_PrivateExtern, /// .private_extern (MachO)
- MCSA_Protected, /// .protected (ELF)
- MCSA_Reference, /// .reference (MachO)
- MCSA_Weak, /// .weak
- MCSA_WeakDefinition, /// .weak_definition (MachO)
- MCSA_WeakReference /// .weak_reference (MachO)
+ MCSA_ELF_TypeFunction, ///< .type _foo, STT_FUNC # aka @function
+ MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC
+ MCSA_ELF_TypeObject, ///< .type _foo, STT_OBJECT # aka @object
+ MCSA_ELF_TypeTLS, ///< .type _foo, STT_TLS # aka @tls_object
+ MCSA_ELF_TypeCommon, ///< .type _foo, STT_COMMON # aka @common
+ MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype
+ MCSA_Global, ///< .globl
+ MCSA_Hidden, ///< .hidden (ELF)
+ MCSA_IndirectSymbol, ///< .indirect_symbol (MachO)
+ MCSA_Internal, ///< .internal (ELF)
+ MCSA_LazyReference, ///< .lazy_reference (MachO)
+ MCSA_Local, ///< .local (ELF)
+ MCSA_NoDeadStrip, ///< .no_dead_strip (MachO)
+ MCSA_PrivateExtern, ///< .private_extern (MachO)
+ MCSA_Protected, ///< .protected (ELF)
+ MCSA_Reference, ///< .reference (MachO)
+ MCSA_Weak, ///< .weak
+ MCSA_WeakDefinition, ///< .weak_definition (MachO)
+ MCSA_WeakReference ///< .weak_reference (MachO)
};
enum MCAssemblerFlag {
- MCAF_SubsectionsViaSymbols /// .subsections_via_symbols (MachO)
+ MCAF_SubsectionsViaSymbols ///< .subsections_via_symbols (MachO)
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index 73d5f8e..fce7602 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -29,7 +29,8 @@ public:
Binary, ///< Binary expressions.
Constant, ///< Constant expressions.
SymbolRef, ///< References to labels and assigned expressions.
- Unary ///< Unary expressions.
+ Unary, ///< Unary expressions.
+ Target ///< Target specific expression.
};
private:
@@ -39,7 +40,7 @@ private:
void operator=(const MCExpr&); // DO NOT IMPLEMENT
protected:
- MCExpr(ExprKind _Kind) : Kind(_Kind) {}
+ explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {}
public:
/// @name Accessors
@@ -85,7 +86,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
class MCConstantExpr : public MCExpr {
int64_t Value;
- MCConstantExpr(int64_t _Value)
+ explicit MCConstantExpr(int64_t _Value)
: MCExpr(MCExpr::Constant), Value(_Value) {}
public:
@@ -117,7 +118,7 @@ public:
class MCSymbolRefExpr : public MCExpr {
const MCSymbol *Symbol;
- MCSymbolRefExpr(const MCSymbol *_Symbol)
+ explicit MCSymbolRefExpr(const MCSymbol *_Symbol)
: MCExpr(MCExpr::SymbolRef), Symbol(_Symbol) {}
public:
@@ -201,20 +202,24 @@ public:
enum Opcode {
Add, ///< Addition.
And, ///< Bitwise and.
- Div, ///< Division.
+ Div, ///< Signed division.
EQ, ///< Equality comparison.
- GT, ///< Greater than comparison.
- GTE, ///< Greater than or equal comparison.
+ GT, ///< Signed greater than comparison (result is either 0 or some
+ ///< target-specific non-zero value)
+ GTE, ///< Signed greater than or equal comparison (result is either 0 or
+ ///< some target-specific non-zero value).
LAnd, ///< Logical and.
LOr, ///< Logical or.
- LT, ///< Less than comparison.
- LTE, ///< Less than or equal comparison.
- Mod, ///< Modulus.
+ LT, ///< Signed less than comparison (result is either 0 or
+ ///< some target-specific non-zero value).
+ LTE, ///< Signed less than or equal comparison (result is either 0 or
+ ///< some target-specific non-zero value).
+ Mod, ///< Signed remainder.
Mul, ///< Multiplication.
NE, ///< Inequality comparison.
Or, ///< Bitwise or.
- Shl, ///< Bitwise shift left.
- Shr, ///< Bitwise shift right.
+ Shl, ///< Shift left.
+ Shr, ///< Shift right (arithmetic or logical, depending on target)
Sub, ///< Subtraction.
Xor ///< Bitwise exclusive or.
};
@@ -326,6 +331,28 @@ public:
static bool classof(const MCBinaryExpr *) { return true; }
};
+/// MCTargetExpr - This is an extension point for target-specific MCExpr
+/// subclasses to implement.
+///
+/// NOTE: All subclasses are required to have trivial destructors because
+/// MCExprs are bump pointer allocated and not destructed.
+class MCTargetExpr : public MCExpr {
+ virtual void Anchor();
+protected:
+ MCTargetExpr() : MCExpr(Target) {}
+ virtual ~MCTargetExpr() {}
+public:
+
+ virtual void PrintImpl(raw_ostream &OS) const = 0;
+ virtual bool EvaluateAsRelocatableImpl(MCValue &Res) const = 0;
+
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::Target;
+ }
+ static bool classof(const MCTargetExpr *) { return true; }
+};
+
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h
new file mode 100644
index 0000000..cd0dd19
--- /dev/null
+++ b/include/llvm/MC/MCFixup.h
@@ -0,0 +1,108 @@
+//===-- llvm/MC/MCFixup.h - Instruction Relocation and Patching -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCFIXUP_H
+#define LLVM_MC_MCFIXUP_H
+
+#include <cassert>
+
+namespace llvm {
+class MCExpr;
+
+// Private constants, do not use.
+//
+// This is currently laid out so that the MCFixup fields can be efficiently
+// accessed, while keeping the offset field large enough that the assembler
+// backend can reasonably use the MCFixup representation for an entire fragment
+// (splitting any overly large fragments).
+//
+// The division of bits between the kind and the opindex can be tweaked if we
+// end up needing more bits for target dependent kinds.
+enum {
+ MCFIXUP_NUM_GENERIC_KINDS = 128,
+ MCFIXUP_NUM_KIND_BITS = 16,
+ MCFIXUP_NUM_OFFSET_BITS = (32 - MCFIXUP_NUM_KIND_BITS)
+};
+
+/// MCFixupKind - Extensible enumeration to represent the type of a fixup.
+enum MCFixupKind {
+ FK_Data_1 = 0, ///< A one-byte fixup.
+ FK_Data_2, ///< A two-byte fixup.
+ FK_Data_4, ///< A four-byte fixup.
+ FK_Data_8, ///< A eight-byte fixup.
+
+ FirstTargetFixupKind = MCFIXUP_NUM_GENERIC_KINDS,
+
+ MaxTargetFixupKind = (1 << MCFIXUP_NUM_KIND_BITS)
+};
+
+/// MCFixup - Encode information on a single operation to perform on an byte
+/// sequence (e.g., an encoded instruction) which requires assemble- or run-
+/// time patching.
+///
+/// Fixups are used any time the target instruction encoder needs to represent
+/// some value in an instruction which is not yet concrete. The encoder will
+/// encode the instruction assuming the value is 0, and emit a fixup which
+/// communicates to the assembler backend how it should rewrite the encoded
+/// value.
+///
+/// During the process of relaxation, the assembler will apply fixups as
+/// symbolic values become concrete. When relaxation is complete, any remaining
+/// fixups become relocations in the object file (or errors, if the fixup cannot
+/// be encoded on the target).
+class MCFixup {
+ static const unsigned MaxOffset = 1 << MCFIXUP_NUM_KIND_BITS;
+
+ /// The value to put into the fixup location. The exact interpretation of the
+ /// expression is target dependent, usually it will one of the operands to an
+ /// instruction or an assembler directive.
+ const MCExpr *Value;
+
+ /// The byte index of start of the relocation inside the encoded instruction.
+ unsigned Offset : MCFIXUP_NUM_OFFSET_BITS;
+
+ /// The target dependent kind of fixup item this is. The kind is used to
+ /// determine how the operand value should be encoded into the instruction.
+ unsigned Kind : MCFIXUP_NUM_KIND_BITS;
+
+public:
+ static MCFixup Create(unsigned Offset, const MCExpr *Value,
+ MCFixupKind Kind) {
+ MCFixup FI;
+ FI.Value = Value;
+ FI.Offset = Offset;
+ FI.Kind = unsigned(Kind);
+
+ assert(Offset == FI.getOffset() && "Offset out of range!");
+ assert(Kind == FI.getKind() && "Kind out of range!");
+ return FI;
+ }
+
+ MCFixupKind getKind() const { return MCFixupKind(Kind); }
+
+ unsigned getOffset() const { return Offset; }
+
+ const MCExpr *getValue() const { return Value; }
+
+ /// getKindForSize - Return the generic fixup kind for a value with the given
+ /// size. It is an error to pass an unsupported size.
+ static MCFixupKind getKindForSize(unsigned Size) {
+ switch (Size) {
+ default: assert(0 && "Invalid generic fixup size!");
+ case 1: return FK_Data_1;
+ case 2: return FK_Data_2;
+ case 4: return FK_Data_4;
+ case 8: return FK_Data_8;
+ }
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
index d62a9da..d2ddc5b 100644
--- a/include/llvm/MC/MCInstPrinter.h
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -14,22 +14,36 @@ namespace llvm {
class MCInst;
class raw_ostream;
class MCAsmInfo;
+class StringRef;
-
/// MCInstPrinter - This is an instance of a target assembly language printer
/// that converts an MCInst to valid target assembly syntax.
class MCInstPrinter {
protected:
+ /// O - The main stream to emit instruction text to.
raw_ostream &O;
+
+ /// CommentStream - a stream that comments can be emitted to if desired.
+ /// Each comment must end with a newline. This will be null if verbose
+ /// assembly emission is disable.
+ raw_ostream *CommentStream;
const MCAsmInfo &MAI;
public:
- MCInstPrinter(raw_ostream &o, const MCAsmInfo &mai) : O(o), MAI(mai) {}
+ MCInstPrinter(raw_ostream &o, const MCAsmInfo &mai)
+ : O(o), CommentStream(0), MAI(mai) {}
virtual ~MCInstPrinter();
+
+ /// setCommentStream - Specify a stream to emit comments to.
+ void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
/// printInst - Print the specified MCInst to the current raw_ostream.
///
virtual void printInst(const MCInst *MI) = 0;
+
+ /// getOpcodeName - Return the name of the specified opcode enum (e.g.
+ /// "MOV32ri") or empty if we can't resolve it.
+ virtual StringRef getOpcodeName(unsigned Opcode) const;
};
} // namespace llvm
diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h
index f82584c..829604c 100644
--- a/include/llvm/MC/MCParser/AsmParser.h
+++ b/include/llvm/MC/MCParser/AsmParser.h
@@ -61,8 +61,8 @@ private:
/// in the directive name and the location of the directive keyword.
StringMap<bool(AsmParser::*)(StringRef, SMLoc)> DirectiveMap;
public:
- AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
- const MCAsmInfo &_MAI);
+ AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
+ const MCAsmInfo &MAI);
~AsmParser();
bool Run();
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 2bcb594..624d9a6 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -60,6 +60,10 @@ namespace llvm {
/// @name Assembly File Formatting.
/// @{
+
+ /// isVerboseAsm - Return true if this streamer supports verbose assembly at
+ /// all.
+ virtual bool isVerboseAsm() const { return false; }
/// AddComment - Add a comment that can be emitted to the generated .s
/// file if applicable as a QoI issue to make the output of the compiler
@@ -129,6 +133,14 @@ namespace llvm {
/// @param DescValue - The value to set into the n_desc field.
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0;
+
+ /// EmitELFSize - Emit an ELF .size directive.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// .size symbol, expression
+ ///
+ virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0;
+
/// EmitCommonSymbol - Emit a common symbol.
///
/// @param Symbol - The common symbol to emit.
@@ -180,6 +192,13 @@ namespace llvm {
/// to pass in a MCExpr for constant integers.
virtual void EmitIntValue(uint64_t Value, unsigned Size,unsigned AddrSpace);
+ /// EmitGPRel32Value - Emit the expression @param Value into the output as a
+ /// gprel32 (32-bit GP relative) value.
+ ///
+ /// This is used to implement assembler directives such as .gprel32 on
+ /// targets that support them.
+ virtual void EmitGPRel32Value(const MCExpr *Value) = 0;
+
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
@@ -225,6 +244,15 @@ namespace llvm {
unsigned char Value = 0) = 0;
/// @}
+
+ /// EmitFileDirective - Switch to a new logical file. This is used to
+ /// implement the '.file "foo.c"' assembler directive.
+ virtual void EmitFileDirective(StringRef Filename) = 0;
+
+ /// EmitDwarfFileDirective - Associate a filename with a specified logical
+ /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler
+ /// directive.
+ virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) = 0;
/// EmitInstruction - Emit the given @param Instruction into the current
/// section.
@@ -241,11 +269,21 @@ namespace llvm {
/// createAsmStreamer - Create a machine code streamer which will print out
/// assembly for the native target, suitable for compiling with a native
/// assembler.
+ ///
+ /// \param InstPrint - If given, the instruction printer to use. If not given
+ /// the MCInst representation will be printed.
+ ///
+ /// \param CE - If given, a code emitter to use to show the instruction
+ /// encoding inline with the assembly.
+ ///
+ /// \param ShowInst - Whether to show the MCInst representation inline with
+ /// the assembly.
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
const MCAsmInfo &MAI, bool isLittleEndian,
bool isVerboseAsm,
MCInstPrinter *InstPrint = 0,
- MCCodeEmitter *CE = 0);
+ MCCodeEmitter *CE = 0,
+ bool ShowInst = false);
// FIXME: These two may end up getting rolled into a single
// createObjectStreamer interface, which implements the assembler backend, and
@@ -254,7 +292,7 @@ namespace llvm {
/// createMachOStream - Create a machine code streamer which will generative
/// Mach-O format object files.
MCStreamer *createMachOStreamer(MCContext &Ctx, raw_ostream &OS,
- MCCodeEmitter *CE = 0);
+ MCCodeEmitter *CE);
/// createELFStreamer - Create a machine code streamer which will generative
/// ELF format object files.
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index e770604..d5c4d95 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -89,7 +89,7 @@ namespace llvm {
return !isDefined();
}
- /// isAbsolute - Check if this this is an absolute symbol.
+ /// isAbsolute - Check if this is an absolute symbol.
bool isAbsolute() const {
return Section == AbsolutePseudoSection;
}
diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h
index f1e7a22..4e459bf 100644
--- a/include/llvm/Metadata.h
+++ b/include/llvm/Metadata.h
@@ -112,7 +112,7 @@ protected:
bool isFunctionLocal);
static MDNode *getMDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
- FunctionLocalness FL);
+ FunctionLocalness FL, bool Insert = true);
public:
// Constructors and destructors.
static MDNode *get(LLVMContext &Context, Value *const *Vals,
@@ -121,6 +121,9 @@ public:
// from isFunctionLocal argument, not by analyzing Vals.
static MDNode *getWhenValsUnresolved(LLVMContext &Context, Value *const *Vals,
unsigned NumVals, bool isFunctionLocal);
+
+ static MDNode *getIfExists(LLVMContext &Context, Value *const *Vals,
+ unsigned NumVals);
/// getOperand - Return specified operand.
Value *getOperand(unsigned i) const;
diff --git a/include/llvm/Module.h b/include/llvm/Module.h
index 3c8055d..901fada 100644
--- a/include/llvm/Module.h
+++ b/include/llvm/Module.h
@@ -19,12 +19,14 @@
#include "llvm/GlobalVariable.h"
#include "llvm/GlobalAlias.h"
#include "llvm/Metadata.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/System/DataTypes.h"
#include <vector>
namespace llvm {
class FunctionType;
+class GVMaterializer;
class LLVMContext;
class MDSymbolTable;
@@ -145,6 +147,7 @@ private:
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
ValueSymbolTable *ValSymTab; ///< Symbol table for values
TypeSymbolTable *TypeSymTab; ///< Symbol table for types
+ OwningPtr<GVMaterializer> Materializer; ///< Used to materialize GlobalValues
std::string ModuleID; ///< Human readable identifier for the module
std::string TargetTriple; ///< Platform target triple Module compiled on
std::string DataLayout; ///< Target data description
@@ -211,11 +214,13 @@ public:
/// Set the module-scope inline assembly blocks.
void setModuleInlineAsm(StringRef Asm) { GlobalScopeAsm = Asm; }
- /// Append to the module-scope inline assembly blocks, automatically
- /// appending a newline to the end.
+ /// Append to the module-scope inline assembly blocks, automatically inserting
+ /// a separating newline if necessary.
void appendModuleInlineAsm(StringRef Asm) {
+ if (!GlobalScopeAsm.empty() &&
+ GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n')
+ GlobalScopeAsm += '\n';
GlobalScopeAsm += Asm;
- GlobalScopeAsm += '\n';
}
/// @}
@@ -345,6 +350,50 @@ public:
const Type *getTypeByName(StringRef Name) const;
/// @}
+/// @name Materialization
+/// @{
+
+ /// setMaterializer - Sets the GVMaterializer to GVM. This module must not
+ /// yet have a Materializer. To reset the materializer for a module that
+ /// already has one, call MaterializeAllPermanently first. Destroying this
+ /// module will destroy its materializer without materializing any more
+ /// GlobalValues. Without destroying the Module, there is no way to detach or
+ /// destroy a materializer without materializing all the GVs it controls, to
+ /// avoid leaving orphan unmaterialized GVs.
+ void setMaterializer(GVMaterializer *GVM);
+ /// getMaterializer - Retrieves the GVMaterializer, if any, for this Module.
+ GVMaterializer *getMaterializer() const { return Materializer.get(); }
+
+ /// isMaterializable - True if the definition of GV has yet to be materialized
+ /// from the GVMaterializer.
+ bool isMaterializable(const GlobalValue *GV) const;
+ /// isDematerializable - Returns true if this GV was loaded from this Module's
+ /// GVMaterializer and the GVMaterializer knows how to dematerialize the GV.
+ bool isDematerializable(const GlobalValue *GV) const;
+
+ /// Materialize - Make sure the GlobalValue is fully read. If the module is
+ /// corrupt, this returns true and fills in the optional string with
+ /// information about the problem. If successful, this returns false.
+ bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0);
+ /// Dematerialize - If the GlobalValue is read in, and if the GVMaterializer
+ /// supports it, release the memory for the function, and set it up to be
+ /// materialized lazily. If !isDematerializable(), this method is a noop.
+ void Dematerialize(GlobalValue *GV);
+
+ /// MaterializeAll - Make sure all GlobalValues in this Module are fully read.
+ /// If the module is corrupt, this returns true and fills in the optional
+ /// string with information about the problem. If successful, this returns
+ /// false.
+ bool MaterializeAll(std::string *ErrInfo = 0);
+
+ /// MaterializeAllPermanently - Make sure all GlobalValues in this Module are
+ /// fully read and clear the Materializer. If the module is corrupt, this
+ /// returns true, fills in the optional string with information about the
+ /// problem, and DOES NOT clear the old Materializer. If successful, this
+ /// returns false.
+ bool MaterializeAllPermanently(std::string *ErrInfo = 0);
+
+/// @}
/// @name Direct access to the globals list, functions list, and symbol table
/// @{
diff --git a/include/llvm/ModuleProvider.h b/include/llvm/ModuleProvider.h
deleted file mode 100644
index 8a0a20c..0000000
--- a/include/llvm/ModuleProvider.h
+++ /dev/null
@@ -1,88 +0,0 @@
-//===-- llvm/ModuleProvider.h - Interface for module providers --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides an abstract interface for loading a module from some
-// place. This interface allows incremental or random access loading of
-// functions from the file. This is useful for applications like JIT compilers
-// or interprocedural optimizers that do not need the entire program in memory
-// at the same time.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MODULEPROVIDER_H
-#define MODULEPROVIDER_H
-
-#include <string>
-
-namespace llvm {
-
-class Function;
-class Module;
-
-class ModuleProvider {
-protected:
- Module *TheModule;
- ModuleProvider();
-
-public:
- virtual ~ModuleProvider();
-
- /// getModule - returns the module this provider is encapsulating.
- ///
- Module* getModule() { return TheModule; }
-
- /// materializeFunction - make sure the given function is fully read. If the
- /// module is corrupt, this returns true and fills in the optional string
- /// with information about the problem. If successful, this returns false.
- ///
- virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0) = 0;
-
- /// dematerializeFunction - If the given function is read in, and if the
- /// module provider supports it, release the memory for the function, and set
- /// it up to be materialized lazily. If the provider doesn't support this
- /// capability, this method is a noop.
- ///
- virtual void dematerializeFunction(Function *) {}
-
- /// materializeModule - make sure the entire Module has been completely read.
- /// On error, return null and fill in the error string if specified.
- ///
- virtual Module* materializeModule(std::string *ErrInfo = 0) = 0;
-
- /// releaseModule - no longer delete the Module* when provider is destroyed.
- /// On error, return null and fill in the error string if specified.
- ///
- virtual Module* releaseModule(std::string *ErrInfo = 0) {
- // Since we're losing control of this Module, we must hand it back complete
- if (!materializeModule(ErrInfo))
- return 0;
- Module *tempM = TheModule;
- TheModule = 0;
- return tempM;
- }
-};
-
-
-/// ExistingModuleProvider - Allow conversion from a fully materialized Module
-/// into a ModuleProvider, allowing code that expects a ModuleProvider to work
-/// if we just have a Module. Note that the ModuleProvider takes ownership of
-/// the Module specified.
-struct ExistingModuleProvider : public ModuleProvider {
- explicit ExistingModuleProvider(Module *M) {
- TheModule = M;
- }
- bool materializeFunction(Function *, std::string * = 0) {
- return false;
- }
- Module* materializeModule(std::string * = 0) { return TheModule; }
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h
index ab08afb..e822a0f 100644
--- a/include/llvm/Pass.h
+++ b/include/llvm/Pass.h
@@ -56,11 +56,11 @@ typedef const PassInfo* AnalysisID;
/// Ordering of pass manager types is important here.
enum PassManagerType {
PMT_Unknown = 0,
- PMT_ModulePassManager = 1, /// MPPassManager
- PMT_CallGraphPassManager, /// CGPassManager
- PMT_FunctionPassManager, /// FPPassManager
- PMT_LoopPassManager, /// LPPassManager
- PMT_BasicBlockPassManager, /// BBPassManager
+ PMT_ModulePassManager = 1, ///< MPPassManager
+ PMT_CallGraphPassManager, ///< CGPassManager
+ PMT_FunctionPassManager, ///< FPPassManager
+ PMT_LoopPassManager, ///< LPPassManager
+ PMT_BasicBlockPassManager, ///< BBPassManager
PMT_Last
};
diff --git a/include/llvm/PassManager.h b/include/llvm/PassManager.h
index a6703fd..4d91163 100644
--- a/include/llvm/PassManager.h
+++ b/include/llvm/PassManager.h
@@ -24,7 +24,6 @@ namespace llvm {
class Pass;
class ModulePass;
class Module;
-class ModuleProvider;
class PassManagerImpl;
class FunctionPassManagerImpl;
@@ -71,8 +70,8 @@ private:
class FunctionPassManager : public PassManagerBase {
public:
/// FunctionPassManager ctor - This initializes the pass manager. It needs,
- /// but does not take ownership of, the specified module provider.
- explicit FunctionPassManager(ModuleProvider *P);
+ /// but does not take ownership of, the specified Module.
+ explicit FunctionPassManager(Module *M);
~FunctionPassManager();
/// add - Add a pass to the queue of passes to run. This passes
@@ -96,15 +95,9 @@ public:
///
bool doFinalization();
- /// getModuleProvider - Return the module provider that this passmanager is
- /// currently using. This is the module provider that it uses when a function
- /// is optimized that is non-resident in the module.
- ModuleProvider *getModuleProvider() const { return MP; }
- void setModuleProvider(ModuleProvider *NewMP) { MP = NewMP; }
-
private:
FunctionPassManagerImpl *FPM;
- ModuleProvider *MP;
+ Module *M;
};
} // End llvm namespace
diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h
index 443a9e0..d5685c6 100644
--- a/include/llvm/PassManagers.h
+++ b/include/llvm/PassManagers.h
@@ -394,8 +394,8 @@ private:
const AnalysisUsage::VectorType &Set) const;
// Set of available Analysis. This information is used while scheduling
- // pass. If a pass requires an analysis which is not not available then
- // equired analysis pass is scheduled to run before the pass itself is
+ // pass. If a pass requires an analysis which is not available then
+ // the required analysis pass is scheduled to run before the pass itself is
// scheduled to run.
std::map<AnalysisID, Pass*> AvailableAnalysis;
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index 37a7c3b..17bcb59 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -180,8 +180,9 @@ template<class To, class From, class SimpleFrom> struct cast_convert_val {
template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
// This _is_ a simple type, just cast it.
static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
- return reinterpret_cast<typename cast_retty<To, FromTy>::ret_type>(
- const_cast<FromTy&>(Val));
+ typename cast_retty<To, FromTy>::ret_type Res2
+ = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
+ return Res2;
}
};
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 7f8b10c..3ee2313 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -1168,7 +1168,7 @@ class bits_storage<DataType, bool> {
template<class T>
static unsigned Bit(const T &V) {
- unsigned BitPos = reinterpret_cast<unsigned>(V);
+ unsigned BitPos = (unsigned)V;
assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
"enum exceeds width of bit vector!");
return 1 << BitPos;
diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h
index 1339e9f..ea6c5fd 100644
--- a/include/llvm/Support/ConstantFolder.h
+++ b/include/llvm/Support/ConstantFolder.h
@@ -39,6 +39,9 @@ public:
Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getNSWAdd(LHS, RHS);
}
+ Constant *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getNUWAdd(LHS, RHS);
+ }
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFAdd(LHS, RHS);
}
@@ -48,6 +51,9 @@ public:
Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getNSWSub(LHS, RHS);
}
+ Constant *CreateNUWSub(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getNUWSub(LHS, RHS);
+ }
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFSub(LHS, RHS);
}
@@ -57,6 +63,9 @@ public:
Constant *CreateNSWMul(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getNSWMul(LHS, RHS);
}
+ Constant *CreateNUWMul(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getNUWMul(LHS, RHS);
+ }
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFMul(LHS, RHS);
}
@@ -115,6 +124,9 @@ public:
Constant *CreateNSWNeg(Constant *C) const {
return ConstantExpr::getNSWNeg(C);
}
+ Constant *CreateNUWNeg(Constant *C) const {
+ return ConstantExpr::getNUWNeg(C);
+ }
Constant *CreateFNeg(Constant *C) const {
return ConstantExpr::getFNeg(C);
}
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index bfccc52..5f591d4 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -580,7 +580,6 @@ const char *MacinfoString(unsigned Encoding);
/// CallFrameString - Return the string for the specified call frame instruction
/// encodings.
const char *CallFrameString(unsigned Encoding);
-
} // End of namespace dwarf
} // End of namespace llvm
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index af546f0..58a1885 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/FormattedStream.h - Formatted streams ------*- C++ -*-===//
+//===-- llvm/Support/FormattedStream.h - Formatted streams ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -119,7 +119,7 @@ namespace llvm
/// space.
///
/// \param NewCol - The column to move to.
- void PadToColumn(unsigned NewCol);
+ formatted_raw_ostream &PadToColumn(unsigned NewCol);
private:
void releaseStream() {
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
index eabf6ad..c8aef9c 100644
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -94,7 +94,7 @@ public:
//===--------------------------------------------------------------------===//
/// CreateGlobalString - Make a new global variable with an initializer that
- /// has array of i8 type filled in the the nul terminated string value
+ /// has array of i8 type filled in with the nul terminated string value
/// specified. If Name is specified, it is the name of the global variable
/// created.
Value *CreateGlobalString(const char *Str = "", const Twine &Name = "");
@@ -318,6 +318,12 @@ public:
return Folder.CreateNSWAdd(LC, RC);
return Insert(BinaryOperator::CreateNSWAdd(LHS, RHS), Name);
}
+ Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateNUWAdd(LC, RC);
+ return Insert(BinaryOperator::CreateNUWAdd(LHS, RHS), Name);
+ }
Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
@@ -336,6 +342,12 @@ public:
return Folder.CreateNSWSub(LC, RC);
return Insert(BinaryOperator::CreateNSWSub(LHS, RHS), Name);
}
+ Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateNUWSub(LC, RC);
+ return Insert(BinaryOperator::CreateNUWSub(LHS, RHS), Name);
+ }
Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
@@ -354,6 +366,12 @@ public:
return Folder.CreateNSWMul(LC, RC);
return Insert(BinaryOperator::CreateNSWMul(LHS, RHS), Name);
}
+ Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Folder.CreateNUWMul(LC, RC);
+ return Insert(BinaryOperator::CreateNUWMul(LHS, RHS), Name);
+ }
Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
@@ -484,6 +502,11 @@ public:
return Folder.CreateNSWNeg(VC);
return Insert(BinaryOperator::CreateNSWNeg(V), Name);
}
+ Value *CreateNUWNeg(Value *V, const Twine &Name = "") {
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreateNUWNeg(VC);
+ return Insert(BinaryOperator::CreateNUWNeg(V), Name);
+ }
Value *CreateFNeg(Value *V, const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
return Folder.CreateFNeg(VC);
diff --git a/include/llvm/Support/IRReader.h b/include/llvm/Support/IRReader.h
index e7780b0..66314e0 100644
--- a/include/llvm/Support/IRReader.h
+++ b/include/llvm/Support/IRReader.h
@@ -23,44 +23,39 @@
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
-#include "llvm/ModuleProvider.h"
namespace llvm {
- /// If the given MemoryBuffer holds a bitcode image, return a ModuleProvider
- /// for it which does lazy deserialization of function bodies. Otherwise,
- /// attempt to parse it as LLVM Assembly and return a fully populated
- /// ModuleProvider. This function *always* takes ownership of the given
- /// MemoryBuffer.
- inline ModuleProvider *getIRModuleProvider(MemoryBuffer *Buffer,
- SMDiagnostic &Err,
- LLVMContext &Context) {
+ /// If the given MemoryBuffer holds a bitcode image, return a Module for it
+ /// which does lazy deserialization of function bodies. Otherwise, attempt to
+ /// parse it as LLVM Assembly and return a fully populated Module. This
+ /// function *always* takes ownership of the given MemoryBuffer.
+ inline Module *getLazyIRModule(MemoryBuffer *Buffer,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
(const unsigned char *)Buffer->getBufferEnd())) {
std::string ErrMsg;
- ModuleProvider *MP = getBitcodeModuleProvider(Buffer, Context, &ErrMsg);
- if (MP == 0) {
+ Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg);
+ if (M == 0) {
Err = SMDiagnostic(Buffer->getBufferIdentifier(), -1, -1, ErrMsg, "");
// ParseBitcodeFile does not take ownership of the Buffer in the
// case of an error.
delete Buffer;
}
- return MP;
+ return M;
}
- Module *M = ParseAssembly(Buffer, 0, Err, Context);
- if (M == 0)
- return 0;
- return new ExistingModuleProvider(M);
+ return ParseAssembly(Buffer, 0, Err, Context);
}
- /// If the given file holds a bitcode image, return a ModuleProvider
+ /// If the given file holds a bitcode image, return a Module
/// for it which does lazy deserialization of function bodies. Otherwise,
/// attempt to parse it as LLVM Assembly and return a fully populated
- /// ModuleProvider.
- inline ModuleProvider *getIRFileModuleProvider(const std::string &Filename,
- SMDiagnostic &Err,
- LLVMContext &Context) {
+ /// Module.
+ inline Module *getLazyIRFileModule(const std::string &Filename,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
std::string ErrMsg;
MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg);
if (F == 0) {
@@ -69,7 +64,7 @@ namespace llvm {
return 0;
}
- return getIRModuleProvider(F, Err, Context);
+ return getLazyIRModule(F, Err, Context);
}
/// If the given MemoryBuffer holds a bitcode image, return a Module
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
new file mode 100644
index 0000000..e6fccfc
--- /dev/null
+++ b/include/llvm/Support/MachO.h
@@ -0,0 +1,56 @@
+//===-- llvm/Support/MachO.h - The MachO file format ------------*- 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 manifest constants for the MachO object file format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MACHO_H
+#define LLVM_SUPPORT_MACHO_H
+
+// NOTE: The enums in this file are intentially named to be different than those
+// in the headers in /usr/include/mach (on darwin systems) to avoid conflicts
+// with those macros.
+namespace llvm {
+ namespace MachO {
+ // Enums from <mach/machine.h>
+ enum {
+ // Capability bits used in the definition of cpu_type.
+ CPUArchMask = 0xff000000, // Mask for architecture bits
+ CPUArchABI64 = 0x01000000, // 64 bit ABI
+
+ // Constants for the cputype field.
+ CPUTypeI386 = 7,
+ CPUTypeX86_64 = CPUTypeI386 | CPUArchABI64,
+ CPUTypeARM = 12,
+ CPUTypeSPARC = 14,
+ CPUTypePowerPC = 18,
+ CPUTypePowerPC64 = CPUTypePowerPC | CPUArchABI64,
+
+
+ // Constants for the cpusubtype field.
+
+ // X86
+ CPUSubType_I386_ALL = 3,
+ CPUSubType_X86_64_ALL = 3,
+
+ // ARM
+ CPUSubType_ARM_ALL = 0,
+ CPUSubType_ARM_V4T = 5,
+ CPUSubType_ARM_V6 = 6,
+
+ // PowerPC
+ CPUSubType_POWERPC_ALL = 0,
+
+ CPUSubType_SPARC_ALL = 0
+ };
+ } // end namespace MachO
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h
index 78a9035..01256e1 100644
--- a/include/llvm/Support/NoFolder.h
+++ b/include/llvm/Support/NoFolder.h
@@ -45,6 +45,9 @@ public:
Value *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateNSWAdd(LHS, RHS);
}
+ Value *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNUWAdd(LHS, RHS);
+ }
Value *CreateFAdd(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFAdd(LHS, RHS);
}
@@ -54,6 +57,9 @@ public:
Value *CreateNSWSub(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateNSWSub(LHS, RHS);
}
+ Value *CreateNUWSub(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNUWSub(LHS, RHS);
+ }
Value *CreateFSub(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFSub(LHS, RHS);
}
@@ -63,6 +69,9 @@ public:
Value *CreateNSWMul(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateNSWMul(LHS, RHS);
}
+ Value *CreateNUWMul(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNUWMul(LHS, RHS);
+ }
Value *CreateFMul(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFMul(LHS, RHS);
}
@@ -121,6 +130,9 @@ public:
Value *CreateNSWNeg(Constant *C) const {
return BinaryOperator::CreateNSWNeg(C);
}
+ Value *CreateNUWNeg(Constant *C) const {
+ return BinaryOperator::CreateNUWNeg(C);
+ }
Value *CreateNot(Constant *C) const {
return BinaryOperator::CreateNot(C);
}
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index 23daad9..f02bc34 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/Support/PatternMatch.h
@@ -423,7 +423,7 @@ m_Select(const Cond &C, const LHS &L, const RHS &R) {
}
/// m_SelectCst - This matches a select of two constants, e.g.:
-/// m_SelectCst(m_Value(V), -1, 0)
+/// m_SelectCst<-1, 0>(m_Value(V))
template<int64_t L, int64_t R, typename Cond>
inline SelectClass_match<Cond, constantint_ty<L>, constantint_ty<R> >
m_SelectCst(const Cond &C) {
@@ -466,6 +466,20 @@ inline CastClass_match<OpTy, Instruction::Trunc>
m_Trunc(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::Trunc>(Op);
}
+
+/// m_SExt
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::SExt>
+m_SExt(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::SExt>(Op);
+}
+
+/// m_ZExt
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::ZExt>
+m_ZExt(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::ZExt>(Op);
+}
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index 5433a00..fd56b16 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -34,33 +34,33 @@ class SourceMgr {
struct SrcBuffer {
/// Buffer - The memory buffer for the file.
MemoryBuffer *Buffer;
-
+
/// IncludeLoc - This is the location of the parent include, or null if at
/// the top level.
SMLoc IncludeLoc;
};
-
+
/// Buffers - This is all of the buffers that we are reading from.
std::vector<SrcBuffer> Buffers;
-
+
// IncludeDirectories - This is the list of directories we should search for
// include files in.
std::vector<std::string> IncludeDirectories;
-
+
/// LineNoCache - This is a cache for line number queries, its implementation
/// is really private to SourceMgr.cpp.
mutable void *LineNoCache;
-
+
SourceMgr(const SourceMgr&); // DO NOT IMPLEMENT
void operator=(const SourceMgr&); // DO NOT IMPLEMENT
public:
SourceMgr() : LineNoCache(0) {}
~SourceMgr();
-
+
void setIncludeDirs(const std::vector<std::string> &Dirs) {
IncludeDirectories = Dirs;
}
-
+
const SrcBuffer &getBufferInfo(unsigned i) const {
assert(i < Buffers.size() && "Invalid Buffer ID!");
return Buffers[i];
@@ -70,12 +70,12 @@ public:
assert(i < Buffers.size() && "Invalid Buffer ID!");
return Buffers[i].Buffer;
}
-
+
SMLoc getParentIncludeLoc(unsigned i) const {
assert(i < Buffers.size() && "Invalid Buffer ID!");
return Buffers[i].IncludeLoc;
}
-
+
unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
SrcBuffer NB;
NB.Buffer = F;
@@ -83,20 +83,20 @@ public:
Buffers.push_back(NB);
return Buffers.size()-1;
}
-
+
/// AddIncludeFile - Search for a file with the specified name in the current
/// directory or in one of the IncludeDirs. If no file is found, this returns
/// ~0, otherwise it returns the buffer ID of the stacked file.
unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc);
-
+
/// FindBufferContainingLoc - Return the ID of the buffer containing the
/// specified location, returning -1 if not found.
int FindBufferContainingLoc(SMLoc Loc) const;
-
+
/// FindLineNumber - Find the line number for the specified location in the
/// specified file. This is not a fast method.
unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const;
-
+
/// PrintMessage - Emit a message about the specified location with the
/// specified string.
///
@@ -105,8 +105,8 @@ public:
/// @param ShowLine - Should the diagnostic show the source line.
void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type,
bool ShowLine = true) const;
-
-
+
+
/// GetMessage - Return an SMDiagnostic at the specified location with the
/// specified string.
///
@@ -116,13 +116,13 @@ public:
SMDiagnostic GetMessage(SMLoc Loc,
const std::string &Msg, const char *Type,
bool ShowLine = true) const;
-
-
+
+
private:
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
};
-
+
/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
/// allowing printing to a raw_ostream as a caret diagnostic.
class SMDiagnostic {
@@ -132,16 +132,16 @@ class SMDiagnostic {
unsigned ShowLine : 1;
public:
- SMDiagnostic() : LineNo(0), ColumnNo(0) {}
+ SMDiagnostic() : LineNo(0), ColumnNo(0), ShowLine(0) {}
SMDiagnostic(const std::string &FN, int Line, int Col,
const std::string &Msg, const std::string &LineStr,
bool showline = true)
: Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
LineContents(LineStr), ShowLine(showline) {}
- void Print(const char *ProgName, raw_ostream &S);
+ void Print(const char *ProgName, raw_ostream &S) const;
};
-
+
} // end llvm namespace
#endif
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
index 59dd29b..384c493 100644
--- a/include/llvm/Support/TargetFolder.h
+++ b/include/llvm/Support/TargetFolder.h
@@ -52,6 +52,9 @@ public:
Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getNSWAdd(LHS, RHS));
}
+ Constant *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getNUWAdd(LHS, RHS));
+ }
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFAdd(LHS, RHS));
}
@@ -61,6 +64,9 @@ public:
Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getNSWSub(LHS, RHS));
}
+ Constant *CreateNUWSub(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getNUWSub(LHS, RHS));
+ }
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFSub(LHS, RHS));
}
@@ -70,6 +76,9 @@ public:
Constant *CreateNSWMul(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getNSWMul(LHS, RHS));
}
+ Constant *CreateNUWMul(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getNUWMul(LHS, RHS));
+ }
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFMul(LHS, RHS));
}
@@ -128,6 +137,9 @@ public:
Constant *CreateNSWNeg(Constant *C) const {
return Fold(ConstantExpr::getNSWNeg(C));
}
+ Constant *CreateNUWNeg(Constant *C) const {
+ return Fold(ConstantExpr::getNUWNeg(C));
+ }
Constant *CreateFNeg(Constant *C) const {
return Fold(ConstantExpr::getFNeg(C));
}
diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h
index fb22e3f..270ac52 100644
--- a/include/llvm/Support/TypeBuilder.h
+++ b/include/llvm/Support/TypeBuilder.h
@@ -231,6 +231,12 @@ public:
/// we special case it.
template<> class TypeBuilder<void*, false>
: public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<const void*, false>
+ : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<volatile void*, false>
+ : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<const volatile void*, false>
+ : public TypeBuilder<types::i<8>*, false> {};
template<typename R, bool cross> class TypeBuilder<R(), cross> {
public:
diff --git a/include/llvm/System/DynamicLibrary.h b/include/llvm/System/DynamicLibrary.h
index ac58407..745b8f8 100644
--- a/include/llvm/System/DynamicLibrary.h
+++ b/include/llvm/System/DynamicLibrary.h
@@ -23,7 +23,7 @@ namespace sys {
/// might be known as shared libraries, shared objects, dynamic shared
/// objects, or dynamic link libraries. Regardless of the terminology or the
/// operating system interface, this class provides a portable interface that
- /// allows dynamic libraries to be loaded and and searched for externally
+ /// allows dynamic libraries to be loaded and searched for externally
/// defined symbols. This is typically used to provide "plug-in" support.
/// It also allows for symbols to be defined which don't live in any library,
/// but rather the main program itself, useful on Windows where the main
diff --git a/include/llvm/System/Path.h b/include/llvm/System/Path.h
index bdfb9aa..1be27b2 100644
--- a/include/llvm/System/Path.h
+++ b/include/llvm/System/Path.h
@@ -28,7 +28,7 @@ namespace sys {
/// platform independent and eliminates many of the unix-specific fields.
/// However, to support llvm-ar, the mode, user, and group fields are
/// retained. These pertain to unix security and may not have a meaningful
- /// value on non-Unix platforms. However, the other fields fields should
+ /// value on non-Unix platforms. However, the other fields should
/// always be applicable on all platforms. The structure is filled in by
/// the PathWithStatus class.
/// @brief File status structure
diff --git a/include/llvm/System/Program.h b/include/llvm/System/Program.h
index 6799562..69ce478 100644
--- a/include/llvm/System/Program.h
+++ b/include/llvm/System/Program.h
@@ -120,10 +120,12 @@ namespace sys {
/// @brief Construct a Program by finding it by name.
static Path FindProgramByName(const std::string& name);
- // These methods change the specified standard stream (stdin or stdout) to
- // binary mode. They return true if an error occurred
+ // These methods change the specified standard stream (stdin,
+ // stdout, or stderr) to binary mode. They return true if an error
+ // occurred
static bool ChangeStdinToBinary();
static bool ChangeStdoutToBinary();
+ static bool ChangeStderrToBinary();
/// A convenience function equivalent to Program prg; prg.Execute(..);
/// prg.Wait(..);
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index 04de4e9..45cbf9d 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===//
+//===-- llvm/Target/Mangler.h - Self-contained name mangler ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 354e743..9a117df 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -376,7 +376,7 @@ class OptionalDefOperand<ValueType ty, dag OpTypes, dag defaultops>
// InstrInfo - This class should only be instantiated once to provide parameters
-// which are global to the the target machine.
+// which are global to the target machine.
//
class InstrInfo {
// If the target wants to associate some target-specific information with each
@@ -399,19 +399,19 @@ def PHI : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops variable_ops);
let AsmString = "PHINODE";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
}
def INLINEASM : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops variable_ops);
let AsmString = "";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
}
def DBG_LABEL : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops i32imm:$id);
let AsmString = "";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
let hasCtrlDep = 1;
let isNotDuplicable = 1;
}
@@ -419,7 +419,7 @@ def EH_LABEL : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops i32imm:$id);
let AsmString = "";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
let hasCtrlDep = 1;
let isNotDuplicable = 1;
}
@@ -427,7 +427,7 @@ def GC_LABEL : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops i32imm:$id);
let AsmString = "";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
let hasCtrlDep = 1;
let isNotDuplicable = 1;
}
@@ -435,21 +435,21 @@ def KILL : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops variable_ops);
let AsmString = "";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
}
def EXTRACT_SUBREG : Instruction {
let OutOperandList = (ops unknown:$dst);
let InOperandList = (ops unknown:$supersrc, i32imm:$subidx);
let AsmString = "";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
}
def INSERT_SUBREG : Instruction {
let OutOperandList = (ops unknown:$dst);
let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
let Constraints = "$supersrc = $dst";
}
@@ -457,7 +457,7 @@ def IMPLICIT_DEF : Instruction {
let OutOperandList = (ops unknown:$dst);
let InOperandList = (ops);
let AsmString = "";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
let isReMaterializable = 1;
let isAsCheapAsAMove = 1;
@@ -466,22 +466,22 @@ def SUBREG_TO_REG : Instruction {
let OutOperandList = (ops unknown:$dst);
let InOperandList = (ops unknown:$implsrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
}
def COPY_TO_REGCLASS : Instruction {
let OutOperandList = (ops unknown:$dst);
let InOperandList = (ops unknown:$src, i32imm:$regclass);
let AsmString = "";
- let Namespace = "TargetInstrInfo";
+ let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
let isAsCheapAsAMove = 1;
}
-def DEBUG_VALUE : Instruction {
+def DBG_VALUE : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops variable_ops);
- let AsmString = "DEBUG_VALUE";
- let Namespace = "TargetInstrInfo";
+ let AsmString = "DBG_VALUE";
+ let Namespace = "TargetOpcode";
let isAsCheapAsAMove = 1;
}
}
diff --git a/include/llvm/Target/TargetAsmLexer.h b/include/llvm/Target/TargetAsmLexer.h
index daba1ba..9fcf449 100644
--- a/include/llvm/Target/TargetAsmLexer.h
+++ b/include/llvm/Target/TargetAsmLexer.h
@@ -38,12 +38,22 @@ protected: // Can only create subclasses.
/// TheTarget - The Target that this machine was created for.
const Target &TheTarget;
+ MCAsmLexer *Lexer;
public:
virtual ~TargetAsmLexer();
const Target &getTarget() const { return TheTarget; }
+ /// InstallLexer - Set the lexer to get tokens from lower-level lexer \arg L.
+ void InstallLexer(MCAsmLexer &L) {
+ Lexer = &L;
+ }
+
+ MCAsmLexer *getLexer() {
+ return Lexer;
+ }
+
/// Lex - Consume the next token from the input stream and return it.
const AsmToken &Lex() {
return CurTok = LexToken();
diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h
index 2e63188..cc88dae 100644
--- a/include/llvm/Target/TargetData.h
+++ b/include/llvm/Target/TargetData.h
@@ -224,6 +224,11 @@ public:
/// getABITypeAlignment - Return the minimum ABI-required alignment for the
/// specified type.
unsigned char getABITypeAlignment(const Type *Ty) const;
+
+ /// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for
+ /// an integer type of the specified bitwidth.
+ unsigned char getABIIntegerTypeAlignment(unsigned BitWidth) const;
+
/// getCallFrameTypeAlignment - Return the minimum ABI-required alignment
/// for the specified type when it is part of a call frame.
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 7144fe0..d95e4e8 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -45,55 +45,6 @@ public:
TargetInstrInfo(const TargetInstrDesc *desc, unsigned NumOpcodes);
virtual ~TargetInstrInfo();
- // Invariant opcodes: All instruction sets have these as their low opcodes.
- enum {
- PHI = 0,
- INLINEASM = 1,
- DBG_LABEL = 2,
- EH_LABEL = 3,
- GC_LABEL = 4,
-
- /// KILL - This instruction is a noop that is used only to adjust the liveness
- /// of registers. This can be useful when dealing with sub-registers.
- KILL = 5,
-
- /// EXTRACT_SUBREG - This instruction takes two operands: a register
- /// that has subregisters, and a subregister index. It returns the
- /// extracted subregister value. This is commonly used to implement
- /// truncation operations on target architectures which support it.
- EXTRACT_SUBREG = 6,
-
- /// INSERT_SUBREG - This instruction takes three operands: a register
- /// that has subregisters, a register providing an insert value, and a
- /// subregister index. It returns the value of the first register with
- /// the value of the second register inserted. The first register is
- /// often defined by an IMPLICIT_DEF, as is commonly used to implement
- /// anyext operations on target architectures which support it.
- INSERT_SUBREG = 7,
-
- /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
- IMPLICIT_DEF = 8,
-
- /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except
- /// that the first operand is an immediate integer constant. This constant
- /// is often zero, as is commonly used to implement zext operations on
- /// target architectures which support it, such as with x86-64 (with
- /// zext from i32 to i64 via implicit zero-extension).
- SUBREG_TO_REG = 9,
-
- /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain
- /// register-to-register copy into a specific register class. This is only
- /// used between instruction selection and MachineInstr creation, before
- /// virtual registers have been created for all the instructions, and it's
- /// only needed in cases where the register classes implied by the
- /// instructions are insufficient. The actual MachineInstrs to perform
- /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook.
- COPY_TO_REGCLASS = 10,
-
- // DEBUG_VALUE - a mapping of the llvm.dbg.value intrinsic
- DEBUG_VALUE = 11
- };
-
unsigned getNumOpcodes() const { return NumOpcodes; }
/// get - Return the machine instruction descriptor that corresponds to the
@@ -109,7 +60,7 @@ public:
/// that aren't always available.
bool isTriviallyReMaterializable(const MachineInstr *MI,
AliasAnalysis *AA = 0) const {
- return MI->getOpcode() == IMPLICIT_DEF ||
+ return MI->getOpcode() == TargetOpcode::IMPLICIT_DEF ||
(MI->getDesc().isRematerializable() &&
(isReallyTriviallyReMaterializable(MI, AA) ||
isReallyTriviallyReMaterializableGeneric(MI, AA)));
@@ -167,12 +118,12 @@ public:
SrcReg == DstReg)
return true;
- if (MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG &&
+ if (MI.getOpcode() == TargetOpcode::EXTRACT_SUBREG &&
MI.getOperand(0).getReg() == MI.getOperand(1).getReg())
return true;
- if ((MI.getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- MI.getOpcode() == TargetInstrInfo::SUBREG_TO_REG) &&
+ if ((MI.getOpcode() == TargetOpcode::INSERT_SUBREG ||
+ MI.getOpcode() == TargetOpcode::SUBREG_TO_REG) &&
MI.getOperand(0).getReg() == MI.getOperand(2).getReg())
return true;
return false;
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 15da845..c6ac89a 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -46,7 +46,10 @@ namespace llvm {
class MachineFunction;
class MachineFrameInfo;
class MachineInstr;
+ class MachineJumpTableInfo;
class MachineModuleInfo;
+ class MCContext;
+ class MCExpr;
class DwarfWriter;
class SDNode;
class SDValue;
@@ -115,10 +118,6 @@ public:
MVT getPointerTy() const { return PointerTy; }
MVT getShiftAmountTy() const { return ShiftAmountTy; }
- /// usesGlobalOffsetTable - Return true if this target uses a GOT for PIC
- /// codegen.
- bool usesGlobalOffsetTable() const { return UsesGlobalOffsetTable; }
-
/// isSelectExpensive - Return true if the select operation is expensive for
/// this target.
bool isSelectExpensive() const { return SelectIsExpensive; }
@@ -347,6 +346,11 @@ public:
return true;
}
+ /// canOpTrap - Returns true if the operation can trap for the value type.
+ /// VT must be a legal type. By default, we optimistically assume most
+ /// operations don't trap except for divide and remainder.
+ virtual bool canOpTrap(unsigned Op, EVT VT) const;
+
/// isVectorClearMaskLegal - Similar to isShuffleMaskLegal. This is
/// used by Targets can use this to indicate if there is a suitable
/// VECTOR_SHUFFLE that can be used to replace a VAND with a constant
@@ -752,11 +756,31 @@ public:
return false;
}
+ /// getJumpTableEncoding - Return the entry encoding for a jump table in the
+ /// current function. The returned value is a member of the
+ /// MachineJumpTableInfo::JTEntryKind enum.
+ virtual unsigned getJumpTableEncoding() const;
+
+ virtual const MCExpr *
+ LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
+ const MachineBasicBlock *MBB, unsigned uid,
+ MCContext &Ctx) const {
+ assert(0 && "Need to implement this hook if target has custom JTIs");
+ return 0;
+ }
+
/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
/// jumptable.
virtual SDValue getPICJumpTableRelocBase(SDValue Table,
- SelectionDAG &DAG) const;
-
+ SelectionDAG &DAG) const;
+
+ /// getPICJumpTableRelocBaseExpr - This returns the relocation base for the
+ /// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an
+ /// MCExpr.
+ virtual const MCExpr *
+ getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
+ unsigned JTI, MCContext &Ctx) const;
+
/// isOffsetFoldingLegal - Return true if folding a constant offset
/// with the given GlobalAddress is legal. It is frequently not legal in
/// PIC relocation models.
@@ -886,10 +910,6 @@ public:
//
protected:
- /// setUsesGlobalOffsetTable - Specify that this target does or doesn't use a
- /// GOT for PC-relative code.
- void setUsesGlobalOffsetTable(bool V) { UsesGlobalOffsetTable = V; }
-
/// setShiftAmountType - Describe the type that should be used for shift
/// amounts. This type defaults to the pointer type.
void setShiftAmountType(MVT VT) { ShiftAmountTy = VT; }
@@ -1152,15 +1172,9 @@ public:
/// described by the Ins array. The implementation should fill in the
/// InVals array with legal-type return values from the call, and return
/// the resulting token chain value.
- ///
- /// The isTailCall flag here is normative. If it is true, the
- /// implementation must emit a tail call. The
- /// IsEligibleForTailCallOptimization hook should be used to catch
- /// cases that cannot be handled.
- ///
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
- CallingConv::ID CallConv, bool isVarArg, bool isTailCall,
+ CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
@@ -1286,19 +1300,6 @@ public:
assert(0 && "ReplaceNodeResults not implemented for this target!");
}
- /// IsEligibleForTailCallOptimization - Check whether the call is eligible for
- /// tail call optimization. Targets which want to do tail call optimization
- /// should override this function.
- virtual bool
- IsEligibleForTailCallOptimization(SDValue Callee,
- CallingConv::ID CalleeCC,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- SelectionDAG& DAG) const {
- // Conservative default: no calls are eligible.
- return false;
- }
-
/// getTargetNodeName() - This method returns the name of a target specific
/// DAG node.
virtual const char *getTargetNodeName(unsigned Opcode) const;
@@ -1572,10 +1573,6 @@ private:
///
bool IsLittleEndian;
- /// UsesGlobalOffsetTable - True if this target uses a GOT for PIC codegen.
- ///
- bool UsesGlobalOffsetTable;
-
/// SelectIsExpensive - Tells the code generator not to expand operations
/// into sequences that use the select operations if possible.
bool SelectIsExpensive;
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index d3e5cf2..42d88a0 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -25,6 +25,7 @@ namespace llvm {
class MCExpr;
class MCSection;
class MCSectionMachO;
+ class MCSymbol;
class MCContext;
class GlobalValue;
class TargetMachine;
@@ -175,187 +176,26 @@ public:
return 0;
}
- /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a
- /// pc-relative reference to the specified global variable from exception
- /// handling information. In addition to the symbol, this returns
- /// by-reference:
- ///
- /// IsIndirect - True if the returned symbol is actually a stub that contains
- /// the address of the symbol, false if the symbol is the global itself.
- ///
- /// IsPCRel - True if the symbol reference is already pc-relative, false if
- /// the caller needs to subtract off the address of the reference from the
- /// symbol.
+ /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a reference
+ /// to the specified global variable from exception handling information.
///
virtual const MCExpr *
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const;
-
-protected:
- virtual const MCSection *
- SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-};
-
-
-
+ MachineModuleInfo *MMI, unsigned Encoding) const;
-class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
- mutable void *UniquingMap;
-protected:
- /// TLSDataSection - Section directive for Thread Local data.
- ///
- const MCSection *TLSDataSection; // Defaults to ".tdata".
-
- /// TLSBSSSection - Section directive for Thread Local uninitialized data.
- /// Null if this target doesn't support a BSS section.
- ///
- const MCSection *TLSBSSSection; // Defaults to ".tbss".
-
- const MCSection *DataRelSection;
- const MCSection *DataRelLocalSection;
- const MCSection *DataRelROSection;
- const MCSection *DataRelROLocalSection;
-
- const MCSection *MergeableConst4Section;
- const MCSection *MergeableConst8Section;
- const MCSection *MergeableConst16Section;
-
-protected:
- const MCSection *getELFSection(StringRef Section, unsigned Type,
- unsigned Flags, SectionKind Kind,
- bool IsExplicit = false) const;
-public:
- TargetLoweringObjectFileELF() : UniquingMap(0) {}
- ~TargetLoweringObjectFileELF();
-
- virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
-
- /// getSectionForConstant - Given a constant with the SectionKind, return a
- /// section that it should be placed in.
- virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
-
-
- virtual const MCSection *
- getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-
- virtual const MCSection *
- SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-};
-
-
-
-class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
- mutable void *UniquingMap;
-
- const MCSection *CStringSection;
- const MCSection *UStringSection;
- const MCSection *TextCoalSection;
- const MCSection *ConstTextCoalSection;
- const MCSection *ConstDataCoalSection;
- const MCSection *ConstDataSection;
- const MCSection *DataCoalSection;
- const MCSection *DataCommonSection;
- const MCSection *DataBSSSection;
- const MCSection *FourByteConstantSection;
- const MCSection *EightByteConstantSection;
- const MCSection *SixteenByteConstantSection;
-
- const MCSection *LazySymbolPointerSection;
- const MCSection *NonLazySymbolPointerSection;
-public:
- TargetLoweringObjectFileMachO() : UniquingMap(0) {}
- ~TargetLoweringObjectFileMachO();
-
- virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
-
- virtual const MCSection *
- SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-
- virtual const MCSection *
- getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-
- virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
-
- /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
- /// decide not to emit the UsedDirective for some symbols in llvm.used.
- /// FIXME: REMOVE this (rdar://7071300)
- virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
- Mangler *) const;
-
- /// getMachOSection - Return the MCSection for the specified mach-o section.
- /// This requires the operands to be valid.
- const MCSectionMachO *getMachOSection(StringRef Segment,
- StringRef Section,
- unsigned TypeAndAttributes,
- SectionKind K) const {
- return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
- }
- const MCSectionMachO *getMachOSection(StringRef Segment,
- StringRef Section,
- unsigned TypeAndAttributes,
- unsigned Reserved2,
- SectionKind K) const;
-
- /// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak
- /// text symbols into.
- const MCSection *getTextCoalSection() const {
- return TextCoalSection;
- }
-
- /// getConstTextCoalSection - Return the "__TEXT,__const_coal" section
- /// we put weak read-only symbols into.
- const MCSection *getConstTextCoalSection() const {
- return ConstTextCoalSection;
- }
-
- /// getLazySymbolPointerSection - Return the section corresponding to
- /// the .lazy_symbol_pointer directive.
- const MCSection *getLazySymbolPointerSection() const {
- return LazySymbolPointerSection;
- }
-
- /// getNonLazySymbolPointerSection - Return the section corresponding to
- /// the .non_lazy_symbol_pointer directive.
- const MCSection *getNonLazySymbolPointerSection() const {
- return NonLazySymbolPointerSection;
- }
-
- /// getSymbolForDwarfGlobalReference - The mach-o version of this method
- /// defaults to returning a stub reference.
virtual const MCExpr *
- getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const;
-};
+ getSymbolForDwarfReference(const MCSymbol *Sym, MachineModuleInfo *MMI,
+ unsigned Encoding) const;
+ virtual unsigned getPersonalityEncoding() const;
+ virtual unsigned getLSDAEncoding() const;
+ virtual unsigned getFDEEncoding() const;
+ virtual unsigned getTTypeEncoding() const;
-
-class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
- mutable void *UniquingMap;
-public:
- TargetLoweringObjectFileCOFF() : UniquingMap(0) {}
- ~TargetLoweringObjectFileCOFF();
-
- virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
-
- virtual const MCSection *
- getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
-
+protected:
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const;
-
- /// getCOFFSection - Return the MCSection for the specified COFF section.
- /// FIXME: Switch this to a semantic view eventually.
- const MCSection *getCOFFSection(StringRef Name, bool isDirective,
- SectionKind K) const;
};
} // end namespace llvm
diff --git a/include/llvm/Target/TargetMachOWriterInfo.h b/include/llvm/Target/TargetMachOWriterInfo.h
deleted file mode 100644
index f723bb5..0000000
--- a/include/llvm/Target/TargetMachOWriterInfo.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===-- llvm/Target/TargetMachOWriterInfo.h - MachO Writer Info--*- 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 TargetMachOWriterInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_TARGETMACHOWRITERINFO_H
-#define LLVM_TARGET_TARGETMACHOWRITERINFO_H
-
-#include "llvm/CodeGen/MachineRelocation.h"
-
-namespace llvm {
-
- class MachineBasicBlock;
- class OutputBuffer;
-
- //===--------------------------------------------------------------------===//
- // TargetMachOWriterInfo
- //===--------------------------------------------------------------------===//
-
- class TargetMachOWriterInfo {
- uint32_t CPUType; // CPU specifier
- uint32_t CPUSubType; // Machine specifier
- public:
- // The various CPU_TYPE_* constants are already defined by at least one
- // system header file and create compilation errors if not respected.
-#if !defined(CPU_TYPE_I386)
-#define CPU_TYPE_I386 7
-#endif
-#if !defined(CPU_TYPE_X86_64)
-#define CPU_TYPE_X86_64 (CPU_TYPE_I386 | 0x1000000)
-#endif
-#if !defined(CPU_TYPE_ARM)
-#define CPU_TYPE_ARM 12
-#endif
-#if !defined(CPU_TYPE_SPARC)
-#define CPU_TYPE_SPARC 14
-#endif
-#if !defined(CPU_TYPE_POWERPC)
-#define CPU_TYPE_POWERPC 18
-#endif
-#if !defined(CPU_TYPE_POWERPC64)
-#define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | 0x1000000)
-#endif
-
- // Constants for the cputype field
- // see <mach/machine.h>
- enum {
- HDR_CPU_TYPE_I386 = CPU_TYPE_I386,
- HDR_CPU_TYPE_X86_64 = CPU_TYPE_X86_64,
- HDR_CPU_TYPE_ARM = CPU_TYPE_ARM,
- HDR_CPU_TYPE_SPARC = CPU_TYPE_SPARC,
- HDR_CPU_TYPE_POWERPC = CPU_TYPE_POWERPC,
- HDR_CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC64
- };
-
-#if !defined(CPU_SUBTYPE_I386_ALL)
-#define CPU_SUBTYPE_I386_ALL 3
-#endif
-#if !defined(CPU_SUBTYPE_X86_64_ALL)
-#define CPU_SUBTYPE_X86_64_ALL 3
-#endif
-#if !defined(CPU_SUBTYPE_ARM_ALL)
-#define CPU_SUBTYPE_ARM_ALL 0
-#endif
-#if !defined(CPU_SUBTYPE_SPARC_ALL)
-#define CPU_SUBTYPE_SPARC_ALL 0
-#endif
-#if !defined(CPU_SUBTYPE_POWERPC_ALL)
-#define CPU_SUBTYPE_POWERPC_ALL 0
-#endif
-
- // Constants for the cpusubtype field
- // see <mach/machine.h>
- enum {
- HDR_CPU_SUBTYPE_I386_ALL = CPU_SUBTYPE_I386_ALL,
- HDR_CPU_SUBTYPE_X86_64_ALL = CPU_SUBTYPE_X86_64_ALL,
- HDR_CPU_SUBTYPE_ARM_ALL = CPU_SUBTYPE_ARM_ALL,
- HDR_CPU_SUBTYPE_SPARC_ALL = CPU_SUBTYPE_SPARC_ALL,
- HDR_CPU_SUBTYPE_POWERPC_ALL = CPU_SUBTYPE_POWERPC_ALL
- };
-
- TargetMachOWriterInfo(uint32_t cputype, uint32_t cpusubtype)
- : CPUType(cputype), CPUSubType(cpusubtype) {}
- virtual ~TargetMachOWriterInfo();
-
- virtual MachineRelocation GetJTRelocation(unsigned Offset,
- MachineBasicBlock *MBB) const;
-
- virtual unsigned GetTargetRelocation(MachineRelocation &MR,
- unsigned FromIdx,
- unsigned ToAddr,
- unsigned ToIdx,
- OutputBuffer &RelocOut,
- OutputBuffer &SecOut,
- bool Scattered,
- bool Extern) const { return 0; }
-
- uint32_t getCPUType() const { return CPUType; }
- uint32_t getCPUSubType() const { return CPUSubType; }
- };
-
-} // end llvm namespace
-
-#endif // LLVM_TARGET_TARGETMACHOWRITERINFO_H
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 4db3d3e..c496e11 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -29,14 +29,11 @@ class TargetIntrinsicInfo;
class TargetJITInfo;
class TargetLowering;
class TargetFrameInfo;
-class MachineCodeEmitter;
class JITCodeEmitter;
-class ObjectCodeEmitter;
class TargetRegisterInfo;
class PassManagerBase;
class PassManager;
class Pass;
-class TargetMachOWriterInfo;
class TargetELFWriterInfo;
class formatted_raw_ostream;
@@ -61,16 +58,6 @@ namespace CodeModel {
};
}
-namespace FileModel {
- enum Model {
- Error,
- None,
- AsmFile,
- MachOFile,
- ElfFile
- };
-}
-
// Code generation optimization level.
namespace CodeGenOpt {
enum Level {
@@ -81,15 +68,6 @@ namespace CodeGenOpt {
};
}
-// Specify if we should encode the LSDA pointer in the FDE as 4- or 8-bytes.
-namespace DwarfLSDAEncoding {
- enum Encoding {
- Default,
- FourByte,
- EightByte
- };
-}
-
//===----------------------------------------------------------------------===//
///
/// TargetMachine - Primary interface to the complete machine description for
@@ -163,11 +141,6 @@ public:
return InstrItineraryData();
}
- /// getMachOWriterInfo - If this target supports a Mach-O writer, return
- /// information for it, otherwise return null.
- ///
- virtual const TargetMachOWriterInfo *getMachOWriterInfo() const { return 0; }
-
/// getELFWriterInfo - If this target supports an ELF writer, return
/// information for it, otherwise return null.
///
@@ -197,24 +170,13 @@ public:
/// is false.
static void setAsmVerbosityDefault(bool);
- /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are
- /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that
- /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded
- /// as a 4-byte pointer by default. However, some systems may require a
- /// different size due to bugs or other conditions. We will default to a
- /// 4-byte encoding unless the system tells us otherwise.
- ///
- /// FIXME: This call-back isn't good! We should be using the correct encoding
- /// regardless of the system. However, there are some systems which have bugs
- /// that prevent this from occuring.
- virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const {
- return DwarfLSDAEncoding::Default;
- }
-
/// CodeGenFileType - These enums are meant to be passed into
- /// addPassesToEmitFile to indicate what type of file to emit.
+ /// addPassesToEmitFile to indicate what type of file to emit, and returned by
+ /// it to indicate what type of file could actually be made.
enum CodeGenFileType {
- AssemblyFile, ObjectFile, DynamicLibrary
+ CGFT_AssemblyFile,
+ CGFT_ObjectFile,
+ CGFT_Null // Do not emit any output.
};
/// getEnableTailMergeDefault - the default setting for -enable-tail-merge
@@ -223,61 +185,17 @@ public:
/// addPassesToEmitFile - Add passes to the specified pass manager to get the
/// specified file emitted. Typically this will involve several steps of code
- /// generation.
- /// This method should return FileModel::Error if emission of this file type
- /// is not supported.
- ///
- virtual FileModel::Model addPassesToEmitFile(PassManagerBase &,
- formatted_raw_ostream &,
- CodeGenFileType,
- CodeGenOpt::Level) {
- return FileModel::None;
- }
-
- /// addPassesToEmitFileFinish - If the passes to emit the specified file had
- /// to be split up (e.g., to add an object writer pass), this method can be
- /// used to finish up adding passes to emit the file, if necessary.
- ///
- virtual bool addPassesToEmitFileFinish(PassManagerBase &,
- MachineCodeEmitter *,
- CodeGenOpt::Level) {
- return true;
- }
-
- /// addPassesToEmitFileFinish - If the passes to emit the specified file had
- /// to be split up (e.g., to add an object writer pass), this method can be
- /// used to finish up adding passes to emit the file, if necessary.
- ///
- virtual bool addPassesToEmitFileFinish(PassManagerBase &,
- JITCodeEmitter *,
- CodeGenOpt::Level) {
- return true;
- }
-
- /// addPassesToEmitFileFinish - If the passes to emit the specified file had
- /// to be split up (e.g., to add an object writer pass), this method can be
- /// used to finish up adding passes to emit the file, if necessary.
- ///
- virtual bool addPassesToEmitFileFinish(PassManagerBase &,
- ObjectCodeEmitter *,
- CodeGenOpt::Level) {
- return true;
- }
-
- /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
- /// get machine code emitted. This uses a MachineCodeEmitter object to handle
- /// actually outputting the machine code and resolving things like the address
- /// of functions. This method returns true if machine code emission is
- /// not supported.
- ///
- virtual bool addPassesToEmitMachineCode(PassManagerBase &,
- MachineCodeEmitter &,
- CodeGenOpt::Level) {
+ /// generation. This method should return true if emission of this file type
+ /// is not supported, or false on success.
+ virtual bool addPassesToEmitFile(PassManagerBase &,
+ formatted_raw_ostream &,
+ CodeGenFileType Filetype,
+ CodeGenOpt::Level) {
return true;
}
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
- /// get machine code emitted. This uses a MachineCodeEmitter object to handle
+ /// get machine code emitted. This uses a JITCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
/// of functions. This method returns true if machine code emission is
/// not supported.
@@ -312,9 +230,6 @@ protected: // Can only create subclasses.
bool addCommonCodeGenPasses(PassManagerBase &, CodeGenOpt::Level);
private:
- // These routines are used by addPassesToEmitFileFinish and
- // addPassesToEmitMachineCode to set the CodeModel if it's still marked
- // as default.
virtual void setCodeModelForJIT();
virtual void setCodeModelForStatic();
@@ -322,56 +237,15 @@ public:
/// addPassesToEmitFile - Add passes to the specified pass manager to get the
/// specified file emitted. Typically this will involve several steps of code
- /// generation. If OptLevel is None, the code generator should emit code as fast
- /// as possible, though the generated code may be less efficient. This method
- /// should return FileModel::Error if emission of this file type is not
- /// supported.
- ///
- /// The default implementation of this method adds components from the
- /// LLVM retargetable code generator, invoking the methods below to get
- /// target-specific passes in standard locations.
- ///
- virtual FileModel::Model addPassesToEmitFile(PassManagerBase &PM,
- formatted_raw_ostream &Out,
- CodeGenFileType FileType,
- CodeGenOpt::Level);
-
- /// addPassesToEmitFileFinish - If the passes to emit the specified file had
- /// to be split up (e.g., to add an object writer pass), this method can be
- /// used to finish up adding passes to emit the file, if necessary.
- ///
- virtual bool addPassesToEmitFileFinish(PassManagerBase &PM,
- MachineCodeEmitter *MCE,
- CodeGenOpt::Level);
-
- /// addPassesToEmitFileFinish - If the passes to emit the specified file had
- /// to be split up (e.g., to add an object writer pass), this method can be
- /// used to finish up adding passes to emit the file, if necessary.
- ///
- virtual bool addPassesToEmitFileFinish(PassManagerBase &PM,
- JITCodeEmitter *JCE,
- CodeGenOpt::Level);
-
- /// addPassesToEmitFileFinish - If the passes to emit the specified file had
- /// to be split up (e.g., to add an object writer pass), this method can be
- /// used to finish up adding passes to emit the file, if necessary.
- ///
- virtual bool addPassesToEmitFileFinish(PassManagerBase &PM,
- ObjectCodeEmitter *OCE,
- CodeGenOpt::Level);
-
- /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
- /// get machine code emitted. This uses a MachineCodeEmitter object to handle
- /// actually outputting the machine code and resolving things like the address
- /// of functions. This method returns true if machine code emission is
- /// not supported.
- ///
- virtual bool addPassesToEmitMachineCode(PassManagerBase &PM,
- MachineCodeEmitter &MCE,
- CodeGenOpt::Level);
+ /// generation. If OptLevel is None, the code generator should emit code as
+ /// fast as possible, though the generated code may be less efficient.
+ virtual bool addPassesToEmitFile(PassManagerBase &PM,
+ formatted_raw_ostream &Out,
+ CodeGenFileType FileType,
+ CodeGenOpt::Level);
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
- /// get machine code emitted. This uses a MachineCodeEmitter object to handle
+ /// get machine code emitted. This uses a JITCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
/// of functions. This method returns true if machine code emission is
/// not supported.
@@ -424,61 +298,13 @@ public:
/// code emitter, if supported. If this is not supported, 'true' should be
/// returned.
virtual bool addCodeEmitter(PassManagerBase &, CodeGenOpt::Level,
- MachineCodeEmitter &) {
- return true;
- }
-
- /// addCodeEmitter - This pass should be overridden by the target to add a
- /// code emitter, if supported. If this is not supported, 'true' should be
- /// returned.
- virtual bool addCodeEmitter(PassManagerBase &, CodeGenOpt::Level,
JITCodeEmitter &) {
return true;
}
- /// addSimpleCodeEmitter - This pass should be overridden by the target to add
- /// a code emitter (without setting flags), if supported. If this is not
- /// supported, 'true' should be returned.
- virtual bool addSimpleCodeEmitter(PassManagerBase &, CodeGenOpt::Level,
- MachineCodeEmitter &) {
- return true;
- }
-
- /// addSimpleCodeEmitter - This pass should be overridden by the target to add
- /// a code emitter (without setting flags), if supported. If this is not
- /// supported, 'true' should be returned.
- virtual bool addSimpleCodeEmitter(PassManagerBase &, CodeGenOpt::Level,
- JITCodeEmitter &) {
- return true;
- }
-
- /// addSimpleCodeEmitter - This pass should be overridden by the target to add
- /// a code emitter (without setting flags), if supported. If this is not
- /// supported, 'true' should be returned.
- virtual bool addSimpleCodeEmitter(PassManagerBase &, CodeGenOpt::Level,
- ObjectCodeEmitter &) {
- return true;
- }
-
/// getEnableTailMergeDefault - the default setting for -enable-tail-merge
/// on this target. User flag overrides.
virtual bool getEnableTailMergeDefault() const { return true; }
-
- /// addAssemblyEmitter - Helper function which creates a target specific
- /// assembly printer, if available.
- ///
- /// \return Returns 'false' on success.
- bool addAssemblyEmitter(PassManagerBase &, CodeGenOpt::Level,
- bool /* VerboseAsmDefault */,
- formatted_raw_ostream &);
-
- /// addObjectFileEmitter - Helper function which creates a target specific
- /// object files emitter, if available. This interface is temporary, for
- /// bringing up MCAssembler-based object file emitters.
- ///
- /// \return Returns 'false' on success.
- bool addObjectFileEmitter(PassManagerBase &, CodeGenOpt::Level,
- formatted_raw_ostream &);
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h
new file mode 100644
index 0000000..10cb45f
--- /dev/null
+++ b/include/llvm/Target/TargetOpcodes.h
@@ -0,0 +1,72 @@
+//===-- llvm/Target/TargetOpcodes.h - Target Indep Opcodes ------*- 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 target independent instruction opcodes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETOPCODES_H
+#define LLVM_TARGET_TARGETOPCODES_H
+
+namespace llvm {
+
+// Invariant opcodes: All instruction sets have these as their low opcodes.
+namespace TargetOpcode {
+ enum {
+ PHI = 0,
+ INLINEASM = 1,
+ DBG_LABEL = 2,
+ EH_LABEL = 3,
+ GC_LABEL = 4,
+
+ /// KILL - This instruction is a noop that is used only to adjust the
+ /// liveness of registers. This can be useful when dealing with
+ /// sub-registers.
+ KILL = 5,
+
+ /// EXTRACT_SUBREG - This instruction takes two operands: a register
+ /// that has subregisters, and a subregister index. It returns the
+ /// extracted subregister value. This is commonly used to implement
+ /// truncation operations on target architectures which support it.
+ EXTRACT_SUBREG = 6,
+
+ /// INSERT_SUBREG - This instruction takes three operands: a register
+ /// that has subregisters, a register providing an insert value, and a
+ /// subregister index. It returns the value of the first register with
+ /// the value of the second register inserted. The first register is
+ /// often defined by an IMPLICIT_DEF, as is commonly used to implement
+ /// anyext operations on target architectures which support it.
+ INSERT_SUBREG = 7,
+
+ /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
+ IMPLICIT_DEF = 8,
+
+ /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except
+ /// that the first operand is an immediate integer constant. This constant
+ /// is often zero, as is commonly used to implement zext operations on
+ /// target architectures which support it, such as with x86-64 (with
+ /// zext from i32 to i64 via implicit zero-extension).
+ SUBREG_TO_REG = 9,
+
+ /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain
+ /// register-to-register copy into a specific register class. This is only
+ /// used between instruction selection and MachineInstr creation, before
+ /// virtual registers have been created for all the instructions, and it's
+ /// only needed in cases where the register classes implied by the
+ /// instructions are insufficient. The actual MachineInstrs to perform
+ /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook.
+ COPY_TO_REGCLASS = 10,
+
+ // DBG_VALUE - a mapping of the llvm.dbg.value intrinsic
+ DBG_VALUE = 11
+ };
+} // end namespace TargetOpcode
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index b43450d..b63c2bf 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -116,10 +116,13 @@ namespace llvm {
/// be emitted for all functions.
extern bool UnwindTablesMandatory;
- /// PerformTailCallOpt - This flag is enabled when -tailcallopt is specified
- /// on the commandline. When the flag is on, the target will perform tail call
- /// optimization (pop the caller's stack) providing it supports it.
- extern bool PerformTailCallOpt;
+ /// GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is
+ /// specified on the commandline. When the flag is on, participating targets
+ /// will perform tail call optimization on all calls which use the fastcc
+ /// calling convention and which satisfy certain target-independent
+ /// criteria (being at the end of a function, having the same return type
+ /// as their parent function, etc.), using an alternate ABI if necessary.
+ extern bool GuaranteedTailCallOpt;
/// StackAlignment - Override default stack alignment for target.
extern unsigned StackAlignment;
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index f93eadb..65b60f7 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -169,7 +169,7 @@ public:
return I;
}
- /// hasSubClass - return true if the the specified TargetRegisterClass
+ /// hasSubClass - return true if the specified TargetRegisterClass
/// is a proper subset of this TargetRegisterClass.
bool hasSubClass(const TargetRegisterClass *cs) const {
for (int i = 0; SubClasses[i] != NULL; ++i)
@@ -696,12 +696,12 @@ public:
/// getFrameIndexOffset - Returns the displacement from the frame register to
/// the stack frame of the specified index.
- virtual int getFrameIndexOffset(MachineFunction &MF, int FI) const;
+ virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
/// getFrameIndexReference - This method should return the base register
/// and offset used to reference a frame index location. The offset is
/// returned directly, and the base register is returned via FrameReg.
- virtual int getFrameIndexReference(MachineFunction &MF, int FI,
+ virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
unsigned &FrameReg) const {
// By default, assume all frame indices are referenced via whatever
// getFrameRegister() says. The target can override this if it's doing
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
index d3aa867..37380ab 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -25,12 +25,14 @@
namespace llvm {
class AsmPrinter;
- class MCAsmParser;
- class MCCodeEmitter;
class Module;
class MCAsmInfo;
+ class MCAsmParser;
+ class MCCodeEmitter;
+ class MCContext;
class MCDisassembler;
class MCInstPrinter;
+ class MCStreamer;
class TargetAsmLexer;
class TargetAsmParser;
class TargetMachine;
@@ -58,8 +60,9 @@ namespace llvm {
const std::string &Features);
typedef AsmPrinter *(*AsmPrinterCtorTy)(formatted_raw_ostream &OS,
TargetMachine &TM,
- const MCAsmInfo *MAI,
- bool VerboseAsm);
+ MCContext &Ctx,
+ MCStreamer &Streamer,
+ const MCAsmInfo *MAI);
typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T,
const MCAsmInfo &MAI);
typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P);
@@ -69,7 +72,8 @@ namespace llvm {
const MCAsmInfo &MAI,
raw_ostream &O);
typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
- TargetMachine &TM);
+ TargetMachine &TM,
+ MCContext &Ctx);
private:
/// Next - The next registered target in the linked list, maintained by the
@@ -189,12 +193,14 @@ namespace llvm {
return TargetMachineCtorFn(*this, Triple, Features);
}
- /// createAsmPrinter - Create a target specific assembly printer pass.
+ /// createAsmPrinter - Create a target specific assembly printer pass. This
+ /// takes ownership of the MCContext and MCStreamer objects but not the MAI.
AsmPrinter *createAsmPrinter(formatted_raw_ostream &OS, TargetMachine &TM,
- const MCAsmInfo *MAI, bool Verbose) const {
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *MAI) const {
if (!AsmPrinterCtorFn)
return 0;
- return AsmPrinterCtorFn(OS, TM, MAI, Verbose);
+ return AsmPrinterCtorFn(OS, TM, Ctx, Streamer, MAI);
}
/// createAsmLexer - Create a target specific assembly lexer.
@@ -231,10 +237,10 @@ namespace llvm {
/// createCodeEmitter - Create a target specific code emitter.
- MCCodeEmitter *createCodeEmitter(TargetMachine &TM) const {
+ MCCodeEmitter *createCodeEmitter(TargetMachine &TM, MCContext &Ctx) const {
if (!CodeEmitterCtorFn)
return 0;
- return CodeEmitterCtorFn(*this, TM);
+ return CodeEmitterCtorFn(*this, TM, Ctx);
}
/// @}
@@ -547,8 +553,9 @@ namespace llvm {
private:
static AsmPrinter *Allocator(formatted_raw_ostream &OS, TargetMachine &TM,
- const MCAsmInfo *MAI, bool Verbose) {
- return new AsmPrinterImpl(OS, TM, MAI, Verbose);
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *MAI) {
+ return new AsmPrinterImpl(OS, TM, Ctx, Streamer, MAI);
}
};
@@ -607,8 +614,9 @@ namespace llvm {
}
private:
- static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM) {
- return new CodeEmitterImpl(T, TM);
+ static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM,
+ MCContext &Ctx) {
+ return new CodeEmitterImpl(T, TM, Ctx);
}
};
diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h
index dc5e644..30ece0e 100644
--- a/include/llvm/Transforms/IPO/InlinerPass.h
+++ b/include/llvm/Transforms/IPO/InlinerPass.h
@@ -52,10 +52,11 @@ struct Inliner : public CallGraphSCCPass {
unsigned getInlineThreshold() const { return InlineThreshold; }
/// Calculate the inline threshold for given Caller. This threshold is lower
- /// if Caller is marked with OptimizeForSize and -inline-threshold is not
- /// given on the comand line.
+ /// if the caller is marked with OptimizeForSize and -inline-threshold is not
+ /// given on the comand line. It is higher if the callee is marked with the
+ /// inlinehint attribute.
///
- unsigned getInlineThreshold(Function* Caller) const;
+ unsigned getInlineThreshold(CallSite CS) const;
/// getInlineCost - This method must be implemented by the subclass to
/// determine the cost of inlining the specified call site. If the cost
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index 7fbbef9..5f494fb 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -19,6 +19,7 @@
#define LLVM_TRANSFORMS_UTILS_CLONING_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Twine.h"
namespace llvm {
@@ -101,7 +102,7 @@ struct ClonedCodeInfo {
///
BasicBlock *CloneBasicBlock(const BasicBlock *BB,
DenseMap<const Value*, Value*> &ValueMap,
- const char *NameSuffix = "", Function *F = 0,
+ const Twine &NameSuffix = "", Function *F = 0,
ClonedCodeInfo *CodeInfo = 0);
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index f6d9f82..bb6fd56 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -38,7 +38,8 @@ template<typename T> class SmallVectorImpl;
/// from this value cannot trap. If it is not obviously safe to load from the
/// specified pointer, we do a quick local scan of the basic block containing
/// ScanFrom, to determine if the address is already accessed.
-bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom);
+bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
+ unsigned Align, const TargetData *TD = 0);
//===----------------------------------------------------------------------===//
// Local constant propagation.
@@ -130,7 +131,7 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
///
/// WARNING: The entry node of a method may not be simplified.
///
-bool SimplifyCFG(BasicBlock *BB);
+bool SimplifyCFG(BasicBlock *BB, const TargetData *TD = 0);
/// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a branch,
/// and if a predecessor branches to us and one of our successors, fold the
diff --git a/include/llvm/Type.h b/include/llvm/Type.h
index 2c37a68..c52419c 100644
--- a/include/llvm/Type.h
+++ b/include/llvm/Type.h
@@ -82,10 +82,11 @@ public:
IntegerTyID, ///< 8: Arbitrary bit width integers
FunctionTyID, ///< 9: Functions
StructTyID, ///< 10: Structures
- ArrayTyID, ///< 11: Arrays
- PointerTyID, ///< 12: Pointers
- OpaqueTyID, ///< 13: Opaque: type with unknown structure
- VectorTyID, ///< 14: SIMD 'packed' format, or other vector type
+ UnionTyID, ///< 11: Unions
+ ArrayTyID, ///< 12: Arrays
+ PointerTyID, ///< 13: Pointers
+ OpaqueTyID, ///< 14: Opaque: type with unknown structure
+ VectorTyID, ///< 15: SIMD 'packed' format, or other vector type
NumTypeIDs, // Must remain as last defined ID
LastPrimitiveTyID = LabelTyID,
@@ -213,27 +214,47 @@ public:
/// getDescription - Return the string representation of the type.
std::string getDescription() const;
- /// isInteger - True if this is an instance of IntegerType.
+ /// isIntegerTy - True if this is an instance of IntegerType.
///
- bool isInteger() const { return ID == IntegerTyID; }
+ bool isIntegerTy() const { return ID == IntegerTyID; }
- /// isInteger - Return true if this is an IntegerType of the specified width.
- bool isInteger(unsigned Bitwidth) const;
+ /// isIntegerTy - Return true if this is an IntegerType of the given width.
+ bool isIntegerTy(unsigned Bitwidth) const;
- /// isIntOrIntVector - Return true if this is an integer type or a vector of
+ /// isIntOrIntVectorTy - Return true if this is an integer type or a vector of
/// integer types.
///
- bool isIntOrIntVector() const;
+ bool isIntOrIntVectorTy() const;
- /// isFloatingPoint - Return true if this is one of the five floating point
+ /// isFloatingPointTy - Return true if this is one of the five floating point
/// types
- bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID ||
+ bool isFloatingPointTy() const { return ID == FloatTyID || ID == DoubleTyID ||
ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; }
- /// isFPOrFPVector - Return true if this is a FP type or a vector of FP types.
+ /// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP.
///
- bool isFPOrFPVector() const;
-
+ bool isFPOrFPVectorTy() const;
+
+ /// isFunctionTy - True if this is an instance of FunctionType.
+ ///
+ bool isFunctionTy() const { return ID == FunctionTyID; }
+
+ /// isStructTy - True if this is an instance of StructType.
+ ///
+ bool isStructTy() const { return ID == StructTyID; }
+
+ /// isArrayTy - True if this is an instance of ArrayType.
+ ///
+ bool isArrayTy() const { return ID == ArrayTyID; }
+
+ /// isPointerTy - True if this is an instance of PointerType.
+ ///
+ bool isPointerTy() const { return ID == PointerTyID; }
+
+ /// isVectorTy - True if this is an instance of VectorType.
+ ///
+ bool isVectorTy() const { return ID == VectorTyID; }
+
/// isAbstract - True if the type is either an Opaque type, or is a derived
/// type that includes an opaque type somewhere in it.
///
@@ -277,7 +298,7 @@ public:
/// does not include vector types.
///
inline bool isAggregateType() const {
- return ID == StructTyID || ID == ArrayTyID;
+ return ID == StructTyID || ID == ArrayTyID || ID == UnionTyID;
}
/// isSized - Return true if it makes sense to take the size of this type. To
@@ -286,11 +307,12 @@ public:
///
bool isSized() const {
// If it's a primitive, it is always sized.
- if (ID == IntegerTyID || isFloatingPoint() || ID == PointerTyID)
+ if (ID == IntegerTyID || isFloatingPointTy() || ID == PointerTyID)
return true;
// If it is not something that can have a size (e.g. a function or label),
// it doesn't have a size.
- if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID)
+ if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID &&
+ ID != UnionTyID)
return false;
// If it is something that can have a size and it's concrete, it definitely
// has a size, otherwise we have to try harder to decide.
diff --git a/include/llvm/Value.h b/include/llvm/Value.h
index f0bd8be..d06cbc0 100644
--- a/include/llvm/Value.h
+++ b/include/llvm/Value.h
@@ -215,6 +215,7 @@ public:
ConstantFPVal, // This is an instance of ConstantFP
ConstantArrayVal, // This is an instance of ConstantArray
ConstantStructVal, // This is an instance of ConstantStruct
+ ConstantUnionVal, // This is an instance of ConstantUnion
ConstantVectorVal, // This is an instance of ConstantVector
ConstantPointerNullVal, // This is an instance of ConstantPointerNull
MDNodeVal, // This is an instance of MDNode
@@ -285,10 +286,11 @@ public:
/// getUnderlyingObject - This method strips off any GEP address adjustments
/// and pointer casts from the specified value, returning the original object
/// being addressed. Note that the returned value has pointer type if the
- /// specified value does.
- Value *getUnderlyingObject();
- const Value *getUnderlyingObject() const {
- return const_cast<Value*>(this)->getUnderlyingObject();
+ /// specified value does. If the MaxLookup value is non-zero, it limits the
+ /// number of instructions to be stripped off.
+ Value *getUnderlyingObject(unsigned MaxLookup = 6);
+ const Value *getUnderlyingObject(unsigned MaxLookup = 6) const {
+ return const_cast<Value*>(this)->getUnderlyingObject(MaxLookup);
}
/// DoPHITranslation - If this value is a PHI node with CurBB as its parent,
diff --git a/include/llvm/ValueSymbolTable.h b/include/llvm/ValueSymbolTable.h
index 53815ba..7497dae 100644
--- a/include/llvm/ValueSymbolTable.h
+++ b/include/llvm/ValueSymbolTable.h
@@ -17,7 +17,6 @@
#include "llvm/Value.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/System/DataTypes.h"
-#include "llvm/ADT/ilist_node.h"
namespace llvm {
template<typename ValueSubClass, typename ItemParentClass>
@@ -195,9 +194,15 @@ public:
/// @name Mutators
/// @{
public:
- /// insert - The method inserts a new entry into the stringmap.
+ /// insert - The method inserts a new entry into the stringmap. This will
+ /// replace existing entry, if any.
void insert(StringRef Name, NamedMDNode *Node) {
- (void) mmap.GetOrCreateValue(Name, Node);
+ StringMapEntry<NamedMDNode *> &Entry =
+ mmap.GetOrCreateValue(Name, Node);
+ if (Entry.getValue() != Node) {
+ mmap.remove(&Entry);
+ (void) mmap.GetOrCreateValue(Name, Node);
+ }
}
/// This method removes a NamedMDNode from the symbol table.
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 4ae8859..808e6fa 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -80,7 +80,7 @@ static Constant *FoldBitCast(Constant *C, const Type *DestTy,
// First thing is first. We only want to think about integer here, so if
// we have something in FP form, recast it as integer.
- if (DstEltTy->isFloatingPoint()) {
+ if (DstEltTy->isFloatingPointTy()) {
// Fold to an vector of integers with same size as our FP type.
unsigned FPWidth = DstEltTy->getPrimitiveSizeInBits();
const Type *DestIVTy =
@@ -95,7 +95,7 @@ static Constant *FoldBitCast(Constant *C, const Type *DestTy,
// Okay, we know the destination is integer, if the input is FP, convert
// it to integer first.
- if (SrcEltTy->isFloatingPoint()) {
+ if (SrcEltTy->isFloatingPointTy()) {
unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();
const Type *SrcIVTy =
VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumSrcElt);
@@ -517,6 +517,42 @@ static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
return 0;
}
+/// CastGEPIndices - If array indices are not pointer-sized integers,
+/// explicitly cast them so that they aren't implicitly casted by the
+/// getelementptr.
+static Constant *CastGEPIndices(Constant *const *Ops, unsigned NumOps,
+ const Type *ResultTy,
+ const TargetData *TD) {
+ if (!TD) return 0;
+ const Type *IntPtrTy = TD->getIntPtrType(ResultTy->getContext());
+
+ bool Any = false;
+ SmallVector<Constant*, 32> NewIdxs;
+ for (unsigned i = 1; i != NumOps; ++i) {
+ if ((i == 1 ||
+ !isa<StructType>(GetElementPtrInst::getIndexedType(Ops[0]->getType(),
+ reinterpret_cast<Value *const *>(Ops+1),
+ i-1))) &&
+ Ops[i]->getType() != IntPtrTy) {
+ Any = true;
+ NewIdxs.push_back(ConstantExpr::getCast(CastInst::getCastOpcode(Ops[i],
+ true,
+ IntPtrTy,
+ true),
+ Ops[i], IntPtrTy));
+ } else
+ NewIdxs.push_back(Ops[i]);
+ }
+ if (!Any) return 0;
+
+ Constant *C =
+ ConstantExpr::getGetElementPtr(Ops[0], &NewIdxs[0], NewIdxs.size());
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ if (Constant *Folded = ConstantFoldConstantExpression(CE, TD))
+ C = Folded;
+ return C;
+}
+
/// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP
/// constant expression, do so.
static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps,
@@ -676,10 +712,10 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
/// using the specified TargetData. If successful, the constant result is
/// result is returned, if not, null is returned.
-Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE,
+Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE,
const TargetData *TD) {
SmallVector<Constant*, 8> Ops;
- for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i) {
+ for (User::const_op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i) {
Constant *NewC = cast<Constant>(*i);
// Recursively fold the ConstantExpr's operands.
if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(NewC))
@@ -810,6 +846,8 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy,
case Instruction::ShuffleVector:
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
case Instruction::GetElementPtr:
+ if (Constant *C = CastGEPIndices(Ops, NumOps, DestTy, TD))
+ return C;
if (Constant *C = SymbolicallyEvaluateGEP(Ops, NumOps, DestTy, TD))
return C;
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp
index 4ba837a..258f1db 100644
--- a/lib/Analysis/DebugInfo.cpp
+++ b/lib/Analysis/DebugInfo.cpp
@@ -725,6 +725,29 @@ DIBasicType DIFactory::CreateBasicTypeEx(DIDescriptor Context,
return DIBasicType(MDNode::get(VMContext, &Elts[0], 10));
}
+/// CreateArtificialType - Create a new DIType with "artificial" flag set.
+DIType DIFactory::CreateArtificialType(DIType Ty) {
+ if (Ty.isArtificial())
+ return Ty;
+
+ SmallVector<Value *, 9> Elts;
+ MDNode *N = Ty.getNode();
+ assert (N && "Unexpected input DIType!");
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ if (Value *V = N->getOperand(i))
+ Elts.push_back(V);
+ else
+ Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext)));
+ }
+
+ unsigned CurFlags = Ty.getFlags();
+ CurFlags = CurFlags | DIType::FlagArtificial;
+
+ // Flags are stored at this slot.
+ Elts[8] = ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags);
+
+ return DIType(MDNode::get(VMContext, Elts.data(), Elts.size()));
+}
/// CreateDerivedType - Create a derived type like const qualified type,
/// pointer, typedef, etc.
@@ -794,7 +817,8 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
unsigned Flags,
DIType DerivedFrom,
DIArray Elements,
- unsigned RuntimeLang) {
+ unsigned RuntimeLang,
+ MDNode *ContainingType) {
Value *Elts[] = {
GetTagConstant(Tag),
@@ -808,9 +832,10 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
DerivedFrom.getNode(),
Elements.getNode(),
- ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang)
+ ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang),
+ ContainingType
};
- return DICompositeType(MDNode::get(VMContext, &Elts[0], 12));
+ return DICompositeType(MDNode::get(VMContext, &Elts[0], 13));
}
@@ -858,7 +883,8 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
bool isLocalToUnit,
bool isDefinition,
unsigned VK, unsigned VIndex,
- DIType ContainingType) {
+ DIType ContainingType,
+ bool isArtificial) {
Value *Elts[] = {
GetTagConstant(dwarf::DW_TAG_subprogram),
@@ -874,9 +900,10 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition),
ConstantInt::get(Type::getInt32Ty(VMContext), (unsigned)VK),
ConstantInt::get(Type::getInt32Ty(VMContext), VIndex),
- ContainingType.getNode()
+ ContainingType.getNode(),
+ ConstantInt::get(Type::getInt1Ty(VMContext), isArtificial)
};
- return DISubprogram(MDNode::get(VMContext, &Elts[0], 14));
+ return DISubprogram(MDNode::get(VMContext, &Elts[0], 15));
}
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
@@ -900,9 +927,10 @@ DISubprogram DIFactory::CreateSubprogramDefinition(DISubprogram &SPDeclaration)
ConstantInt::get(Type::getInt1Ty(VMContext), true),
DeclNode->getOperand(11), // Virtuality
DeclNode->getOperand(12), // VIndex
- DeclNode->getOperand(13) // Containting Type
+ DeclNode->getOperand(13), // Containting Type
+ DeclNode->getOperand(14) // isArtificial
};
- return DISubprogram(MDNode::get(VMContext, &Elts[0], 14));
+ return DISubprogram(MDNode::get(VMContext, &Elts[0], 15));
}
/// CreateGlobalVariable - Create a new descriptor for the specified global.
@@ -1033,6 +1061,8 @@ DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo,
/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D,
Instruction *InsertBefore) {
+ assert(Storage && "no storage passed to dbg.declare");
+ assert(D.getNode() && "empty DIVariable passed to dbg.declare");
if (!DeclareFn)
DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
@@ -1044,19 +1074,27 @@ Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D,
/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D,
BasicBlock *InsertAtEnd) {
+ assert(Storage && "no storage passed to dbg.declare");
+ assert(D.getNode() && "empty DIVariable passed to dbg.declare");
if (!DeclareFn)
DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
Value *Args[] = { MDNode::get(Storage->getContext(), &Storage, 1),
D.getNode() };
- return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd);
-}
+
+ // If this block already has a terminator then insert this intrinsic
+ // before the terminator.
+ if (TerminatorInst *T = InsertAtEnd->getTerminator())
+ return CallInst::Create(DeclareFn, Args, Args+2, "", T);
+ else
+ return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd);}
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset,
DIVariable D,
Instruction *InsertBefore) {
assert(V && "no value passed to dbg.value");
+ assert(D.getNode() && "empty DIVariable passed to dbg.value");
if (!ValueFn)
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
@@ -1071,6 +1109,7 @@ Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset,
DIVariable D,
BasicBlock *InsertAtEnd) {
assert(V && "no value passed to dbg.value");
+ assert(D.getNode() && "empty DIVariable passed to dbg.value");
if (!ValueFn)
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp
index e803a48..ec94bc8 100644
--- a/lib/Analysis/IPA/GlobalsModRef.cpp
+++ b/lib/Analysis/IPA/GlobalsModRef.cpp
@@ -486,7 +486,7 @@ GlobalsModRef::alias(const Value *V1, unsigned V1Size,
if (GV1 && !NonAddressTakenGlobals.count(GV1)) GV1 = 0;
if (GV2 && !NonAddressTakenGlobals.count(GV2)) GV2 = 0;
- // If the the two pointers are derived from two different non-addr-taken
+ // If the two pointers are derived from two different non-addr-taken
// globals, or if one is and the other isn't, we know these can't alias.
if ((GV1 || GV2) && GV1 != GV2)
return NoAlias;
diff --git a/lib/Analysis/IPA/Makefile b/lib/Analysis/IPA/Makefile
index da719ba..b850c9f 100644
--- a/lib/Analysis/IPA/Makefile
+++ b/lib/Analysis/IPA/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMipa
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp
index 38611cc..4ce6868 100644
--- a/lib/Analysis/IVUsers.cpp
+++ b/lib/Analysis/IVUsers.cpp
@@ -21,6 +21,7 @@
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Assembly/AsmAnnotationWriter.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -35,42 +36,30 @@ Pass *llvm::createIVUsersPass() {
return new IVUsers();
}
-/// containsAddRecFromDifferentLoop - Determine whether expression S involves a
-/// subexpression that is an AddRec from a loop other than L. An outer loop
-/// of L is OK, but not an inner loop nor a disjoint loop.
-static bool containsAddRecFromDifferentLoop(const SCEV *S, Loop *L) {
- // This is very common, put it first.
- if (isa<SCEVConstant>(S))
- return false;
- if (const SCEVCommutativeExpr *AE = dyn_cast<SCEVCommutativeExpr>(S)) {
- for (unsigned int i=0; i< AE->getNumOperands(); i++)
- if (containsAddRecFromDifferentLoop(AE->getOperand(i), L))
- return true;
- return false;
- }
- if (const SCEVAddRecExpr *AE = dyn_cast<SCEVAddRecExpr>(S)) {
- if (const Loop *newLoop = AE->getLoop()) {
- if (newLoop == L)
- return false;
- // if newLoop is an outer loop of L, this is OK.
- if (newLoop->contains(L))
- return false;
+/// CollectSubexprs - Split S into subexpressions which can be pulled out into
+/// separate registers.
+static void CollectSubexprs(const SCEV *S,
+ SmallVectorImpl<const SCEV *> &Ops,
+ ScalarEvolution &SE) {
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+ // Break out add operands.
+ for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
+ I != E; ++I)
+ CollectSubexprs(*I, Ops, SE);
+ return;
+ } else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
+ // Split a non-zero base out of an addrec.
+ if (!AR->getStart()->isZero()) {
+ CollectSubexprs(AR->getStart(), Ops, SE);
+ CollectSubexprs(SE.getAddRecExpr(SE.getIntegerSCEV(0, AR->getType()),
+ AR->getStepRecurrence(SE),
+ AR->getLoop()), Ops, SE);
+ return;
}
- return true;
}
- if (const SCEVUDivExpr *DE = dyn_cast<SCEVUDivExpr>(S))
- return containsAddRecFromDifferentLoop(DE->getLHS(), L) ||
- containsAddRecFromDifferentLoop(DE->getRHS(), L);
-#if 0
- // SCEVSDivExpr has been backed out temporarily, but will be back; we'll
- // need this when it is.
- if (const SCEVSDivExpr *DE = dyn_cast<SCEVSDivExpr>(S))
- return containsAddRecFromDifferentLoop(DE->getLHS(), L) ||
- containsAddRecFromDifferentLoop(DE->getRHS(), L);
-#endif
- if (const SCEVCastExpr *CE = dyn_cast<SCEVCastExpr>(S))
- return containsAddRecFromDifferentLoop(CE->getOperand(), L);
- return false;
+
+ // Otherwise use the value itself.
+ Ops.push_back(S);
}
/// getSCEVStartAndStride - Compute the start and stride of this expression,
@@ -89,35 +78,42 @@ static bool getSCEVStartAndStride(const SCEV *&SH, Loop *L, Loop *UseLoop,
if (const SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(SH)) {
for (unsigned i = 0, e = AE->getNumOperands(); i != e; ++i)
if (const SCEVAddRecExpr *AddRec =
- dyn_cast<SCEVAddRecExpr>(AE->getOperand(i))) {
- if (AddRec->getLoop() == L)
- TheAddRec = SE->getAddExpr(AddRec, TheAddRec);
- else
- return false; // Nested IV of some sort?
- } else {
+ dyn_cast<SCEVAddRecExpr>(AE->getOperand(i)))
+ TheAddRec = SE->getAddExpr(AddRec, TheAddRec);
+ else
Start = SE->getAddExpr(Start, AE->getOperand(i));
- }
} else if (isa<SCEVAddRecExpr>(SH)) {
TheAddRec = SH;
} else {
return false; // not analyzable.
}
- const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(TheAddRec);
- if (!AddRec || AddRec->getLoop() != L) return false;
+ // Break down TheAddRec into its component parts.
+ SmallVector<const SCEV *, 4> Subexprs;
+ CollectSubexprs(TheAddRec, Subexprs, *SE);
+
+ // Look for an addrec on the current loop among the parts.
+ const SCEV *AddRecStride = 0;
+ for (SmallVectorImpl<const SCEV *>::iterator I = Subexprs.begin(),
+ E = Subexprs.end(); I != E; ++I) {
+ const SCEV *S = *I;
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S))
+ if (AR->getLoop() == L) {
+ *I = AR->getStart();
+ AddRecStride = AR->getStepRecurrence(*SE);
+ break;
+ }
+ }
+ if (!AddRecStride)
+ return false;
+
+ // Add up everything else into a start value (which may not be
+ // loop-invariant).
+ const SCEV *AddRecStart = SE->getAddExpr(Subexprs);
// Use getSCEVAtScope to attempt to simplify other loops out of
// the picture.
- const SCEV *AddRecStart = AddRec->getStart();
AddRecStart = SE->getSCEVAtScope(AddRecStart, UseLoop);
- const SCEV *AddRecStride = AddRec->getStepRecurrence(*SE);
-
- // FIXME: If Start contains an SCEVAddRecExpr from a different loop, other
- // than an outer loop of the current loop, reject it. LSR has no concept of
- // operating on more than one loop at a time so don't confuse it with such
- // expressions.
- if (containsAddRecFromDifferentLoop(AddRecStart, L))
- return false;
Start = SE->getAddExpr(Start, AddRecStart);
@@ -130,7 +126,7 @@ static bool getSCEVStartAndStride(const SCEV *&SH, Loop *L, Loop *UseLoop,
DEBUG(dbgs() << "[";
WriteAsOperand(dbgs(), L->getHeader(), /*PrintType=*/false);
- dbgs() << "] Variable stride: " << *AddRec << "\n");
+ dbgs() << "] Variable stride: " << *AddRecStride << "\n");
}
Stride = AddRecStride;
@@ -246,14 +242,6 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
}
if (AddUserToIVUsers) {
- IVUsersOfOneStride *StrideUses = IVUsesByStride[Stride];
- if (!StrideUses) { // First occurrence of this stride?
- StrideOrder.push_back(Stride);
- StrideUses = new IVUsersOfOneStride(Stride);
- IVUses.push_back(StrideUses);
- IVUsesByStride[Stride] = StrideUses;
- }
-
// Okay, we found a user that we cannot reduce. Analyze the instruction
// and decide what to do with it. If we are a use inside of the loop, use
// the value before incrementation, otherwise use it after incrementation.
@@ -261,27 +249,21 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
// The value used will be incremented by the stride more than we are
// expecting, so subtract this off.
const SCEV *NewStart = SE->getMinusSCEV(Start, Stride);
- StrideUses->addUser(NewStart, User, I);
- StrideUses->Users.back().setIsUseOfPostIncrementedValue(true);
+ IVUses.push_back(new IVStrideUse(this, Stride, NewStart, User, I));
+ IVUses.back().setIsUseOfPostIncrementedValue(true);
DEBUG(dbgs() << " USING POSTINC SCEV, START=" << *NewStart<< "\n");
} else {
- StrideUses->addUser(Start, User, I);
+ IVUses.push_back(new IVStrideUse(this, Stride, Start, User, I));
}
}
}
return true;
}
-void IVUsers::AddUser(const SCEV *Stride, const SCEV *Offset,
- Instruction *User, Value *Operand) {
- IVUsersOfOneStride *StrideUses = IVUsesByStride[Stride];
- if (!StrideUses) { // First occurrence of this stride?
- StrideOrder.push_back(Stride);
- StrideUses = new IVUsersOfOneStride(Stride);
- IVUses.push_back(StrideUses);
- IVUsesByStride[Stride] = StrideUses;
- }
- IVUsesByStride[Stride]->addUser(Offset, User, Operand);
+IVStrideUse &IVUsers::AddUser(const SCEV *Stride, const SCEV *Offset,
+ Instruction *User, Value *Operand) {
+ IVUses.push_back(new IVStrideUse(this, Stride, Offset, User, Operand));
+ return IVUses.back();
}
IVUsers::IVUsers()
@@ -315,15 +297,15 @@ bool IVUsers::runOnLoop(Loop *l, LPPassManager &LPM) {
/// value of the OperandValToReplace of the given IVStrideUse.
const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &U) const {
// Start with zero.
- const SCEV *RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType());
+ const SCEV *RetVal = SE->getIntegerSCEV(0, U.getStride()->getType());
// Create the basic add recurrence.
- RetVal = SE->getAddRecExpr(RetVal, U.getParent()->Stride, L);
+ RetVal = SE->getAddRecExpr(RetVal, U.getStride(), L);
// Add the offset in a separate step, because it may be loop-variant.
RetVal = SE->getAddExpr(RetVal, U.getOffset());
// For uses of post-incremented values, add an extra stride to compute
// the actual replacement value.
if (U.isUseOfPostIncrementedValue())
- RetVal = SE->getAddExpr(RetVal, U.getParent()->Stride);
+ RetVal = SE->getAddExpr(RetVal, U.getStride());
return RetVal;
}
@@ -332,9 +314,9 @@ const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &U) const {
/// isUseOfPostIncrementedValue flag.
const SCEV *IVUsers::getCanonicalExpr(const IVStrideUse &U) const {
// Start with zero.
- const SCEV *RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType());
+ const SCEV *RetVal = SE->getIntegerSCEV(0, U.getStride()->getType());
// Create the basic add recurrence.
- RetVal = SE->getAddRecExpr(RetVal, U.getParent()->Stride, L);
+ RetVal = SE->getAddRecExpr(RetVal, U.getStride(), L);
// Add the offset in a separate step, because it may be loop-variant.
RetVal = SE->getAddExpr(RetVal, U.getOffset());
return RetVal;
@@ -349,24 +331,20 @@ void IVUsers::print(raw_ostream &OS, const Module *M) const {
}
OS << ":\n";
- for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e; ++Stride) {
- std::map<const SCEV *, IVUsersOfOneStride*>::const_iterator SI =
- IVUsesByStride.find(StrideOrder[Stride]);
- assert(SI != IVUsesByStride.end() && "Stride doesn't exist!");
- OS << " Stride " << *SI->first->getType() << " " << *SI->first << ":\n";
-
- for (ilist<IVStrideUse>::const_iterator UI = SI->second->Users.begin(),
- E = SI->second->Users.end(); UI != E; ++UI) {
- OS << " ";
- WriteAsOperand(OS, UI->getOperandValToReplace(), false);
- OS << " = ";
- OS << *getReplacementExpr(*UI);
- if (UI->isUseOfPostIncrementedValue())
- OS << " (post-inc)";
- OS << " in ";
- UI->getUser()->print(OS);
- OS << '\n';
- }
+ // Use a defualt AssemblyAnnotationWriter to suppress the default info
+ // comments, which aren't relevant here.
+ AssemblyAnnotationWriter Annotator;
+ for (ilist<IVStrideUse>::const_iterator UI = IVUses.begin(),
+ E = IVUses.end(); UI != E; ++UI) {
+ OS << " ";
+ WriteAsOperand(OS, UI->getOperandValToReplace(), false);
+ OS << " = "
+ << *getReplacementExpr(*UI);
+ if (UI->isUseOfPostIncrementedValue())
+ OS << " (post-inc)";
+ OS << " in ";
+ UI->getUser()->print(OS, &Annotator);
+ OS << '\n';
}
}
@@ -375,14 +353,12 @@ void IVUsers::dump() const {
}
void IVUsers::releaseMemory() {
- IVUsesByStride.clear();
- StrideOrder.clear();
Processed.clear();
IVUses.clear();
}
void IVStrideUse::deleted() {
// Remove this user from the list.
- Parent->Users.erase(this);
+ Parent->IVUses.erase(this);
// this now dangles!
}
diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp
index 651c918..972d034 100644
--- a/lib/Analysis/InlineCost.cpp
+++ b/lib/Analysis/InlineCost.cpp
@@ -25,26 +25,28 @@ unsigned InlineCostAnalyzer::FunctionInfo::
CountCodeReductionForConstant(Value *V) {
unsigned Reduction = 0;
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
- if (isa<BranchInst>(*UI))
- Reduction += 40; // Eliminating a conditional branch is a big win
- else if (SwitchInst *SI = dyn_cast<SwitchInst>(*UI))
- // Eliminating a switch is a big win, proportional to the number of edges
- // deleted.
- Reduction += (SI->getNumSuccessors()-1) * 40;
- else if (isa<IndirectBrInst>(*UI))
- // Eliminating an indirect branch is a big win.
- Reduction += 200;
- else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
+ if (isa<BranchInst>(*UI) || isa<SwitchInst>(*UI)) {
+ // We will be able to eliminate all but one of the successors.
+ const TerminatorInst &TI = cast<TerminatorInst>(**UI);
+ const unsigned NumSucc = TI.getNumSuccessors();
+ unsigned Instrs = 0;
+ for (unsigned I = 0; I != NumSucc; ++I)
+ Instrs += TI.getSuccessor(I)->size();
+ // We don't know which blocks will be eliminated, so use the average size.
+ Reduction += InlineConstants::InstrCost*Instrs*(NumSucc-1)/NumSucc;
+ } else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
// Turning an indirect call into a direct call is a BIG win
- Reduction += CI->getCalledValue() == V ? 500 : 0;
+ if (CI->getCalledValue() == V)
+ Reduction += InlineConstants::IndirectCallBonus;
} else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) {
// Turning an indirect call into a direct call is a BIG win
- Reduction += II->getCalledValue() == V ? 500 : 0;
+ if (II->getCalledValue() == V)
+ Reduction += InlineConstants::IndirectCallBonus;
} else {
// Figure out if this instruction will be removed due to simple constant
// propagation.
Instruction &Inst = cast<Instruction>(**UI);
-
+
// We can't constant propagate instructions which have effects or
// read memory.
//
@@ -53,7 +55,7 @@ unsigned InlineCostAnalyzer::FunctionInfo::
// Unfortunately, we don't know the pointer that may get propagated here,
// so we can't make this decision.
if (Inst.mayReadFromMemory() || Inst.mayHaveSideEffects() ||
- isa<AllocaInst>(Inst))
+ isa<AllocaInst>(Inst))
continue;
bool AllOperandsConstant = true;
@@ -65,7 +67,7 @@ unsigned InlineCostAnalyzer::FunctionInfo::
if (AllOperandsConstant) {
// We will get to remove this instruction...
- Reduction += 7;
+ Reduction += InlineConstants::InstrCost;
// And any other instructions that use it which become constants
// themselves.
@@ -87,11 +89,14 @@ unsigned InlineCostAnalyzer::FunctionInfo::
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){
Instruction *I = cast<Instruction>(*UI);
if (isa<LoadInst>(I) || isa<StoreInst>(I))
- Reduction += 10;
+ Reduction += InlineConstants::InstrCost;
else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I)) {
// If the GEP has variable indices, we won't be able to do much with it.
- if (!GEP->hasAllConstantIndices())
- Reduction += CountCodeReductionForAlloca(GEP)+15;
+ if (GEP->hasAllConstantIndices())
+ Reduction += CountCodeReductionForAlloca(GEP);
+ } else if (BitCastInst *BCI = dyn_cast<BitCastInst>(I)) {
+ // Track pointer through bitcasts.
+ Reduction += CountCodeReductionForAlloca(BCI);
} else {
// If there is some other strange instruction, we're not going to be able
// to do much if we inline this.
@@ -158,10 +163,11 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) {
(F->getName() == "setjmp" || F->getName() == "_setjmp"))
NeverInline = true;
- // Calls often compile into many machine instructions. Bump up their
- // cost to reflect this.
- if (!isa<IntrinsicInst>(II) && !callIsSmall(CS.getCalledFunction()))
- NumInsts += InlineConstants::CallPenalty;
+ if (!isa<IntrinsicInst>(II) && !callIsSmall(CS.getCalledFunction())) {
+ // Each argument to a call takes on average one instruction to set up.
+ NumInsts += CS.arg_size();
+ ++NumCalls;
+ }
}
if (const AllocaInst *AI = dyn_cast<AllocaInst>(II)) {
@@ -223,8 +229,14 @@ void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) {
if (Metrics.NumRets==1)
--Metrics.NumInsts;
+ // Don't bother calculating argument weights if we are never going to inline
+ // the function anyway.
+ if (Metrics.NeverInline)
+ return;
+
// Check out all of the arguments to the function, figuring out how much
// code can be eliminated if one of the arguments is a constant.
+ ArgumentWeights.reserve(F->arg_size());
for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
ArgumentWeights.push_back(ArgInfo(CountCodeReductionForConstant(I),
CountCodeReductionForAlloca(I)));
@@ -313,23 +325,18 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
I != E; ++I, ++ArgNo) {
// Each argument passed in has a cost at both the caller and the callee
- // sides. This favors functions that take many arguments over functions
- // that take few arguments.
- InlineCost -= 20;
-
- // If this is a function being passed in, it is very likely that we will be
- // able to turn an indirect function call into a direct function call.
- if (isa<Function>(I))
- InlineCost -= 100;
-
+ // sides. Measurements show that each argument costs about the same as an
+ // instruction.
+ InlineCost -= InlineConstants::InstrCost;
+
// If an alloca is passed in, inlining this function is likely to allow
// significant future optimization possibilities (like scalar promotion, and
// scalarization), so encourage the inlining of the function.
//
- else if (isa<AllocaInst>(I)) {
+ if (isa<AllocaInst>(I)) {
if (ArgNo < CalleeFI.ArgumentWeights.size())
InlineCost -= CalleeFI.ArgumentWeights[ArgNo].AllocaWeight;
-
+
// If this is a constant being passed into the function, use the argument
// weights calculated for the callee to determine how much will be folded
// away with this information.
@@ -341,14 +348,17 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
// Now that we have considered all of the factors that make the call site more
// likely to be inlined, look at factors that make us not want to inline it.
-
+
+ // Calls usually take a long time, so they make the inlining gain smaller.
+ InlineCost += CalleeFI.Metrics.NumCalls * InlineConstants::CallPenalty;
+
// Don't inline into something too big, which would make it bigger.
// "size" here is the number of basic blocks, not instructions.
//
InlineCost += Caller->size()/15;
// Look at the size of the callee. Each instruction counts as 5.
- InlineCost += CalleeFI.Metrics.NumInsts*5;
+ InlineCost += CalleeFI.Metrics.NumInsts*InlineConstants::InstrCost;
return llvm::InlineCost::get(InlineCost);
}
diff --git a/lib/Analysis/LiveValues.cpp b/lib/Analysis/LiveValues.cpp
index 02ec7d3..1b91d93 100644
--- a/lib/Analysis/LiveValues.cpp
+++ b/lib/Analysis/LiveValues.cpp
@@ -184,7 +184,7 @@ LiveValues::Memo &LiveValues::compute(const Value *V) {
}
}
- // If the value was never used outside the the block in which it was
+ // If the value was never used outside the block in which it was
// defined, it's killed in that block.
if (!LiveOutOfDefBB)
M.Killed.insert(DefBB);
diff --git a/lib/Analysis/Makefile b/lib/Analysis/Makefile
index f61b8aa..4af6d35 100644
--- a/lib/Analysis/Makefile
+++ b/lib/Analysis/Makefile
@@ -11,7 +11,6 @@ LEVEL = ../..
LIBRARYNAME = LLVMAnalysis
DIRS = IPA
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Analysis/MemoryBuiltins.cpp b/lib/Analysis/MemoryBuiltins.cpp
index b448628..297b588 100644
--- a/lib/Analysis/MemoryBuiltins.cpp
+++ b/lib/Analysis/MemoryBuiltins.cpp
@@ -24,7 +24,7 @@ using namespace llvm;
// malloc Call Utility Functions.
//
-/// isMalloc - Returns true if the the value is either a malloc call or a
+/// isMalloc - Returns true if the value is either a malloc call or a
/// bitcast of the result of a malloc call.
bool llvm::isMalloc(const Value *I) {
return extractMallocCall(I) || extractMallocCallFromBitCast(I);
@@ -183,7 +183,7 @@ Value *llvm::getMallocArraySize(CallInst *CI, const TargetData *TD,
// free Call Utility Functions.
//
-/// isFreeCall - Returns true if the the value is a call to the builtin free()
+/// isFreeCall - Returns true if the value is a call to the builtin free()
bool llvm::isFreeCall(const Value *I) {
const CallInst *CI = dyn_cast<CallInst>(I);
if (!CI)
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 2f44913..9ee7d3a 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -214,8 +214,8 @@ bool SCEVCastExpr::properlyDominates(BasicBlock *BB, DominatorTree *DT) const {
SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeID &ID,
const SCEV *op, const Type *ty)
: SCEVCastExpr(ID, scTruncate, op, ty) {
- assert((Op->getType()->isInteger() || isa<PointerType>(Op->getType())) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((Op->getType()->isIntegerTy() || isa<PointerType>(Op->getType())) &&
+ (Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Cannot truncate non-integer value!");
}
@@ -226,8 +226,8 @@ void SCEVTruncateExpr::print(raw_ostream &OS) const {
SCEVZeroExtendExpr::SCEVZeroExtendExpr(const FoldingSetNodeID &ID,
const SCEV *op, const Type *ty)
: SCEVCastExpr(ID, scZeroExtend, op, ty) {
- assert((Op->getType()->isInteger() || isa<PointerType>(Op->getType())) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((Op->getType()->isIntegerTy() || isa<PointerType>(Op->getType())) &&
+ (Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Cannot zero extend non-integer value!");
}
@@ -238,8 +238,8 @@ void SCEVZeroExtendExpr::print(raw_ostream &OS) const {
SCEVSignExtendExpr::SCEVSignExtendExpr(const FoldingSetNodeID &ID,
const SCEV *op, const Type *ty)
: SCEVCastExpr(ID, scSignExtend, op, ty) {
- assert((Op->getType()->isInteger() || isa<PointerType>(Op->getType())) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((Op->getType()->isIntegerTy() || isa<PointerType>(Op->getType())) &&
+ (Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Cannot sign extend non-integer value!");
}
@@ -312,6 +312,21 @@ bool SCEVAddRecExpr::isLoopInvariant(const Loop *QueryLoop) const {
return true;
}
+bool
+SCEVAddRecExpr::dominates(BasicBlock *BB, DominatorTree *DT) const {
+ return DT->dominates(L->getHeader(), BB) &&
+ SCEVNAryExpr::dominates(BB, DT);
+}
+
+bool
+SCEVAddRecExpr::properlyDominates(BasicBlock *BB, DominatorTree *DT) const {
+ // This uses a "dominates" query instead of "properly dominates" query because
+ // the instruction which produces the addrec's value is a PHI, and a PHI
+ // effectively properly dominates its entire containing block.
+ return DT->dominates(L->getHeader(), BB) &&
+ SCEVNAryExpr::properlyDominates(BB, DT);
+}
+
void SCEVAddRecExpr::print(raw_ostream &OS) const {
OS << "{" << *Operands[0];
for (unsigned i = 1, e = Operands.size(); i != e; ++i)
@@ -321,15 +336,6 @@ void SCEVAddRecExpr::print(raw_ostream &OS) const {
OS << ">";
}
-void SCEVFieldOffsetExpr::print(raw_ostream &OS) const {
- // LLVM struct fields don't have names, so just print the field number.
- OS << "offsetof(" << *STy << ", " << FieldNo << ")";
-}
-
-void SCEVAllocSizeExpr::print(raw_ostream &OS) const {
- OS << "sizeof(" << *AllocTy << ")";
-}
-
bool SCEVUnknown::isLoopInvariant(const Loop *L) const {
// All non-instruction values are loop invariant. All instructions are loop
// invariant if they are not contained in the specified loop.
@@ -356,7 +362,91 @@ const Type *SCEVUnknown::getType() const {
return V->getType();
}
+bool SCEVUnknown::isSizeOf(const Type *&AllocTy) const {
+ if (ConstantExpr *VCE = dyn_cast<ConstantExpr>(V))
+ if (VCE->getOpcode() == Instruction::PtrToInt)
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(VCE->getOperand(0)))
+ if (CE->getOpcode() == Instruction::GetElementPtr &&
+ CE->getOperand(0)->isNullValue() &&
+ CE->getNumOperands() == 2)
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(1)))
+ if (CI->isOne()) {
+ AllocTy = cast<PointerType>(CE->getOperand(0)->getType())
+ ->getElementType();
+ return true;
+ }
+
+ return false;
+}
+
+bool SCEVUnknown::isAlignOf(const Type *&AllocTy) const {
+ if (ConstantExpr *VCE = dyn_cast<ConstantExpr>(V))
+ if (VCE->getOpcode() == Instruction::PtrToInt)
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(VCE->getOperand(0)))
+ if (CE->getOpcode() == Instruction::GetElementPtr &&
+ CE->getOperand(0)->isNullValue()) {
+ const Type *Ty =
+ cast<PointerType>(CE->getOperand(0)->getType())->getElementType();
+ if (const StructType *STy = dyn_cast<StructType>(Ty))
+ if (!STy->isPacked() &&
+ CE->getNumOperands() == 3 &&
+ CE->getOperand(1)->isNullValue()) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(2)))
+ if (CI->isOne() &&
+ STy->getNumElements() == 2 &&
+ STy->getElementType(0)->isIntegerTy(1)) {
+ AllocTy = STy->getElementType(1);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool SCEVUnknown::isOffsetOf(const Type *&CTy, Constant *&FieldNo) const {
+ if (ConstantExpr *VCE = dyn_cast<ConstantExpr>(V))
+ if (VCE->getOpcode() == Instruction::PtrToInt)
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(VCE->getOperand(0)))
+ if (CE->getOpcode() == Instruction::GetElementPtr &&
+ CE->getNumOperands() == 3 &&
+ CE->getOperand(0)->isNullValue() &&
+ CE->getOperand(1)->isNullValue()) {
+ const Type *Ty =
+ cast<PointerType>(CE->getOperand(0)->getType())->getElementType();
+ // Ignore vector types here so that ScalarEvolutionExpander doesn't
+ // emit getelementptrs that index into vectors.
+ if (isa<StructType>(Ty) || isa<ArrayType>(Ty)) {
+ CTy = Ty;
+ FieldNo = CE->getOperand(2);
+ return true;
+ }
+ }
+
+ return false;
+}
+
void SCEVUnknown::print(raw_ostream &OS) const {
+ const Type *AllocTy;
+ if (isSizeOf(AllocTy)) {
+ OS << "sizeof(" << *AllocTy << ")";
+ return;
+ }
+ if (isAlignOf(AllocTy)) {
+ OS << "alignof(" << *AllocTy << ")";
+ return;
+ }
+
+ const Type *CTy;
+ Constant *FieldNo;
+ if (isOffsetOf(CTy, FieldNo)) {
+ OS << "offsetof(" << *CTy << ", ";
+ WriteAsOperand(OS, FieldNo, false);
+ OS << ")";
+ return;
+ }
+
+ // Otherwise just print it normally.
WriteAsOperand(OS, V, false);
}
@@ -515,21 +605,6 @@ namespace {
return operator()(LC->getOperand(), RC->getOperand());
}
- // Compare offsetof expressions.
- if (const SCEVFieldOffsetExpr *LA = dyn_cast<SCEVFieldOffsetExpr>(LHS)) {
- const SCEVFieldOffsetExpr *RA = cast<SCEVFieldOffsetExpr>(RHS);
- if (CompareTypes(LA->getStructType(), RA->getStructType()) ||
- CompareTypes(RA->getStructType(), LA->getStructType()))
- return CompareTypes(LA->getStructType(), RA->getStructType());
- return LA->getFieldNo() < RA->getFieldNo();
- }
-
- // Compare sizeof expressions by the allocation type.
- if (const SCEVAllocSizeExpr *LA = dyn_cast<SCEVAllocSizeExpr>(LHS)) {
- const SCEVAllocSizeExpr *RA = cast<SCEVAllocSizeExpr>(RHS);
- return CompareTypes(LA->getAllocType(), RA->getAllocType());
- }
-
llvm_unreachable("Unknown SCEV kind!");
return false;
}
@@ -2172,74 +2247,38 @@ const SCEV *ScalarEvolution::getUMinExpr(const SCEV *LHS,
return getNotSCEV(getUMaxExpr(getNotSCEV(LHS), getNotSCEV(RHS)));
}
-const SCEV *ScalarEvolution::getFieldOffsetExpr(const StructType *STy,
- unsigned FieldNo) {
- // If we have TargetData we can determine the constant offset.
- if (TD) {
- const Type *IntPtrTy = TD->getIntPtrType(getContext());
- const StructLayout &SL = *TD->getStructLayout(STy);
- uint64_t Offset = SL.getElementOffset(FieldNo);
- return getIntegerSCEV(Offset, IntPtrTy);
- }
+const SCEV *ScalarEvolution::getSizeOfExpr(const Type *AllocTy) {
+ Constant *C = ConstantExpr::getSizeOf(AllocTy);
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ C = ConstantFoldConstantExpression(CE, TD);
+ const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(AllocTy));
+ return getTruncateOrZeroExtend(getSCEV(C), Ty);
+}
- // Field 0 is always at offset 0.
- if (FieldNo == 0) {
- const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(STy));
- return getIntegerSCEV(0, Ty);
- }
+const SCEV *ScalarEvolution::getAlignOfExpr(const Type *AllocTy) {
+ Constant *C = ConstantExpr::getAlignOf(AllocTy);
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ C = ConstantFoldConstantExpression(CE, TD);
+ const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(AllocTy));
+ return getTruncateOrZeroExtend(getSCEV(C), Ty);
+}
- // Okay, it looks like we really DO need an offsetof expr. Check to see if we
- // already have one, otherwise create a new one.
- FoldingSetNodeID ID;
- ID.AddInteger(scFieldOffset);
- ID.AddPointer(STy);
- ID.AddInteger(FieldNo);
- void *IP = 0;
- if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
- SCEV *S = SCEVAllocator.Allocate<SCEVFieldOffsetExpr>();
+const SCEV *ScalarEvolution::getOffsetOfExpr(const StructType *STy,
+ unsigned FieldNo) {
+ Constant *C = ConstantExpr::getOffsetOf(STy, FieldNo);
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ C = ConstantFoldConstantExpression(CE, TD);
const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(STy));
- new (S) SCEVFieldOffsetExpr(ID, Ty, STy, FieldNo);
- UniqueSCEVs.InsertNode(S, IP);
- return S;
+ return getTruncateOrZeroExtend(getSCEV(C), Ty);
}
-const SCEV *ScalarEvolution::getAllocSizeExpr(const Type *AllocTy) {
- // If we have TargetData we can determine the constant size.
- if (TD && AllocTy->isSized()) {
- const Type *IntPtrTy = TD->getIntPtrType(getContext());
- return getIntegerSCEV(TD->getTypeAllocSize(AllocTy), IntPtrTy);
- }
-
- // Expand an array size into the element size times the number
- // of elements.
- if (const ArrayType *ATy = dyn_cast<ArrayType>(AllocTy)) {
- const SCEV *E = getAllocSizeExpr(ATy->getElementType());
- return getMulExpr(
- E, getConstant(ConstantInt::get(cast<IntegerType>(E->getType()),
- ATy->getNumElements())));
- }
-
- // Expand a vector size into the element size times the number
- // of elements.
- if (const VectorType *VTy = dyn_cast<VectorType>(AllocTy)) {
- const SCEV *E = getAllocSizeExpr(VTy->getElementType());
- return getMulExpr(
- E, getConstant(ConstantInt::get(cast<IntegerType>(E->getType()),
- VTy->getNumElements())));
- }
-
- // Okay, it looks like we really DO need a sizeof expr. Check to see if we
- // already have one, otherwise create a new one.
- FoldingSetNodeID ID;
- ID.AddInteger(scAllocSize);
- ID.AddPointer(AllocTy);
- void *IP = 0;
- if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
- SCEV *S = SCEVAllocator.Allocate<SCEVAllocSizeExpr>();
- const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(AllocTy));
- new (S) SCEVAllocSizeExpr(ID, Ty, AllocTy);
- UniqueSCEVs.InsertNode(S, IP);
- return S;
+const SCEV *ScalarEvolution::getOffsetOfExpr(const Type *CTy,
+ Constant *FieldNo) {
+ Constant *C = ConstantExpr::getOffsetOf(CTy, FieldNo);
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ C = ConstantFoldConstantExpression(CE, TD);
+ const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(CTy));
+ return getTruncateOrZeroExtend(getSCEV(C), Ty);
}
const SCEV *ScalarEvolution::getUnknown(Value *V) {
@@ -2269,7 +2308,7 @@ const SCEV *ScalarEvolution::getUnknown(Value *V) {
/// has access to target-specific information.
bool ScalarEvolution::isSCEVable(const Type *Ty) const {
// Integers and pointers are always SCEVable.
- return Ty->isInteger() || isa<PointerType>(Ty);
+ return Ty->isIntegerTy() || isa<PointerType>(Ty);
}
/// getTypeSizeInBits - Return the size in bits of the specified type,
@@ -2282,7 +2321,7 @@ uint64_t ScalarEvolution::getTypeSizeInBits(const Type *Ty) const {
return TD->getTypeSizeInBits(Ty);
// Integer types have fixed sizes.
- if (Ty->isInteger())
+ if (Ty->isIntegerTy())
return Ty->getPrimitiveSizeInBits();
// The only other support type is pointer. Without TargetData, conservatively
@@ -2298,7 +2337,7 @@ uint64_t ScalarEvolution::getTypeSizeInBits(const Type *Ty) const {
const Type *ScalarEvolution::getEffectiveSCEVType(const Type *Ty) const {
assert(isSCEVable(Ty) && "Type is not SCEVable!");
- if (Ty->isInteger())
+ if (Ty->isIntegerTy())
return Ty;
// The only other support type is pointer.
@@ -2327,7 +2366,7 @@ const SCEV *ScalarEvolution::getSCEV(Value *V) {
/// getIntegerSCEV - Given a SCEVable type, create a constant for the
/// specified signed integer value and return a SCEV for the constant.
-const SCEV *ScalarEvolution::getIntegerSCEV(int Val, const Type *Ty) {
+const SCEV *ScalarEvolution::getIntegerSCEV(int64_t Val, const Type *Ty) {
const IntegerType *ITy = cast<IntegerType>(getEffectiveSCEVType(Ty));
return getConstant(ConstantInt::get(ITy, Val));
}
@@ -2373,8 +2412,8 @@ const SCEV *
ScalarEvolution::getTruncateOrZeroExtend(const SCEV *V,
const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || isa<PointerType>(SrcTy)) &&
+ (Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Cannot truncate or zero extend with non-integer arguments!");
if (getTypeSizeInBits(SrcTy) == getTypeSizeInBits(Ty))
return V; // No conversion
@@ -2390,8 +2429,8 @@ const SCEV *
ScalarEvolution::getTruncateOrSignExtend(const SCEV *V,
const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || isa<PointerType>(SrcTy)) &&
+ (Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Cannot truncate or zero extend with non-integer arguments!");
if (getTypeSizeInBits(SrcTy) == getTypeSizeInBits(Ty))
return V; // No conversion
@@ -2406,8 +2445,8 @@ ScalarEvolution::getTruncateOrSignExtend(const SCEV *V,
const SCEV *
ScalarEvolution::getNoopOrZeroExtend(const SCEV *V, const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || isa<PointerType>(SrcTy)) &&
+ (Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Cannot noop or zero extend with non-integer arguments!");
assert(getTypeSizeInBits(SrcTy) <= getTypeSizeInBits(Ty) &&
"getNoopOrZeroExtend cannot truncate!");
@@ -2422,8 +2461,8 @@ ScalarEvolution::getNoopOrZeroExtend(const SCEV *V, const Type *Ty) {
const SCEV *
ScalarEvolution::getNoopOrSignExtend(const SCEV *V, const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || isa<PointerType>(SrcTy)) &&
+ (Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Cannot noop or sign extend with non-integer arguments!");
assert(getTypeSizeInBits(SrcTy) <= getTypeSizeInBits(Ty) &&
"getNoopOrSignExtend cannot truncate!");
@@ -2439,8 +2478,8 @@ ScalarEvolution::getNoopOrSignExtend(const SCEV *V, const Type *Ty) {
const SCEV *
ScalarEvolution::getNoopOrAnyExtend(const SCEV *V, const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || isa<PointerType>(SrcTy)) &&
+ (Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Cannot noop or any extend with non-integer arguments!");
assert(getTypeSizeInBits(SrcTy) <= getTypeSizeInBits(Ty) &&
"getNoopOrAnyExtend cannot truncate!");
@@ -2454,8 +2493,8 @@ ScalarEvolution::getNoopOrAnyExtend(const SCEV *V, const Type *Ty) {
const SCEV *
ScalarEvolution::getTruncateOrNoop(const SCEV *V, const Type *Ty) {
const Type *SrcTy = V->getType();
- assert((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
- (Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((SrcTy->isIntegerTy() || isa<PointerType>(SrcTy)) &&
+ (Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Cannot truncate or noop with non-integer arguments!");
assert(getTypeSizeInBits(SrcTy) >= getTypeSizeInBits(Ty) &&
"getTruncateOrNoop cannot extend!");
@@ -2527,7 +2566,7 @@ ScalarEvolution::ForgetSymbolicName(Instruction *I, const SCEV *SymName) {
if (It != Scalars.end()) {
// Short-circuit the def-use traversal if the symbolic name
// ceases to appear in expressions.
- if (!It->second->hasOperand(SymName))
+ if (It->second != SymName && !It->second->hasOperand(SymName))
continue;
// SCEVUnknown for a PHI either means that it has an unrecognized
@@ -2689,16 +2728,15 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
// For a struct, add the member offset.
unsigned FieldNo = cast<ConstantInt>(Index)->getZExtValue();
TotalOffset = getAddExpr(TotalOffset,
- getFieldOffsetExpr(STy, FieldNo),
+ getOffsetOfExpr(STy, FieldNo),
/*HasNUW=*/false, /*HasNSW=*/InBounds);
} else {
// For an array, add the element offset, explicitly scaled.
const SCEV *LocalOffset = getSCEV(Index);
- if (!isa<PointerType>(LocalOffset->getType()))
- // Getelementptr indicies are signed.
- LocalOffset = getTruncateOrSignExtend(LocalOffset, IntPtrTy);
+ // Getelementptr indicies are signed.
+ LocalOffset = getTruncateOrSignExtend(LocalOffset, IntPtrTy);
// Lower "inbounds" GEPs to NSW arithmetic.
- LocalOffset = getMulExpr(LocalOffset, getAllocSizeExpr(*GTI),
+ LocalOffset = getMulExpr(LocalOffset, getSizeOfExpr(*GTI),
/*HasNUW=*/false, /*HasNSW=*/InBounds);
TotalOffset = getAddExpr(TotalOffset, LocalOffset,
/*HasNUW=*/false, /*HasNSW=*/InBounds);
@@ -2797,62 +2835,67 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) {
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S))
return ConstantRange(C->getValue()->getValue());
+ unsigned BitWidth = getTypeSizeInBits(S->getType());
+ ConstantRange ConservativeResult(BitWidth, /*isFullSet=*/true);
+
+ // If the value has known zeros, the maximum unsigned value will have those
+ // known zeros as well.
+ uint32_t TZ = GetMinTrailingZeros(S);
+ if (TZ != 0)
+ ConservativeResult =
+ ConstantRange(APInt::getMinValue(BitWidth),
+ APInt::getMaxValue(BitWidth).lshr(TZ).shl(TZ) + 1);
+
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
ConstantRange X = getUnsignedRange(Add->getOperand(0));
for (unsigned i = 1, e = Add->getNumOperands(); i != e; ++i)
X = X.add(getUnsignedRange(Add->getOperand(i)));
- return X;
+ return ConservativeResult.intersectWith(X);
}
if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {
ConstantRange X = getUnsignedRange(Mul->getOperand(0));
for (unsigned i = 1, e = Mul->getNumOperands(); i != e; ++i)
X = X.multiply(getUnsignedRange(Mul->getOperand(i)));
- return X;
+ return ConservativeResult.intersectWith(X);
}
if (const SCEVSMaxExpr *SMax = dyn_cast<SCEVSMaxExpr>(S)) {
ConstantRange X = getUnsignedRange(SMax->getOperand(0));
for (unsigned i = 1, e = SMax->getNumOperands(); i != e; ++i)
X = X.smax(getUnsignedRange(SMax->getOperand(i)));
- return X;
+ return ConservativeResult.intersectWith(X);
}
if (const SCEVUMaxExpr *UMax = dyn_cast<SCEVUMaxExpr>(S)) {
ConstantRange X = getUnsignedRange(UMax->getOperand(0));
for (unsigned i = 1, e = UMax->getNumOperands(); i != e; ++i)
X = X.umax(getUnsignedRange(UMax->getOperand(i)));
- return X;
+ return ConservativeResult.intersectWith(X);
}
if (const SCEVUDivExpr *UDiv = dyn_cast<SCEVUDivExpr>(S)) {
ConstantRange X = getUnsignedRange(UDiv->getLHS());
ConstantRange Y = getUnsignedRange(UDiv->getRHS());
- return X.udiv(Y);
+ return ConservativeResult.intersectWith(X.udiv(Y));
}
if (const SCEVZeroExtendExpr *ZExt = dyn_cast<SCEVZeroExtendExpr>(S)) {
ConstantRange X = getUnsignedRange(ZExt->getOperand());
- return X.zeroExtend(cast<IntegerType>(ZExt->getType())->getBitWidth());
+ return ConservativeResult.intersectWith(X.zeroExtend(BitWidth));
}
if (const SCEVSignExtendExpr *SExt = dyn_cast<SCEVSignExtendExpr>(S)) {
ConstantRange X = getUnsignedRange(SExt->getOperand());
- return X.signExtend(cast<IntegerType>(SExt->getType())->getBitWidth());
+ return ConservativeResult.intersectWith(X.signExtend(BitWidth));
}
if (const SCEVTruncateExpr *Trunc = dyn_cast<SCEVTruncateExpr>(S)) {
ConstantRange X = getUnsignedRange(Trunc->getOperand());
- return X.truncate(cast<IntegerType>(Trunc->getType())->getBitWidth());
+ return ConservativeResult.intersectWith(X.truncate(BitWidth));
}
- ConstantRange FullSet(getTypeSizeInBits(S->getType()), true);
-
if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
- const SCEV *T = getBackedgeTakenCount(AddRec->getLoop());
- const SCEVConstant *Trip = dyn_cast<SCEVConstant>(T);
- ConstantRange ConservativeResult = FullSet;
-
// If there's no unsigned wrap, the value will never be less than its
// initial value.
if (AddRec->hasNoUnsignedWrap())
@@ -2862,10 +2905,11 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) {
APInt(getTypeSizeInBits(C->getType()), 0));
// TODO: non-affine addrec
- if (Trip && AddRec->isAffine()) {
+ if (AddRec->isAffine()) {
const Type *Ty = AddRec->getType();
const SCEV *MaxBECount = getMaxBackedgeTakenCount(AddRec->getLoop());
- if (getTypeSizeInBits(MaxBECount->getType()) <= getTypeSizeInBits(Ty)) {
+ if (!isa<SCEVCouldNotCompute>(MaxBECount) &&
+ getTypeSizeInBits(MaxBECount->getType()) <= BitWidth) {
MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty);
const SCEV *Start = AddRec->getStart();
@@ -2883,7 +2927,7 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) {
EndRange.getUnsignedMax());
if (Min.isMinValue() && Max.isMaxValue())
return ConservativeResult;
- return ConstantRange(Min, Max+1);
+ return ConservativeResult.intersectWith(ConstantRange(Min, Max+1));
}
}
@@ -2897,11 +2941,11 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) {
APInt Zeros(BitWidth, 0), Ones(BitWidth, 0);
ComputeMaskedBits(U->getValue(), Mask, Zeros, Ones, TD);
if (Ones == ~Zeros + 1)
- return FullSet;
- return ConstantRange(Ones, ~Zeros + 1);
+ return ConservativeResult;
+ return ConservativeResult.intersectWith(ConstantRange(Ones, ~Zeros + 1));
}
- return FullSet;
+ return ConservativeResult;
}
/// getSignedRange - Determine the signed range for a particular SCEV.
@@ -2912,62 +2956,67 @@ ScalarEvolution::getSignedRange(const SCEV *S) {
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S))
return ConstantRange(C->getValue()->getValue());
+ unsigned BitWidth = getTypeSizeInBits(S->getType());
+ ConstantRange ConservativeResult(BitWidth, /*isFullSet=*/true);
+
+ // If the value has known zeros, the maximum signed value will have those
+ // known zeros as well.
+ uint32_t TZ = GetMinTrailingZeros(S);
+ if (TZ != 0)
+ ConservativeResult =
+ ConstantRange(APInt::getSignedMinValue(BitWidth),
+ APInt::getSignedMaxValue(BitWidth).ashr(TZ).shl(TZ) + 1);
+
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
ConstantRange X = getSignedRange(Add->getOperand(0));
for (unsigned i = 1, e = Add->getNumOperands(); i != e; ++i)
X = X.add(getSignedRange(Add->getOperand(i)));
- return X;
+ return ConservativeResult.intersectWith(X);
}
if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {
ConstantRange X = getSignedRange(Mul->getOperand(0));
for (unsigned i = 1, e = Mul->getNumOperands(); i != e; ++i)
X = X.multiply(getSignedRange(Mul->getOperand(i)));
- return X;
+ return ConservativeResult.intersectWith(X);
}
if (const SCEVSMaxExpr *SMax = dyn_cast<SCEVSMaxExpr>(S)) {
ConstantRange X = getSignedRange(SMax->getOperand(0));
for (unsigned i = 1, e = SMax->getNumOperands(); i != e; ++i)
X = X.smax(getSignedRange(SMax->getOperand(i)));
- return X;
+ return ConservativeResult.intersectWith(X);
}
if (const SCEVUMaxExpr *UMax = dyn_cast<SCEVUMaxExpr>(S)) {
ConstantRange X = getSignedRange(UMax->getOperand(0));
for (unsigned i = 1, e = UMax->getNumOperands(); i != e; ++i)
X = X.umax(getSignedRange(UMax->getOperand(i)));
- return X;
+ return ConservativeResult.intersectWith(X);
}
if (const SCEVUDivExpr *UDiv = dyn_cast<SCEVUDivExpr>(S)) {
ConstantRange X = getSignedRange(UDiv->getLHS());
ConstantRange Y = getSignedRange(UDiv->getRHS());
- return X.udiv(Y);
+ return ConservativeResult.intersectWith(X.udiv(Y));
}
if (const SCEVZeroExtendExpr *ZExt = dyn_cast<SCEVZeroExtendExpr>(S)) {
ConstantRange X = getSignedRange(ZExt->getOperand());
- return X.zeroExtend(cast<IntegerType>(ZExt->getType())->getBitWidth());
+ return ConservativeResult.intersectWith(X.zeroExtend(BitWidth));
}
if (const SCEVSignExtendExpr *SExt = dyn_cast<SCEVSignExtendExpr>(S)) {
ConstantRange X = getSignedRange(SExt->getOperand());
- return X.signExtend(cast<IntegerType>(SExt->getType())->getBitWidth());
+ return ConservativeResult.intersectWith(X.signExtend(BitWidth));
}
if (const SCEVTruncateExpr *Trunc = dyn_cast<SCEVTruncateExpr>(S)) {
ConstantRange X = getSignedRange(Trunc->getOperand());
- return X.truncate(cast<IntegerType>(Trunc->getType())->getBitWidth());
+ return ConservativeResult.intersectWith(X.truncate(BitWidth));
}
- ConstantRange FullSet(getTypeSizeInBits(S->getType()), true);
-
if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
- const SCEV *T = getBackedgeTakenCount(AddRec->getLoop());
- const SCEVConstant *Trip = dyn_cast<SCEVConstant>(T);
- ConstantRange ConservativeResult = FullSet;
-
// If there's no signed wrap, and all the operands have the same sign or
// zero, the value won't ever change sign.
if (AddRec->hasNoSignedWrap()) {
@@ -2977,20 +3026,22 @@ ScalarEvolution::getSignedRange(const SCEV *S) {
if (!isKnownNonNegative(AddRec->getOperand(i))) AllNonNeg = false;
if (!isKnownNonPositive(AddRec->getOperand(i))) AllNonPos = false;
}
- unsigned BitWidth = getTypeSizeInBits(AddRec->getType());
if (AllNonNeg)
- ConservativeResult = ConstantRange(APInt(BitWidth, 0),
- APInt::getSignedMinValue(BitWidth));
+ ConservativeResult = ConservativeResult.intersectWith(
+ ConstantRange(APInt(BitWidth, 0),
+ APInt::getSignedMinValue(BitWidth)));
else if (AllNonPos)
- ConservativeResult = ConstantRange(APInt::getSignedMinValue(BitWidth),
- APInt(BitWidth, 1));
+ ConservativeResult = ConservativeResult.intersectWith(
+ ConstantRange(APInt::getSignedMinValue(BitWidth),
+ APInt(BitWidth, 1)));
}
// TODO: non-affine addrec
- if (Trip && AddRec->isAffine()) {
+ if (AddRec->isAffine()) {
const Type *Ty = AddRec->getType();
const SCEV *MaxBECount = getMaxBackedgeTakenCount(AddRec->getLoop());
- if (getTypeSizeInBits(MaxBECount->getType()) <= getTypeSizeInBits(Ty)) {
+ if (!isa<SCEVCouldNotCompute>(MaxBECount) &&
+ getTypeSizeInBits(MaxBECount->getType()) <= BitWidth) {
MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty);
const SCEV *Start = AddRec->getStart();
@@ -3008,7 +3059,7 @@ ScalarEvolution::getSignedRange(const SCEV *S) {
EndRange.getSignedMax());
if (Min.isMinSignedValue() && Max.isMaxSignedValue())
return ConservativeResult;
- return ConstantRange(Min, Max+1);
+ return ConservativeResult.intersectWith(ConstantRange(Min, Max+1));
}
}
@@ -3017,18 +3068,17 @@ ScalarEvolution::getSignedRange(const SCEV *S) {
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
// For a SCEVUnknown, ask ValueTracking.
- unsigned BitWidth = getTypeSizeInBits(U->getType());
- if (!U->getValue()->getType()->isInteger() && !TD)
- return FullSet;
+ if (!U->getValue()->getType()->isIntegerTy() && !TD)
+ return ConservativeResult;
unsigned NS = ComputeNumSignBits(U->getValue(), TD);
if (NS == 1)
- return FullSet;
- return
+ return ConservativeResult;
+ return ConservativeResult.intersectWith(
ConstantRange(APInt::getSignedMinValue(BitWidth).ashr(NS - 1),
- APInt::getSignedMaxValue(BitWidth).ashr(NS - 1)+1);
+ APInt::getSignedMaxValue(BitWidth).ashr(NS - 1)+1));
}
- return FullSet;
+ return ConservativeResult;
}
/// createSCEV - We know that there is no SCEV for the specified value.
@@ -3179,7 +3229,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
case Instruction::Shl:
// Turn shift left of a constant amount into a multiply.
if (ConstantInt *SA = dyn_cast<ConstantInt>(U->getOperand(1))) {
- uint32_t BitWidth = cast<IntegerType>(V->getType())->getBitWidth();
+ uint32_t BitWidth = cast<IntegerType>(U->getType())->getBitWidth();
Constant *X = ConstantInt::get(getContext(),
APInt(BitWidth, 1).shl(SA->getLimitedValue(BitWidth)));
return getMulExpr(getSCEV(U->getOperand(0)), getSCEV(X));
@@ -3189,7 +3239,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
case Instruction::LShr:
// Turn logical shift right of a constant into a unsigned divide.
if (ConstantInt *SA = dyn_cast<ConstantInt>(U->getOperand(1))) {
- uint32_t BitWidth = cast<IntegerType>(V->getType())->getBitWidth();
+ uint32_t BitWidth = cast<IntegerType>(U->getType())->getBitWidth();
Constant *X = ConstantInt::get(getContext(),
APInt(BitWidth, 1).shl(SA->getLimitedValue(BitWidth)));
return getUDivExpr(getSCEV(U->getOperand(0)), getSCEV(X));
@@ -3230,10 +3280,10 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
return getSCEV(U->getOperand(0));
break;
- // It's tempting to handle inttoptr and ptrtoint, however this can
- // lead to pointer expressions which cannot be expanded to GEPs
- // (because they may overflow). For now, the only pointer-typed
- // expressions we handle are GEPs and address literals.
+ // It's tempting to handle inttoptr and ptrtoint as no-ops, however this can
+ // lead to pointer expressions which cannot safely be expanded to GEPs,
+ // because ScalarEvolution doesn't respect the GEP aliasing rules when
+ // simplifying integer expressions.
case Instruction::GetElementPtr:
return createNodeForGEP(cast<GEPOperator>(U));
@@ -3350,19 +3400,19 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
std::pair<std::map<const Loop *, BackedgeTakenInfo>::iterator, bool> Pair =
BackedgeTakenCounts.insert(std::make_pair(L, getCouldNotCompute()));
if (Pair.second) {
- BackedgeTakenInfo ItCount = ComputeBackedgeTakenCount(L);
- if (ItCount.Exact != getCouldNotCompute()) {
- assert(ItCount.Exact->isLoopInvariant(L) &&
- ItCount.Max->isLoopInvariant(L) &&
- "Computed trip count isn't loop invariant for loop!");
+ BackedgeTakenInfo BECount = ComputeBackedgeTakenCount(L);
+ if (BECount.Exact != getCouldNotCompute()) {
+ assert(BECount.Exact->isLoopInvariant(L) &&
+ BECount.Max->isLoopInvariant(L) &&
+ "Computed backedge-taken count isn't loop invariant for loop!");
++NumTripCountsComputed;
// Update the value in the map.
- Pair.first->second = ItCount;
+ Pair.first->second = BECount;
} else {
- if (ItCount.Max != getCouldNotCompute())
+ if (BECount.Max != getCouldNotCompute())
// Update the value in the map.
- Pair.first->second = ItCount;
+ Pair.first->second = BECount;
if (isa<PHINode>(L->getHeader()->begin()))
// Only count loops that have phi nodes as not being computable.
++NumTripCountsNotComputed;
@@ -3373,7 +3423,7 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
// conservative estimates made without the benefit of trip count
// information. This is similar to the code in forgetLoop, except that
// it handles SCEVUnknown PHI nodes specially.
- if (ItCount.hasAnyInfo()) {
+ if (BECount.hasAnyInfo()) {
SmallVector<Instruction *, 16> Worklist;
PushLoopPHIs(L, Worklist);
@@ -4230,9 +4280,6 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
return getTruncateExpr(Op, Cast->getType());
}
- if (isa<SCEVTargetDataConstant>(V))
- return V;
-
llvm_unreachable("Unknown SCEV type!");
return 0;
}
@@ -4403,7 +4450,7 @@ const SCEV *ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
-StartC->getValue()->getValue(),
*this);
}
- } else if (AddRec->isQuadratic() && AddRec->getType()->isInteger()) {
+ } else if (AddRec->isQuadratic() && AddRec->getType()->isIntegerTy()) {
// If this is a quadratic (3-term) AddRec {L,+,M,+,N}, find the roots of
// the quadratic equation to solve it.
std::pair<const SCEV *,const SCEV *> Roots = SolveQuadraticEquation(AddRec,
@@ -4947,6 +4994,9 @@ const SCEV *ScalarEvolution::getBECount(const SCEV *Start,
const SCEV *End,
const SCEV *Step,
bool NoWrap) {
+ assert(!isKnownNegative(Step) &&
+ "This code doesn't handle negative strides yet!");
+
const Type *Ty = Start->getType();
const SCEV *NegOne = getIntegerSCEV(-1, Ty);
const SCEV *Diff = getMinusSCEV(End, Start);
@@ -4989,39 +5039,35 @@ ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
AddRec->hasNoUnsignedWrap();
if (AddRec->isAffine()) {
- // FORNOW: We only support unit strides.
unsigned BitWidth = getTypeSizeInBits(AddRec->getType());
const SCEV *Step = AddRec->getStepRecurrence(*this);
- // TODO: handle non-constant strides.
- const SCEVConstant *CStep = dyn_cast<SCEVConstant>(Step);
- if (!CStep || CStep->isZero())
+ if (Step->isZero())
return getCouldNotCompute();
- if (CStep->isOne()) {
+ if (Step->isOne()) {
// With unit stride, the iteration never steps past the limit value.
- } else if (CStep->getValue()->getValue().isStrictlyPositive()) {
- if (NoWrap) {
- // We know the iteration won't step past the maximum value for its type.
- ;
- } else if (const SCEVConstant *CLimit = dyn_cast<SCEVConstant>(RHS)) {
- // Test whether a positive iteration iteration can step past the limit
- // value and past the maximum value for its type in a single step.
- if (isSigned) {
- APInt Max = APInt::getSignedMaxValue(BitWidth);
- if ((Max - CStep->getValue()->getValue())
- .slt(CLimit->getValue()->getValue()))
- return getCouldNotCompute();
- } else {
- APInt Max = APInt::getMaxValue(BitWidth);
- if ((Max - CStep->getValue()->getValue())
- .ult(CLimit->getValue()->getValue()))
- return getCouldNotCompute();
- }
- } else
- // TODO: handle non-constant limit values below.
- return getCouldNotCompute();
+ } else if (isKnownPositive(Step)) {
+ // Test whether a positive iteration can step past the limit
+ // value and past the maximum value for its type in a single step.
+ // Note that it's not sufficient to check NoWrap here, because even
+ // though the value after a wrap is undefined, it's not undefined
+ // behavior, so if wrap does occur, the loop could either terminate or
+ // loop infinitely, but in either case, the loop is guaranteed to
+ // iterate at least until the iteration where the wrapping occurs.
+ const SCEV *One = getIntegerSCEV(1, Step->getType());
+ if (isSigned) {
+ APInt Max = APInt::getSignedMaxValue(BitWidth);
+ if ((Max - getSignedRange(getMinusSCEV(Step, One)).getSignedMax())
+ .slt(getSignedRange(RHS).getSignedMax()))
+ return getCouldNotCompute();
+ } else {
+ APInt Max = APInt::getMaxValue(BitWidth);
+ if ((Max - getUnsignedRange(getMinusSCEV(Step, One)).getUnsignedMax())
+ .ult(getUnsignedRange(RHS).getUnsignedMax()))
+ return getCouldNotCompute();
+ }
} else
- // TODO: handle negative strides below.
+ // TODO: Handle negative strides here and below.
return getCouldNotCompute();
// We know the LHS is of the form {n,+,s} and the RHS is some loop-invariant
@@ -5054,6 +5100,20 @@ ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
getSignedRange(End).getSignedMax() :
getUnsignedRange(End).getUnsignedMax());
+ // If MaxEnd is within a step of the maximum integer value in its type,
+ // adjust it down to the minimum value which would produce the same effect.
+ // This allows the subsequent ceiling divison of (N+(step-1))/step to
+ // compute the correct value.
+ const SCEV *StepMinusOne = getMinusSCEV(Step,
+ getIntegerSCEV(1, Step->getType()));
+ MaxEnd = isSigned ?
+ getSMinExpr(MaxEnd,
+ getMinusSCEV(getConstant(APInt::getSignedMaxValue(BitWidth)),
+ StepMinusOne)) :
+ getUMinExpr(MaxEnd,
+ getMinusSCEV(getConstant(APInt::getMaxValue(BitWidth)),
+ StepMinusOne));
+
// Finally, we subtract these two values and divide, rounding up, to get
// the number of times the backedge is executed.
const SCEV *BECount = getBECount(Start, End, Step, NoWrap);
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index a72f58f..c2e1f89 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -365,31 +365,33 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
// the indices index into the element or field type selected by the
// preceding index.
for (;;) {
- const SCEV *ElSize = SE.getAllocSizeExpr(ElTy);
// If the scale size is not 0, attempt to factor out a scale for
// array indexing.
SmallVector<const SCEV *, 8> ScaledOps;
- if (ElTy->isSized() && !ElSize->isZero()) {
- SmallVector<const SCEV *, 8> NewOps;
- for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
- const SCEV *Op = Ops[i];
- const SCEV *Remainder = SE.getIntegerSCEV(0, Ty);
- if (FactorOutConstant(Op, Remainder, ElSize, SE, SE.TD)) {
- // Op now has ElSize factored out.
- ScaledOps.push_back(Op);
- if (!Remainder->isZero())
- NewOps.push_back(Remainder);
- AnyNonZeroIndices = true;
- } else {
- // The operand was not divisible, so add it to the list of operands
- // we'll scan next iteration.
- NewOps.push_back(Ops[i]);
+ if (ElTy->isSized()) {
+ const SCEV *ElSize = SE.getSizeOfExpr(ElTy);
+ if (!ElSize->isZero()) {
+ SmallVector<const SCEV *, 8> NewOps;
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
+ const SCEV *Op = Ops[i];
+ const SCEV *Remainder = SE.getIntegerSCEV(0, Ty);
+ if (FactorOutConstant(Op, Remainder, ElSize, SE, SE.TD)) {
+ // Op now has ElSize factored out.
+ ScaledOps.push_back(Op);
+ if (!Remainder->isZero())
+ NewOps.push_back(Remainder);
+ AnyNonZeroIndices = true;
+ } else {
+ // The operand was not divisible, so add it to the list of operands
+ // we'll scan next iteration.
+ NewOps.push_back(Ops[i]);
+ }
+ }
+ // If we made any changes, update Ops.
+ if (!ScaledOps.empty()) {
+ Ops = NewOps;
+ SimplifyAddOperands(Ops, Ty, SE);
}
- }
- // If we made any changes, update Ops.
- if (!ScaledOps.empty()) {
- Ops = NewOps;
- SimplifyAddOperands(Ops, Ty, SE);
}
}
@@ -427,22 +429,22 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
}
}
} else {
- // Without TargetData, just check for a SCEVFieldOffsetExpr of the
+ // Without TargetData, just check for an offsetof expression of the
// appropriate struct type.
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
- if (const SCEVFieldOffsetExpr *FO =
- dyn_cast<SCEVFieldOffsetExpr>(Ops[i]))
- if (FO->getStructType() == STy) {
- unsigned FieldNo = FO->getFieldNo();
- GepIndices.push_back(
- ConstantInt::get(Type::getInt32Ty(Ty->getContext()),
- FieldNo));
- ElTy = STy->getTypeAtIndex(FieldNo);
+ if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(Ops[i])) {
+ const Type *CTy;
+ Constant *FieldNo;
+ if (U->isOffsetOf(CTy, FieldNo) && CTy == STy) {
+ GepIndices.push_back(FieldNo);
+ ElTy =
+ STy->getTypeAtIndex(cast<ConstantInt>(FieldNo)->getZExtValue());
Ops[i] = SE.getConstant(Ty, 0);
AnyNonZeroIndices = true;
FoundFieldNo = true;
break;
}
+ }
}
// If no struct field offsets were found, tentatively assume that
// field zero was selected (since the zero offset would obviously
@@ -639,8 +641,52 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
// Reuse a previously-inserted PHI, if present.
for (BasicBlock::iterator I = L->getHeader()->begin();
PHINode *PN = dyn_cast<PHINode>(I); ++I)
- if (isInsertedInstruction(PN) && SE.getSCEV(PN) == Normalized)
- return PN;
+ if (SE.isSCEVable(PN->getType()) &&
+ (SE.getEffectiveSCEVType(PN->getType()) ==
+ SE.getEffectiveSCEVType(Normalized->getType())) &&
+ SE.getSCEV(PN) == Normalized)
+ if (BasicBlock *LatchBlock = L->getLoopLatch()) {
+ Instruction *IncV =
+ cast<Instruction>(PN->getIncomingValueForBlock(LatchBlock));
+
+ // Determine if this is a well-behaved chain of instructions leading
+ // back to the PHI. It probably will be, if we're scanning an inner
+ // loop already visited by LSR for example, but it wouldn't have
+ // to be.
+ do {
+ if (IncV->getNumOperands() == 0 || isa<PHINode>(IncV)) {
+ IncV = 0;
+ break;
+ }
+ IncV = dyn_cast<Instruction>(IncV->getOperand(0));
+ if (!IncV)
+ break;
+ if (IncV->mayHaveSideEffects()) {
+ IncV = 0;
+ break;
+ }
+ } while (IncV != PN);
+
+ if (IncV) {
+ // Ok, the add recurrence looks usable.
+ // Remember this PHI, even in post-inc mode.
+ InsertedValues.insert(PN);
+ // Remember the increment.
+ IncV = cast<Instruction>(PN->getIncomingValueForBlock(LatchBlock));
+ rememberInstruction(IncV);
+ if (L == IVIncInsertLoop)
+ do {
+ if (SE.DT->dominates(IncV, IVIncInsertPos))
+ break;
+ // Make sure the increment is where we want it. But don't move it
+ // down past a potential existing post-inc user.
+ IncV->moveBefore(IVIncInsertPos);
+ IVIncInsertPos = IncV;
+ IncV = cast<Instruction>(IncV->getOperand(0));
+ } while (IncV != PN);
+ return PN;
+ }
+ }
// Save the original insertion point so we can restore it when we're done.
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
@@ -711,7 +757,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
// Restore the original insert point.
if (SaveInsertBB)
- Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
// Remember this PHI, even in post-inc mode.
InsertedValues.insert(PN);
@@ -774,6 +820,7 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
// Re-apply any non-loop-dominating scale.
if (PostLoopScale) {
+ Result = InsertNoopCastOfTo(Result, IntTy);
Result = Builder.CreateMul(Result,
expandCodeFor(PostLoopScale, IntTy));
rememberInstruction(Result);
@@ -785,6 +832,7 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
const SCEV *const OffsetArray[1] = { PostLoopOffset };
Result = expandAddToGEP(OffsetArray, OffsetArray+1, PTy, IntTy, Result);
} else {
+ Result = InsertNoopCastOfTo(Result, IntTy);
Result = Builder.CreateAdd(Result,
expandCodeFor(PostLoopOffset, IntTy));
rememberInstruction(Result);
@@ -825,7 +873,7 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
while (isa<PHINode>(NewInsertPt)) ++NewInsertPt;
V = expandCodeFor(SE.getTruncateExpr(SE.getUnknown(V), Ty), 0,
NewInsertPt);
- Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
return V;
}
@@ -1001,14 +1049,6 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) {
return LHS;
}
-Value *SCEVExpander::visitFieldOffsetExpr(const SCEVFieldOffsetExpr *S) {
- return ConstantExpr::getOffsetOf(S->getStructType(), S->getFieldNo());
-}
-
-Value *SCEVExpander::visitAllocSizeExpr(const SCEVAllocSizeExpr *S) {
- return ConstantExpr::getSizeOf(S->getAllocType());
-}
-
Value *SCEVExpander::expandCodeFor(const SCEV *SH, const Type *Ty) {
// Expand the code for this SCEV.
Value *V = expand(SH);
@@ -1059,10 +1099,32 @@ Value *SCEVExpander::expand(const SCEV *S) {
if (!PostIncLoop)
InsertedExpressions[std::make_pair(S, InsertPt)] = V;
- Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
return V;
}
+void SCEVExpander::rememberInstruction(Value *I) {
+ if (!PostIncLoop)
+ InsertedValues.insert(I);
+
+ // If we just claimed an existing instruction and that instruction had
+ // been the insert point, adjust the insert point forward so that
+ // subsequently inserted code will be dominated.
+ if (Builder.GetInsertPoint() == I) {
+ BasicBlock::iterator It = cast<Instruction>(I);
+ do { ++It; } while (isInsertedInstruction(It));
+ Builder.SetInsertPoint(Builder.GetInsertBlock(), It);
+ }
+}
+
+void SCEVExpander::restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I) {
+ // If we aquired more instructions since the old insert point was saved,
+ // advance past them.
+ while (isInsertedInstruction(I)) ++I;
+
+ Builder.SetInsertPoint(BB, I);
+}
+
/// getOrInsertCanonicalInductionVariable - This method returns the
/// canonical induction variable of the specified type for the specified
/// loop (inserting one if there is none). A canonical induction variable
@@ -1070,13 +1132,13 @@ Value *SCEVExpander::expand(const SCEV *S) {
Value *
SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L,
const Type *Ty) {
- assert(Ty->isInteger() && "Can only insert integer induction variables!");
+ assert(Ty->isIntegerTy() && "Can only insert integer induction variables!");
const SCEV *H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty),
SE.getIntegerSCEV(1, Ty), L);
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
Value *V = expandCodeFor(H, 0, L->getHeader()->begin());
if (SaveInsertBB)
- Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
+ restoreInsertPoint(SaveInsertBB, SaveInsertPt);
return V;
}
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp
index 91e5bc3..7cc9c0d 100644
--- a/lib/Analysis/ValueTracking.cpp
+++ b/lib/Analysis/ValueTracking.cpp
@@ -49,11 +49,11 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
assert(V && "No Value?");
assert(Depth <= MaxDepth && "Limit Search Depth");
unsigned BitWidth = Mask.getBitWidth();
- assert((V->getType()->isIntOrIntVector() || isa<PointerType>(V->getType())) &&
- "Not integer or pointer type!");
+ assert((V->getType()->isIntOrIntVectorTy() || isa<PointerType>(V->getType()))
+ && "Not integer or pointer type!");
assert((!TD ||
TD->getTypeSizeInBits(V->getType()->getScalarType()) == BitWidth) &&
- (!V->getType()->isIntOrIntVector() ||
+ (!V->getType()->isIntOrIntVectorTy() ||
V->getType()->getScalarSizeInBits() == BitWidth) &&
KnownZero.getBitWidth() == BitWidth &&
KnownOne.getBitWidth() == BitWidth &&
@@ -269,7 +269,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
}
case Instruction::BitCast: {
const Type *SrcTy = I->getOperand(0)->getType();
- if ((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
+ if ((SrcTy->isIntegerTy() || isa<PointerType>(SrcTy)) &&
// TODO: For now, not handling conversions like:
// (bitcast i64 %x to <2 x i32>)
!isa<VectorType>(I->getType())) {
@@ -421,20 +421,29 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
}
case Instruction::SRem:
if (ConstantInt *Rem = dyn_cast<ConstantInt>(I->getOperand(1))) {
- APInt RA = Rem->getValue();
- if (RA.isPowerOf2() || (-RA).isPowerOf2()) {
- APInt LowBits = RA.isStrictlyPositive() ? (RA - 1) : ~RA;
+ APInt RA = Rem->getValue().abs();
+ if (RA.isPowerOf2()) {
+ APInt LowBits = RA - 1;
APInt Mask2 = LowBits | APInt::getSignBit(BitWidth);
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero2, KnownOne2, TD,
Depth+1);
- // If the sign bit of the first operand is zero, the sign bit of
- // the result is zero. If the first operand has no one bits below
- // the second operand's single 1 bit, its sign will be zero.
+ // The low bits of the first operand are unchanged by the srem.
+ KnownZero = KnownZero2 & LowBits;
+ KnownOne = KnownOne2 & LowBits;
+
+ // If the first operand is non-negative or has all low bits zero, then
+ // the upper bits are all zero.
if (KnownZero2[BitWidth-1] || ((KnownZero2 & LowBits) == LowBits))
- KnownZero2 |= ~LowBits;
+ KnownZero |= ~LowBits;
- KnownZero |= KnownZero2 & Mask;
+ // If the first operand is negative and not all low bits are zero, then
+ // the upper bits are all one.
+ if (KnownOne2[BitWidth-1] && ((KnownOne2 & LowBits) != 0))
+ KnownOne |= ~LowBits;
+
+ KnownZero &= Mask;
+ KnownOne &= Mask;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
}
@@ -640,7 +649,7 @@ bool llvm::MaskedValueIsZero(Value *V, const APInt &Mask,
///
unsigned llvm::ComputeNumSignBits(Value *V, const TargetData *TD,
unsigned Depth) {
- assert((TD || V->getType()->isIntOrIntVector()) &&
+ assert((TD || V->getType()->isIntOrIntVectorTy()) &&
"ComputeNumSignBits requires a TargetData object to operate "
"on non-integer values!");
const Type *Ty = V->getType();
@@ -814,7 +823,7 @@ bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
assert(V && "No Value?");
assert(Depth <= MaxDepth && "Limit Search Depth");
- assert(V->getType()->isInteger() && "Not integer or pointer type!");
+ assert(V->getType()->isIntegerTy() && "Not integer or pointer type!");
const Type *T = V->getType();
@@ -1363,7 +1372,7 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
// Make sure the index-ee is a pointer to array of i8.
const PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType());
const ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType());
- if (AT == 0 || !AT->getElementType()->isInteger(8))
+ if (AT == 0 || !AT->getElementType()->isIntegerTy(8))
return false;
// Check to make sure that the first operand of the GEP is an integer and
@@ -1402,7 +1411,7 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
// Must be a Constant Array
ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
- if (Array == 0 || !Array->getType()->getElementType()->isInteger(8))
+ if (Array == 0 || !Array->getType()->getElementType()->isIntegerTy(8))
return false;
// Get the number of elements in the array
diff --git a/lib/Archive/Archive.cpp b/lib/Archive/Archive.cpp
index 00778d9..f4f8a43 100644
--- a/lib/Archive/Archive.cpp
+++ b/lib/Archive/Archive.cpp
@@ -14,7 +14,6 @@
#include "ArchiveInternals.h"
#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/Module.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/System/Process.h"
@@ -173,8 +172,8 @@ void Archive::cleanUpMemory() {
foreignST = 0;
}
- // Delete any ModuleProviders and ArchiveMember's we've allocated as a result
- // of symbol table searches.
+ // Delete any Modules and ArchiveMember's we've allocated as a result of
+ // symbol table searches.
for (ModuleMap::iterator I=modules.begin(), E=modules.end(); I != E; ++I ) {
delete I->second.first;
delete I->second.second;
@@ -221,51 +220,37 @@ bool llvm::GetBitcodeSymbols(const sys::Path& fName,
return true;
}
- ModuleProvider *MP = getBitcodeModuleProvider(Buffer.get(), Context, ErrMsg);
- if (!MP)
+ Module *M = ParseBitcodeFile(Buffer.get(), Context, ErrMsg);
+ if (!M)
return true;
- // Get the module from the provider
- Module* M = MP->materializeModule();
- if (M == 0) {
- delete MP;
- return true;
- }
-
// Get the symbols
getSymbols(M, symbols);
// Done with the module.
- delete MP;
+ delete M;
return true;
}
-ModuleProvider*
+Module*
llvm::GetBitcodeSymbols(const unsigned char *BufPtr, unsigned Length,
const std::string& ModuleID,
LLVMContext& Context,
std::vector<std::string>& symbols,
std::string* ErrMsg) {
- // Get the module provider
- MemoryBuffer *Buffer =MemoryBuffer::getNewMemBuffer(Length, ModuleID.c_str());
+ // Get the module.
+ std::auto_ptr<MemoryBuffer> Buffer(
+ MemoryBuffer::getNewMemBuffer(Length, ModuleID.c_str()));
memcpy((char*)Buffer->getBufferStart(), BufPtr, Length);
- ModuleProvider *MP = getBitcodeModuleProvider(Buffer, Context, ErrMsg);
- if (!MP)
+ Module *M = ParseBitcodeFile(Buffer.get(), Context, ErrMsg);
+ if (!M)
return 0;
- // Get the module from the provider
- Module* M = MP->materializeModule();
- if (M == 0) {
- delete MP;
- return 0;
- }
-
// Get the symbols
getSymbols(M, symbols);
- // Done with the module. Note that ModuleProvider will delete the
- // Module when it is deleted. Also note that its the caller's responsibility
- // to delete the ModuleProvider.
- return MP;
+ // Done with the module. Note that it's the caller's responsibility to delete
+ // the Module.
+ return M;
}
diff --git a/lib/Archive/ArchiveInternals.h b/lib/Archive/ArchiveInternals.h
index d187ed9..baea544 100644
--- a/lib/Archive/ArchiveInternals.h
+++ b/lib/Archive/ArchiveInternals.h
@@ -77,11 +77,11 @@ namespace llvm {
std::vector<std::string>& symbols,
std::string* ErrMsg);
- ModuleProvider* GetBitcodeSymbols(const unsigned char*Buffer,unsigned Length,
- const std::string& ModuleID,
- LLVMContext& Context,
- std::vector<std::string>& symbols,
- std::string* ErrMsg);
+ Module* GetBitcodeSymbols(const unsigned char*Buffer,unsigned Length,
+ const std::string& ModuleID,
+ LLVMContext& Context,
+ std::vector<std::string>& symbols,
+ std::string* ErrMsg);
}
#endif
diff --git a/lib/Archive/ArchiveReader.cpp b/lib/Archive/ArchiveReader.cpp
index 74895d8..3ef15d2 100644
--- a/lib/Archive/ArchiveReader.cpp
+++ b/lib/Archive/ArchiveReader.cpp
@@ -120,7 +120,8 @@ Archive::parseMemberHeader(const char*& At, const char* End, std::string* error)
if (Hdr->name[1] == '1' && Hdr->name[2] == '/') {
if (isdigit(Hdr->name[3])) {
unsigned len = atoi(&Hdr->name[3]);
- pathname.assign(At, len);
+ const char *nulp = (const char *)memchr(At, '\0', len);
+ pathname.assign(At, nulp != 0 ? nulp - At : len);
At += len;
MemberSize -= len;
flags |= ArchiveMember::HasLongFilenameFlag;
@@ -452,9 +453,9 @@ Archive* Archive::OpenAndLoadSymbols(const sys::Path& file,
return result.release();
}
-// Look up one symbol in the symbol table and return a ModuleProvider for the
-// module that defines that symbol.
-ModuleProvider*
+// Look up one symbol in the symbol table and return the module that defines
+// that symbol.
+Module*
Archive::findModuleDefiningSymbol(const std::string& symbol,
std::string* ErrMsg) {
SymTabType::iterator SI = symTab.find(symbol);
@@ -483,27 +484,27 @@ Archive::findModuleDefiningSymbol(const std::string& symbol,
if (!mbr)
return 0;
- // Now, load the bitcode module to get the ModuleProvider
+ // Now, load the bitcode module to get the Module.
std::string FullMemberName = archPath.str() + "(" +
mbr->getPath().str() + ")";
MemoryBuffer *Buffer =MemoryBuffer::getNewMemBuffer(mbr->getSize(),
FullMemberName.c_str());
memcpy((char*)Buffer->getBufferStart(), mbr->getData(), mbr->getSize());
- ModuleProvider *mp = getBitcodeModuleProvider(Buffer, Context, ErrMsg);
- if (!mp)
+ Module *m = getLazyBitcodeModule(Buffer, Context, ErrMsg);
+ if (!m)
return 0;
- modules.insert(std::make_pair(fileOffset, std::make_pair(mp, mbr)));
+ modules.insert(std::make_pair(fileOffset, std::make_pair(m, mbr)));
- return mp;
+ return m;
}
// Look up multiple symbols in the symbol table and return a set of
-// ModuleProviders that define those symbols.
+// Modules that define those symbols.
bool
Archive::findModulesDefiningSymbols(std::set<std::string>& symbols,
- std::set<ModuleProvider*>& result,
+ std::set<Module*>& result,
std::string* error) {
if (!mapfile || !base) {
if (error)
@@ -536,19 +537,19 @@ Archive::findModulesDefiningSymbols(std::set<std::string>& symbols,
std::vector<std::string> symbols;
std::string FullMemberName = archPath.str() + "(" +
mbr->getPath().str() + ")";
- ModuleProvider* MP =
+ Module* M =
GetBitcodeSymbols((const unsigned char*)At, mbr->getSize(),
FullMemberName, Context, symbols, error);
- if (MP) {
+ if (M) {
// Insert the module's symbols into the symbol table
for (std::vector<std::string>::iterator I = symbols.begin(),
E=symbols.end(); I != E; ++I ) {
symTab.insert(std::make_pair(*I, offset));
}
- // Insert the ModuleProvider and the ArchiveMember into the table of
+ // Insert the Module and the ArchiveMember into the table of
// modules.
- modules.insert(std::make_pair(offset, std::make_pair(MP, mbr)));
+ modules.insert(std::make_pair(offset, std::make_pair(M, mbr)));
} else {
if (error)
*error = "Can't parse bitcode member: " +
@@ -571,11 +572,11 @@ Archive::findModulesDefiningSymbols(std::set<std::string>& symbols,
for (std::set<std::string>::iterator I=symbols.begin(),
E=symbols.end(); I != E;) {
// See if this symbol exists
- ModuleProvider* mp = findModuleDefiningSymbol(*I,error);
- if (mp) {
- // The symbol exists, insert the ModuleProvider into our result,
- // duplicates wil be ignored
- result.insert(mp);
+ Module* m = findModuleDefiningSymbol(*I,error);
+ if (m) {
+ // The symbol exists, insert the Module into our result, duplicates will
+ // be ignored.
+ result.insert(m);
// Remove the symbol now that its been resolved, being careful to
// post-increment the iterator.
diff --git a/lib/Archive/ArchiveWriter.cpp b/lib/Archive/ArchiveWriter.cpp
index d17f6b5..58fbbf4 100644
--- a/lib/Archive/ArchiveWriter.cpp
+++ b/lib/Archive/ArchiveWriter.cpp
@@ -12,12 +12,12 @@
//===----------------------------------------------------------------------===//
#include "ArchiveInternals.h"
-#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Module.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/System/Signals.h"
#include "llvm/System/Process.h"
-#include "llvm/ModuleProvider.h"
+#include "llvm/System/Signals.h"
#include <fstream>
#include <ostream>
#include <iomanip>
@@ -225,12 +225,12 @@ Archive::writeMember(
std::vector<std::string> symbols;
std::string FullMemberName = archPath.str() + "(" + member.getPath().str()
+ ")";
- ModuleProvider* MP =
+ Module* M =
GetBitcodeSymbols((const unsigned char*)data,fSize,
FullMemberName, Context, symbols, ErrMsg);
// If the bitcode parsed successfully
- if ( MP ) {
+ if ( M ) {
for (std::vector<std::string>::iterator SI = symbols.begin(),
SE = symbols.end(); SI != SE; ++SI) {
@@ -244,7 +244,7 @@ Archive::writeMember(
}
}
// We don't need this module any more.
- delete MP;
+ delete M;
} else {
delete mFile;
if (ErrMsg)
diff --git a/lib/Archive/Makefile b/lib/Archive/Makefile
index 1256e1c..da97804 100644
--- a/lib/Archive/Makefile
+++ b/lib/Archive/Makefile
@@ -9,7 +9,6 @@
LEVEL = ../..
LIBRARYNAME = LLVMArchive
-CXXFLAGS = -fno-rtti
# We only want an archive so only those modules actually used by a tool are
# included.
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 2a926d2..46f3cbc 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -558,6 +558,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(readnone);
KEYWORD(readonly);
+ KEYWORD(inlinehint);
KEYWORD(noinline);
KEYWORD(alwaysinline);
KEYWORD(optsize);
@@ -569,6 +570,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(type);
KEYWORD(opaque);
+ KEYWORD(union);
KEYWORD(eq); KEYWORD(ne); KEYWORD(slt); KEYWORD(sgt); KEYWORD(sle);
KEYWORD(sge); KEYWORD(ult); KEYWORD(ugt); KEYWORD(ule); KEYWORD(uge);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 04a5263c..9cae0d2 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -947,6 +947,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
case lltok::kw_noinline: Attrs |= Attribute::NoInline; break;
case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
+ case lltok::kw_inlinehint: Attrs |= Attribute::InlineHint; break;
case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break;
case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break;
case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break;
@@ -955,6 +956,14 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
case lltok::kw_naked: Attrs |= Attribute::Naked; break;
+ case lltok::kw_alignstack: {
+ unsigned Alignment;
+ if (ParseOptionalStackAlignment(Alignment))
+ return true;
+ Attrs |= Attribute::constructStackAlignmentFromInt(Alignment);
+ continue;
+ }
+
case lltok::kw_align: {
unsigned Alignment;
if (ParseOptionalAlignment(Alignment))
@@ -962,6 +971,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
Attrs |= Attribute::constructAlignmentFromInt(Alignment);
continue;
}
+
}
Lex.Lex();
}
@@ -1130,6 +1140,25 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,
return false;
}
+/// ParseOptionalStackAlignment
+/// ::= /* empty */
+/// ::= 'alignstack' '(' 4 ')'
+bool LLParser::ParseOptionalStackAlignment(unsigned &Alignment) {
+ Alignment = 0;
+ if (!EatIfPresent(lltok::kw_alignstack))
+ return false;
+ LocTy ParenLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::lparen))
+ return Error(ParenLoc, "expected '('");
+ LocTy AlignLoc = Lex.getLoc();
+ if (ParseUInt32(Alignment)) return true;
+ ParenLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::rparen))
+ return Error(ParenLoc, "expected ')'");
+ if (!isPowerOf2_32(Alignment))
+ return Error(AlignLoc, "stack alignment is not a power of two");
+ return false;
+}
/// ParseIndexList - This parses the index list for an insert/extractvalue
/// instruction. This sets AteExtraComma in the case where we eat an extra
@@ -1266,6 +1295,11 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
if (ParseStructType(Result, false))
return true;
break;
+ case lltok::kw_union:
+ // TypeRec ::= 'union' '{' ... '}'
+ if (ParseUnionType(Result))
+ return true;
+ break;
case lltok::lsquare:
// TypeRec ::= '[' ... ']'
Lex.Lex(); // eat the lsquare.
@@ -1575,6 +1609,38 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
return false;
}
+/// ParseUnionType
+/// TypeRec
+/// ::= 'union' '{' TypeRec (',' TypeRec)* '}'
+bool LLParser::ParseUnionType(PATypeHolder &Result) {
+ assert(Lex.getKind() == lltok::kw_union);
+ Lex.Lex(); // Consume the 'union'
+
+ if (ParseToken(lltok::lbrace, "'{' expected after 'union'")) return true;
+
+ SmallVector<PATypeHolder, 8> ParamsList;
+ do {
+ LocTy EltTyLoc = Lex.getLoc();
+ if (ParseTypeRec(Result)) return true;
+ ParamsList.push_back(Result);
+
+ if (Result->isVoidTy())
+ return Error(EltTyLoc, "union element can not have void type");
+ if (!UnionType::isValidElementType(Result))
+ return Error(EltTyLoc, "invalid element type for union");
+
+ } while (EatIfPresent(lltok::comma)) ;
+
+ if (ParseToken(lltok::rbrace, "expected '}' at end of union"))
+ return true;
+
+ SmallVector<const Type*, 8> ParamsListTy;
+ for (unsigned i = 0, e = ParamsList.size(); i != e; ++i)
+ ParamsListTy.push_back(ParamsList[i].get());
+ Result = HandleUpRefs(UnionType::get(&ParamsListTy[0], ParamsListTy.size()));
+ return false;
+}
+
/// ParseArrayVectorType - Parse an array or vector type, assuming the first
/// token has already been consumed.
/// TypeRec
@@ -1991,8 +2057,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
if (Elts.empty())
return Error(ID.Loc, "constant vector must not be empty");
- if (!Elts[0]->getType()->isInteger() &&
- !Elts[0]->getType()->isFloatingPoint())
+ if (!Elts[0]->getType()->isIntegerTy() &&
+ !Elts[0]->getType()->isFloatingPointTy())
return Error(FirstEltLoc,
"vector elements must have integer or floating point type");
@@ -2134,8 +2200,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
ParseToken(lltok::rparen, "expected ')' in extractvalue constantexpr"))
return true;
- if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
- return Error(ID.Loc, "extractvalue operand must be array or struct");
+ if (!Val->getType()->isAggregateType())
+ return Error(ID.Loc, "extractvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
Indices.end()))
return Error(ID.Loc, "invalid indices for extractvalue");
@@ -2155,8 +2221,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
ParseIndexList(Indices) ||
ParseToken(lltok::rparen, "expected ')' in insertvalue constantexpr"))
return true;
- if (!isa<StructType>(Val0->getType()) && !isa<ArrayType>(Val0->getType()))
- return Error(ID.Loc, "extractvalue operand must be array or struct");
+ if (!Val0->getType()->isAggregateType())
+ return Error(ID.Loc, "insertvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
Indices.end()))
return Error(ID.Loc, "invalid indices for insertvalue");
@@ -2184,12 +2250,12 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
CmpInst::Predicate Pred = (CmpInst::Predicate)PredVal;
if (Opc == Instruction::FCmp) {
- if (!Val0->getType()->isFPOrFPVector())
+ if (!Val0->getType()->isFPOrFPVectorTy())
return Error(ID.Loc, "fcmp requires floating point operands");
ID.ConstantVal = ConstantExpr::getFCmp(Pred, Val0, Val1);
} else {
assert(Opc == Instruction::ICmp && "Unexpected opcode for CmpInst!");
- if (!Val0->getType()->isIntOrIntVector() &&
+ if (!Val0->getType()->isIntOrIntVectorTy() &&
!isa<PointerType>(Val0->getType()))
return Error(ID.Loc, "icmp requires pointer or integer operands");
ID.ConstantVal = ConstantExpr::getICmp(Pred, Val0, Val1);
@@ -2240,7 +2306,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
return true;
if (Val0->getType() != Val1->getType())
return Error(ID.Loc, "operands of constexpr must have same type");
- if (!Val0->getType()->isIntOrIntVector()) {
+ if (!Val0->getType()->isIntOrIntVectorTy()) {
if (NUW)
return Error(ModifierLoc, "nuw only applies to integer operations");
if (NSW)
@@ -2248,8 +2314,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
}
// API compatibility: Accept either integer or floating-point types with
// add, sub, and mul.
- if (!Val0->getType()->isIntOrIntVector() &&
- !Val0->getType()->isFPOrFPVector())
+ if (!Val0->getType()->isIntOrIntVectorTy() &&
+ !Val0->getType()->isFPOrFPVectorTy())
return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
unsigned Flags = 0;
if (NUW) Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
@@ -2279,7 +2345,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
return true;
if (Val0->getType() != Val1->getType())
return Error(ID.Loc, "operands of constexpr must have same type");
- if (!Val0->getType()->isIntOrIntVector())
+ if (!Val0->getType()->isIntOrIntVectorTy())
return Error(ID.Loc,
"constexpr requires integer or integer vector operands");
ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1);
@@ -2449,7 +2515,7 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
V = ConstantInt::get(Context, ID.APSIntVal);
return false;
case ValID::t_APFloat:
- if (!Ty->isFloatingPoint() ||
+ if (!Ty->isFloatingPointTy() ||
!ConstantFP::isValueValidForType(Ty, ID.APFloatVal))
return Error(ID.Loc, "floating point constant invalid for type");
@@ -2492,8 +2558,17 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
V = Constant::getNullValue(Ty);
return false;
case ValID::t_Constant:
- if (ID.ConstantVal->getType() != Ty)
+ if (ID.ConstantVal->getType() != Ty) {
+ // Allow a constant struct with a single member to be converted
+ // to a union, if the union has a member which is the same type
+ // as the struct member.
+ if (const UnionType* utype = dyn_cast<UnionType>(Ty)) {
+ return ParseUnionValue(utype, ID, V);
+ }
+
return Error(ID.Loc, "constant expression type mismatch");
+ }
+
V = ID.ConstantVal;
return false;
}
@@ -2523,6 +2598,22 @@ bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
return false;
}
+bool LLParser::ParseUnionValue(const UnionType* utype, ValID &ID, Value *&V) {
+ if (const StructType* stype = dyn_cast<StructType>(ID.ConstantVal->getType())) {
+ if (stype->getNumContainedTypes() != 1)
+ return Error(ID.Loc, "constant expression type mismatch");
+ int index = utype->getElementTypeIndex(stype->getContainedType(0));
+ if (index < 0)
+ return Error(ID.Loc, "initializer type is not a member of the union");
+
+ V = ConstantUnion::get(
+ utype, cast<Constant>(ID.ConstantVal->getOperand(0)));
+ return false;
+ }
+
+ return Error(ID.Loc, "constant expression type mismatch");
+}
+
/// FunctionHeader
/// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs
@@ -2566,7 +2657,6 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
return Error(LinkageLoc, "invalid linkage for function declaration");
break;
case GlobalValue::AppendingLinkage:
- case GlobalValue::GhostLinkage:
case GlobalValue::CommonLinkage:
return Error(LinkageLoc, "invalid function linkage type");
}
@@ -2873,7 +2963,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
// API compatibility: Accept either integer or floating-point types.
bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 0);
if (!Result) {
- if (!Inst->getType()->isIntOrIntVector()) {
+ if (!Inst->getType()->isIntOrIntVectorTy()) {
if (NUW)
return Error(ModifierLoc, "nuw only applies to integer operations");
if (NSW)
@@ -3292,11 +3382,11 @@ bool LLParser::ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS,
switch (OperandType) {
default: llvm_unreachable("Unknown operand type!");
case 0: // int or FP.
- Valid = LHS->getType()->isIntOrIntVector() ||
- LHS->getType()->isFPOrFPVector();
+ Valid = LHS->getType()->isIntOrIntVectorTy() ||
+ LHS->getType()->isFPOrFPVectorTy();
break;
- case 1: Valid = LHS->getType()->isIntOrIntVector(); break;
- case 2: Valid = LHS->getType()->isFPOrFPVector(); break;
+ case 1: Valid = LHS->getType()->isIntOrIntVectorTy(); break;
+ case 2: Valid = LHS->getType()->isFPOrFPVectorTy(); break;
}
if (!Valid)
@@ -3316,7 +3406,7 @@ bool LLParser::ParseLogical(Instruction *&Inst, PerFunctionState &PFS,
ParseValue(LHS->getType(), RHS, PFS))
return true;
- if (!LHS->getType()->isIntOrIntVector())
+ if (!LHS->getType()->isIntOrIntVectorTy())
return Error(Loc,"instruction requires integer or integer vector operands");
Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
@@ -3340,12 +3430,12 @@ bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS,
return true;
if (Opc == Instruction::FCmp) {
- if (!LHS->getType()->isFPOrFPVector())
+ if (!LHS->getType()->isFPOrFPVectorTy())
return Error(Loc, "fcmp requires floating point operands");
Inst = new FCmpInst(CmpInst::Predicate(Pred), LHS, RHS);
} else {
assert(Opc == Instruction::ICmp && "Unknown opcode for CmpInst!");
- if (!LHS->getType()->isIntOrIntVector() &&
+ if (!LHS->getType()->isIntOrIntVectorTy() &&
!isa<PointerType>(LHS->getType()))
return Error(Loc, "icmp requires integer operands");
Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS);
@@ -3643,7 +3733,7 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
}
}
- if (Size && !Size->getType()->isInteger(32))
+ if (Size && !Size->getType()->isIntegerTy(32))
return Error(SizeLoc, "element count must be i32");
if (isAlloca) {
@@ -3783,8 +3873,8 @@ int LLParser::ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS) {
ParseIndexList(Indices, AteExtraComma))
return true;
- if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
- return Error(Loc, "extractvalue operand must be array or struct");
+ if (!Val->getType()->isAggregateType())
+ return Error(Loc, "extractvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
Indices.end()))
@@ -3805,8 +3895,8 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
ParseIndexList(Indices, AteExtraComma))
return true;
- if (!isa<StructType>(Val0->getType()) && !isa<ArrayType>(Val0->getType()))
- return Error(Loc0, "extractvalue operand must be array or struct");
+ if (!Val0->getType()->isAggregateType())
+ return Error(Loc0, "insertvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
Indices.end()))
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 85c07ff..9abe404 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -31,6 +31,7 @@ namespace llvm {
class GlobalValue;
class MDString;
class MDNode;
+ class UnionType;
/// ValID - Represents a reference of a definition of some sort with no type.
/// There are several cases where we have to parse the value but where the
@@ -169,6 +170,7 @@ namespace llvm {
bool ParseOptionalVisibility(unsigned &Visibility);
bool ParseOptionalCallingConv(CallingConv::ID &CC);
bool ParseOptionalAlignment(unsigned &Alignment);
+ bool ParseOptionalStackAlignment(unsigned &Alignment);
bool ParseInstructionMetadata(SmallVectorImpl<std::pair<unsigned,
MDNode *> > &);
bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma);
@@ -211,6 +213,7 @@ namespace llvm {
}
bool ParseTypeRec(PATypeHolder &H);
bool ParseStructType(PATypeHolder &H, bool Packed);
+ bool ParseUnionType(PATypeHolder &H);
bool ParseArrayVectorType(PATypeHolder &H, bool isVector);
bool ParseFunctionType(PATypeHolder &Result);
PATypeHolder HandleUpRefs(const Type *Ty);
@@ -279,6 +282,8 @@ namespace llvm {
return ParseTypeAndBasicBlock(BB, Loc, PFS);
}
+ bool ParseUnionValue(const UnionType* utype, ValID &ID, Value *&V);
+
struct ParamInfo {
LocTy Loc;
Value *V;
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 80eb194..3ac9169 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -85,6 +85,7 @@ namespace lltok {
kw_readnone,
kw_readonly,
+ kw_inlinehint,
kw_noinline,
kw_alwaysinline,
kw_optsize,
@@ -96,6 +97,7 @@ namespace lltok {
kw_type,
kw_opaque,
+ kw_union,
kw_eq, kw_ne, kw_slt, kw_sgt, kw_sle, kw_sge, kw_ult, kw_ugt, kw_ule,
kw_uge, kw_oeq, kw_one, kw_olt, kw_ogt, kw_ole, kw_oge, kw_ord, kw_uno,
diff --git a/lib/AsmParser/Makefile b/lib/AsmParser/Makefile
index 7b53a87..995bb0e 100644
--- a/lib/AsmParser/Makefile
+++ b/lib/AsmParser/Makefile
@@ -10,6 +10,5 @@
LEVEL = ../..
LIBRARYNAME := LLVMAsmParser
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Bitcode/Reader/BitReader.cpp b/lib/Bitcode/Reader/BitReader.cpp
index 32b97e8..7537435 100644
--- a/lib/Bitcode/Reader/BitReader.cpp
+++ b/lib/Bitcode/Reader/BitReader.cpp
@@ -21,17 +21,8 @@ using namespace llvm;
Optionally returns a human-readable error message via OutMessage. */
LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
LLVMModuleRef *OutModule, char **OutMessage) {
- std::string Message;
-
- *OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), getGlobalContext(),
- &Message));
- if (!*OutModule) {
- if (OutMessage)
- *OutMessage = strdup(Message.c_str());
- return 1;
- }
-
- return 0;
+ return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule,
+ OutMessage);
}
LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
@@ -57,18 +48,8 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
LLVMModuleProviderRef *OutMP,
char **OutMessage) {
- std::string Message;
-
- *OutMP = wrap(getBitcodeModuleProvider(unwrap(MemBuf), getGlobalContext(),
- &Message));
-
- if (!*OutMP) {
- if (OutMessage)
- *OutMessage = strdup(Message.c_str());
- return 1;
- }
-
- return 0;
+ return LLVMGetBitcodeModuleProviderInContext(wrap(&getGlobalContext()),
+ MemBuf, OutMP, OutMessage);
}
LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
@@ -77,8 +58,8 @@ LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
char **OutMessage) {
std::string Message;
- *OutMP = wrap(getBitcodeModuleProvider(unwrap(MemBuf), *unwrap(ContextRef),
- &Message));
+ *OutMP = reinterpret_cast<LLVMModuleProviderRef>(
+ getLazyBitcodeModule(unwrap(MemBuf), *unwrap(ContextRef), &Message));
if (!*OutMP) {
if (OutMessage)
*OutMessage = strdup(Message.c_str());
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 2549a51..cebfbf6 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -28,7 +28,8 @@
using namespace llvm;
void BitcodeReader::FreeState() {
- delete Buffer;
+ if (BufferOwned)
+ delete Buffer;
Buffer = 0;
std::vector<PATypeHolder>().swap(TypeList);
ValueList.clear();
@@ -107,17 +108,17 @@ static int GetDecodedBinaryOpcode(unsigned Val, const Type *Ty) {
switch (Val) {
default: return -1;
case bitc::BINOP_ADD:
- return Ty->isFPOrFPVector() ? Instruction::FAdd : Instruction::Add;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FAdd : Instruction::Add;
case bitc::BINOP_SUB:
- return Ty->isFPOrFPVector() ? Instruction::FSub : Instruction::Sub;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FSub : Instruction::Sub;
case bitc::BINOP_MUL:
- return Ty->isFPOrFPVector() ? Instruction::FMul : Instruction::Mul;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FMul : Instruction::Mul;
case bitc::BINOP_UDIV: return Instruction::UDiv;
case bitc::BINOP_SDIV:
- return Ty->isFPOrFPVector() ? Instruction::FDiv : Instruction::SDiv;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FDiv : Instruction::SDiv;
case bitc::BINOP_UREM: return Instruction::URem;
case bitc::BINOP_SREM:
- return Ty->isFPOrFPVector() ? Instruction::FRem : Instruction::SRem;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FRem : Instruction::SRem;
case bitc::BINOP_SHL: return Instruction::Shl;
case bitc::BINOP_LSHR: return Instruction::LShr;
case bitc::BINOP_ASHR: return Instruction::AShr;
@@ -584,6 +585,13 @@ bool BitcodeReader::ParseTypeTable() {
ResultTy = StructType::get(Context, EltTys, Record[0]);
break;
}
+ case bitc::TYPE_CODE_UNION: { // UNION: [eltty x N]
+ SmallVector<const Type*, 8> EltTys;
+ for (unsigned i = 0, e = Record.size(); i != e; ++i)
+ EltTys.push_back(getTypeByID(Record[i], true));
+ ResultTy = UnionType::get(&EltTys[0], EltTys.size());
+ break;
+ }
case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
if (Record.size() < 2)
return Error("Invalid ARRAY type record");
@@ -1167,7 +1175,7 @@ bool BitcodeReader::ParseConstants() {
Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
- if (OpTy->isFPOrFPVector())
+ if (OpTy->isFPOrFPVectorTy())
V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
else
V = ConstantExpr::getICmp(Record[3], Op0, Op1);
@@ -1241,11 +1249,7 @@ bool BitcodeReader::RememberAndSkipFunctionBody() {
// Save the current stream state.
uint64_t CurBit = Stream.GetCurrentBitNo();
- DeferredFunctionInfo[Fn] = std::make_pair(CurBit, Fn->getLinkage());
-
- // Set the functions linkage to GhostLinkage so we know it is lazily
- // deserialized.
- Fn->setLinkage(GlobalValue::GhostLinkage);
+ DeferredFunctionInfo[Fn] = CurBit;
// Skip over the function block for now.
if (Stream.SkipBlock())
@@ -1253,17 +1257,10 @@ bool BitcodeReader::RememberAndSkipFunctionBody() {
return false;
}
-bool BitcodeReader::ParseModule(const std::string &ModuleID) {
- // Reject multiple MODULE_BLOCK's in a single bitstream.
- if (TheModule)
- return Error("Multiple MODULE_BLOCKs in same stream");
-
+bool BitcodeReader::ParseModule() {
if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
return Error("Malformed block record");
- // Otherwise, create the module.
- TheModule = new Module(ModuleID, Context);
-
SmallVector<uint64_t, 64> Record;
std::vector<std::string> SectionTable;
std::vector<std::string> GCTable;
@@ -1520,7 +1517,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
return Error("Premature end of bitstream");
}
-bool BitcodeReader::ParseBitcode() {
+bool BitcodeReader::ParseBitcodeInto(Module *M) {
TheModule = 0;
if (Buffer->getBufferSize() & 3)
@@ -1564,7 +1561,11 @@ bool BitcodeReader::ParseBitcode() {
return Error("Malformed BlockInfoBlock");
break;
case bitc::MODULE_BLOCK_ID:
- if (ParseModule(Buffer->getBufferIdentifier()))
+ // Reject multiple MODULE_BLOCK's in a single bitstream.
+ if (TheModule)
+ return Error("Multiple MODULE_BLOCKs in same stream");
+ TheModule = M;
+ if (ParseModule())
return true;
break;
default:
@@ -1702,12 +1703,12 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
if (Opc == Instruction::Add ||
Opc == Instruction::Sub ||
Opc == Instruction::Mul) {
- if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+ if (Record[OpNum] & (1 << bitc::OBO_NO_SIGNED_WRAP))
cast<BinaryOperator>(I)->setHasNoSignedWrap(true);
- if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+ if (Record[OpNum] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true);
} else if (Opc == Instruction::SDiv) {
- if (Record[3] & (1 << bitc::SDIV_EXACT))
+ if (Record[OpNum] & (1 << bitc::SDIV_EXACT))
cast<BinaryOperator>(I)->setIsExact(true);
}
}
@@ -1891,7 +1892,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
OpNum+1 != Record.size())
return Error("Invalid CMP record");
- if (LHS->getType()->isFPOrFPVector())
+ if (LHS->getType()->isFPOrFPVectorTy())
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
else
I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
@@ -2299,22 +2300,28 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
}
//===----------------------------------------------------------------------===//
-// ModuleProvider implementation
+// GVMaterializer implementation
//===----------------------------------------------------------------------===//
-bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) {
- // If it already is material, ignore the request.
- if (!F->hasNotBeenReadFromBitcode()) return false;
+bool BitcodeReader::isMaterializable(const GlobalValue *GV) const {
+ if (const Function *F = dyn_cast<Function>(GV)) {
+ return F->isDeclaration() &&
+ DeferredFunctionInfo.count(const_cast<Function*>(F));
+ }
+ return false;
+}
- DenseMap<Function*, std::pair<uint64_t, unsigned> >::iterator DFII =
- DeferredFunctionInfo.find(F);
+bool BitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) {
+ Function *F = dyn_cast<Function>(GV);
+ // If it's not a function or is already material, ignore the request.
+ if (!F || !F->isMaterializable()) return false;
+
+ DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F);
assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
- // Move the bit stream to the saved position of the deferred function body and
- // restore the real linkage type for the function.
- Stream.JumpToBit(DFII->second.first);
- F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second);
+ // Move the bit stream to the saved position of the deferred function body.
+ Stream.JumpToBit(DFII->second);
if (ParseFunctionBody(F)) {
if (ErrInfo) *ErrInfo = ErrorString;
@@ -2336,27 +2343,36 @@ bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) {
return false;
}
-void BitcodeReader::dematerializeFunction(Function *F) {
- // If this function isn't materialized, or if it is a proto, this is a noop.
- if (F->hasNotBeenReadFromBitcode() || F->isDeclaration())
+bool BitcodeReader::isDematerializable(const GlobalValue *GV) const {
+ const Function *F = dyn_cast<Function>(GV);
+ if (!F || F->isDeclaration())
+ return false;
+ return DeferredFunctionInfo.count(const_cast<Function*>(F));
+}
+
+void BitcodeReader::Dematerialize(GlobalValue *GV) {
+ Function *F = dyn_cast<Function>(GV);
+ // If this function isn't dematerializable, this is a noop.
+ if (!F || !isDematerializable(F))
return;
assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
// Just forget the function body, we can remat it later.
F->deleteBody();
- F->setLinkage(GlobalValue::GhostLinkage);
}
-Module *BitcodeReader::materializeModule(std::string *ErrInfo) {
+bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) {
+ assert(M == TheModule &&
+ "Can only Materialize the Module this BitcodeReader is attached to.");
// Iterate over the module, deserializing any functions that are still on
// disk.
for (Module::iterator F = TheModule->begin(), E = TheModule->end();
F != E; ++F)
- if (F->hasNotBeenReadFromBitcode() &&
- materializeFunction(F, ErrInfo))
- return 0;
+ if (F->isMaterializable() &&
+ Materialize(F, ErrInfo))
+ return true;
// Upgrade any intrinsic calls that slipped through (should not happen!) and
// delete the old functions to clean up. We can't do this unless the entire
@@ -2380,19 +2396,7 @@ Module *BitcodeReader::materializeModule(std::string *ErrInfo) {
// Check debug info intrinsics.
CheckDebugInfoIntrinsics(TheModule);
- return TheModule;
-}
-
-
-/// This method is provided by the parent ModuleProvde class and overriden
-/// here. It simply releases the module from its provided and frees up our
-/// state.
-/// @brief Release our hold on the generated module
-Module *BitcodeReader::releaseModule(std::string *ErrInfo) {
- // Since we're losing control of this Module, we must hand it back complete
- Module *M = ModuleProvider::releaseModule(ErrInfo);
- FreeState();
- return M;
+ return false;
}
@@ -2400,45 +2404,41 @@ Module *BitcodeReader::releaseModule(std::string *ErrInfo) {
// External interface
//===----------------------------------------------------------------------===//
-/// getBitcodeModuleProvider - lazy function-at-a-time loading from a file.
+/// getLazyBitcodeModule - lazy function-at-a-time loading from a file.
///
-ModuleProvider *llvm::getBitcodeModuleProvider(MemoryBuffer *Buffer,
- LLVMContext& Context,
- std::string *ErrMsg) {
+Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
+ LLVMContext& Context,
+ std::string *ErrMsg) {
+ Module *M = new Module(Buffer->getBufferIdentifier(), Context);
BitcodeReader *R = new BitcodeReader(Buffer, Context);
- if (R->ParseBitcode()) {
+ M->setMaterializer(R);
+ if (R->ParseBitcodeInto(M)) {
if (ErrMsg)
*ErrMsg = R->getErrorString();
- // Don't let the BitcodeReader dtor delete 'Buffer'.
- R->releaseMemoryBuffer();
- delete R;
+ delete M; // Also deletes R.
return 0;
}
- return R;
+ // Have the BitcodeReader dtor delete 'Buffer'.
+ R->setBufferOwned(true);
+ return M;
}
/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
/// If an error occurs, return null and fill in *ErrMsg if non-null.
Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
std::string *ErrMsg){
- BitcodeReader *R;
- R = static_cast<BitcodeReader*>(getBitcodeModuleProvider(Buffer, Context,
- ErrMsg));
- if (!R) return 0;
-
- // Read in the entire module.
- Module *M = R->materializeModule(ErrMsg);
+ Module *M = getLazyBitcodeModule(Buffer, Context, ErrMsg);
+ if (!M) return 0;
// Don't let the BitcodeReader dtor delete 'Buffer', regardless of whether
// there was an error.
- R->releaseMemoryBuffer();
+ static_cast<BitcodeReader*>(M->getMaterializer())->setBufferOwned(false);
- // If there was no error, tell ModuleProvider not to delete it when its dtor
- // is run.
- if (M)
- M = R->releaseModule(ErrMsg);
-
- delete R;
+ // Read in the entire module, and destroy the BitcodeReader.
+ if (M->MaterializeAllPermanently(ErrMsg)) {
+ delete M;
+ return NULL;
+ }
return M;
}
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
index bb3961a..55c71f7 100644
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ b/lib/Bitcode/Reader/BitcodeReader.h
@@ -14,7 +14,7 @@
#ifndef BITCODE_READER_H
#define BITCODE_READER_H
-#include "llvm/ModuleProvider.h"
+#include "llvm/GVMaterializer.h"
#include "llvm/Attributes.h"
#include "llvm/Type.h"
#include "llvm/OperandTraits.h"
@@ -121,9 +121,11 @@ public:
void AssignValue(Value *V, unsigned Idx);
};
-class BitcodeReader : public ModuleProvider {
+class BitcodeReader : public GVMaterializer {
LLVMContext &Context;
+ Module *TheModule;
MemoryBuffer *Buffer;
+ bool BufferOwned;
BitstreamReader StreamFile;
BitstreamCursor Stream;
@@ -160,9 +162,9 @@ class BitcodeReader : public ModuleProvider {
bool HasReversedFunctionsWithBodies;
/// DeferredFunctionInfo - When function bodies are initially scanned, this
- /// map contains info about where to find deferred function body (in the
- /// stream) and what linkage the original function had.
- DenseMap<Function*, std::pair<uint64_t, unsigned> > DeferredFunctionInfo;
+ /// map contains info about where to find deferred function body in the
+ /// stream.
+ DenseMap<Function*, uint64_t> DeferredFunctionInfo;
/// BlockAddrFwdRefs - These are blockaddr references to basic blocks. These
/// are resolved lazily when functions are loaded.
@@ -171,7 +173,8 @@ class BitcodeReader : public ModuleProvider {
public:
explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C)
- : Context(C), Buffer(buffer), ErrorString(0), ValueList(C), MDValueList(C) {
+ : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false),
+ ErrorString(0), ValueList(C), MDValueList(C) {
HasReversedFunctionsWithBodies = false;
}
~BitcodeReader() {
@@ -180,17 +183,15 @@ public:
void FreeState();
- /// releaseMemoryBuffer - This causes the reader to completely forget about
- /// the memory buffer it contains, which prevents the buffer from being
- /// destroyed when it is deleted.
- void releaseMemoryBuffer() {
- Buffer = 0;
- }
+ /// setBufferOwned - If this is true, the reader will destroy the MemoryBuffer
+ /// when the reader is destroyed.
+ void setBufferOwned(bool Owned) { BufferOwned = Owned; }
- virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0);
- virtual Module *materializeModule(std::string *ErrInfo = 0);
- virtual void dematerializeFunction(Function *F);
- virtual Module *releaseModule(std::string *ErrInfo = 0);
+ virtual bool isMaterializable(const GlobalValue *GV) const;
+ virtual bool isDematerializable(const GlobalValue *GV) const;
+ virtual bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0);
+ virtual bool MaterializeModule(Module *M, std::string *ErrInfo = 0);
+ virtual void Dematerialize(GlobalValue *GV);
bool Error(const char *Str) {
ErrorString = Str;
@@ -200,7 +201,7 @@ public:
/// @brief Main interface to parsing a bitcode buffer.
/// @returns true if an error occurred.
- bool ParseBitcode();
+ bool ParseBitcodeInto(Module *M);
private:
const Type *getTypeByID(unsigned ID, bool isTypeTable = false);
Value *getFnValueByID(unsigned ID, const Type *Ty) {
@@ -248,7 +249,7 @@ private:
}
- bool ParseModule(const std::string &ModuleID);
+ bool ParseModule();
bool ParseAttributeBlock();
bool ParseTypeTable();
bool ParseTypeSymbolTable();
diff --git a/lib/Bitcode/Reader/Makefile b/lib/Bitcode/Reader/Makefile
index 0aae3bf..59af8d53 100644
--- a/lib/Bitcode/Reader/Makefile
+++ b/lib/Bitcode/Reader/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMBitReader
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 5a4a1b2..82e73b5 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -181,6 +181,14 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Log2_32_Ceil(VE.getTypes().size()+1)));
unsigned StructAbbrev = Stream.EmitAbbrev(Abbv);
+ // Abbrev for TYPE_CODE_UNION.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_UNION));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+ Log2_32_Ceil(VE.getTypes().size()+1)));
+ unsigned UnionAbbrev = Stream.EmitAbbrev(Abbv);
+
// Abbrev for TYPE_CODE_ARRAY.
Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
@@ -250,6 +258,17 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
AbbrevToUse = StructAbbrev;
break;
}
+ case Type::UnionTyID: {
+ const UnionType *UT = cast<UnionType>(T);
+ // UNION: [eltty x N]
+ Code = bitc::TYPE_CODE_UNION;
+ // Output all of the element types.
+ for (UnionType::element_iterator I = UT->element_begin(),
+ E = UT->element_end(); I != E; ++I)
+ TypeVals.push_back(VE.getTypeID(*I));
+ AbbrevToUse = UnionAbbrev;
+ break;
+ }
case Type::ArrayTyID: {
const ArrayType *AT = cast<ArrayType>(T);
// ARRAY: [numelts, eltty]
@@ -280,7 +299,6 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
static unsigned getEncodedLinkage(const GlobalValue *GV) {
switch (GV->getLinkage()) {
default: llvm_unreachable("Invalid linkage!");
- case GlobalValue::GhostLinkage: // Map ghost linkage onto external.
case GlobalValue::ExternalLinkage: return 0;
case GlobalValue::WeakAnyLinkage: return 1;
case GlobalValue::AppendingLinkage: return 2;
@@ -499,7 +517,7 @@ static void WriteModuleMetadata(const ValueEnumerator &VE,
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) {
- if (!N->isFunctionLocal()) {
+ if (!N->isFunctionLocal() || !N->getFunction()) {
if (!StartedMetadataBlock) {
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
StartedMetadataBlock = true;
@@ -563,7 +581,7 @@ static void WriteFunctionLocalMetadata(const Function &F,
for (unsigned i = 0, e = Vals.size(); i != e; ++i)
if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first))
- if (N->getFunction() == &F) {
+ if (N->isFunctionLocal() && N->getFunction() == &F) {
if (!StartedMetadataBlock) {
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
StartedMetadataBlock = true;
@@ -790,7 +808,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
else if (isCStr7)
AbbrevToUse = CString7Abbrev;
} else if (isa<ConstantArray>(C) || isa<ConstantStruct>(V) ||
- isa<ConstantVector>(V)) {
+ isa<ConstantUnion>(C) || isa<ConstantVector>(V)) {
Code = bitc::CST_CODE_AGGREGATE;
for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
Record.push_back(VE.getValueID(C->getOperand(i)));
@@ -1511,16 +1529,50 @@ enum {
DarwinBCHeaderSize = 5*4
};
+/// isARMTriplet - Return true if the triplet looks like:
+/// arm-*, thumb-*, armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*.
+static bool isARMTriplet(const std::string &TT) {
+ size_t Pos = 0;
+ size_t Size = TT.size();
+ if (Size >= 6 &&
+ TT[0] == 't' && TT[1] == 'h' && TT[2] == 'u' &&
+ TT[3] == 'm' && TT[4] == 'b')
+ Pos = 5;
+ else if (Size >= 4 && TT[0] == 'a' && TT[1] == 'r' && TT[2] == 'm')
+ Pos = 3;
+ else
+ return false;
+
+ if (TT[Pos] == '-')
+ return true;
+ else if (TT[Pos] == 'v') {
+ if (Size >= Pos+4 &&
+ TT[Pos+1] == '6' && TT[Pos+2] == 't' && TT[Pos+3] == '2')
+ return true;
+ else if (Size >= Pos+4 &&
+ TT[Pos+1] == '5' && TT[Pos+2] == 't' && TT[Pos+3] == 'e')
+ return true;
+ } else
+ return false;
+ while (++Pos < Size && TT[Pos] != '-') {
+ if (!isdigit(TT[Pos]))
+ return false;
+ }
+ return true;
+}
+
static void EmitDarwinBCHeader(BitstreamWriter &Stream,
const std::string &TT) {
unsigned CPUType = ~0U;
- // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*. The CPUType is a
- // magic number from /usr/include/mach/machine.h. It is ok to reproduce the
+ // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*,
+ // armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*. The CPUType is a magic
+ // number from /usr/include/mach/machine.h. It is ok to reproduce the
// specific constants here because they are implicitly part of the Darwin ABI.
enum {
DARWIN_CPU_ARCH_ABI64 = 0x01000000,
DARWIN_CPU_TYPE_X86 = 7,
+ DARWIN_CPU_TYPE_ARM = 12,
DARWIN_CPU_TYPE_POWERPC = 18
};
@@ -1533,6 +1585,8 @@ static void EmitDarwinBCHeader(BitstreamWriter &Stream,
CPUType = DARWIN_CPU_TYPE_POWERPC;
else if (TT.find("powerpc64-") == 0)
CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64;
+ else if (isARMTriplet(TT))
+ CPUType = DARWIN_CPU_TYPE_ARM;
// Traditional Bitcode starts after header.
unsigned BCOffset = DarwinBCHeaderSize;
diff --git a/lib/Bitcode/Writer/Makefile b/lib/Bitcode/Writer/Makefile
index 5f9742e..7b0bd72 100644
--- a/lib/Bitcode/Writer/Makefile
+++ b/lib/Bitcode/Writer/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMBitWriter
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index c46d735..595497f 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -93,7 +93,7 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
OI != E; ++OI) {
if (MDNode *MD = dyn_cast<MDNode>(*OI))
- if (MD->isFunctionLocal())
+ if (MD->isFunctionLocal() && MD->getFunction())
// These will get enumerated during function-incorporation.
continue;
EnumerateOperandType(*OI);
@@ -408,21 +408,25 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
FirstInstID = Values.size();
+ SmallVector<MDNode *, 8> FunctionLocalMDs;
// Add all of the instructions.
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
OI != E; ++OI) {
if (MDNode *MD = dyn_cast<MDNode>(*OI))
- if (!MD->isFunctionLocal())
- // These were already enumerated during ValueEnumerator creation.
- continue;
- EnumerateOperandType(*OI);
+ if (MD->isFunctionLocal() && MD->getFunction())
+ // Enumerate metadata after the instructions they might refer to.
+ FunctionLocalMDs.push_back(MD);
}
if (!I->getType()->isVoidTy())
EnumerateValue(I);
}
}
+
+ // Add all of the function-local metadata.
+ for (unsigned i = 0, e = FunctionLocalMDs.size(); i != e; ++i)
+ EnumerateOperandType(FunctionLocalMDs[i]);
}
void ValueEnumerator::purgeFunction() {
diff --git a/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/lib/CodeGen/AggressiveAntiDepBreaker.cpp
index ca1f4a3..8840622f 100644
--- a/lib/CodeGen/AggressiveAntiDepBreaker.cpp
+++ b/lib/CodeGen/AggressiveAntiDepBreaker.cpp
@@ -425,8 +425,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI,
unsigned Reg = MO.getReg();
if (Reg == 0) continue;
// Ignore KILLs and passthru registers for liveness...
- if ((MI->getOpcode() == TargetInstrInfo::KILL) ||
- (PassthruRegs.count(Reg) != 0))
+ if (MI->isKill() || (PassthruRegs.count(Reg) != 0))
continue;
// Update def for Reg and aliases.
@@ -481,7 +480,7 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
// Form a group of all defs and uses of a KILL instruction to ensure
// that all registers are renamed as a group.
- if (MI->getOpcode() == TargetInstrInfo::KILL) {
+ if (MI->isKill()) {
DEBUG(dbgs() << "\tKill Group:");
unsigned FirstReg = 0;
@@ -792,7 +791,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
// Ignore KILL instructions (they form a group in ScanInstruction
// but don't cause any anti-dependence breaking themselves)
- if (MI->getOpcode() != TargetInstrInfo::KILL) {
+ if (!MI->isKill()) {
// Attempt to break each anti-dependency...
for (unsigned i = 0, e = Edges.size(); i != e; ++i) {
SDep *Edge = Edges[i];
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index f4d8864..fc08384 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "asm-printer"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/DerivedTypes.h"
@@ -24,6 +25,7 @@
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
@@ -31,10 +33,6 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/FormattedStream.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
@@ -45,37 +43,27 @@
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/FormattedStream.h"
#include <cerrno>
using namespace llvm;
-static cl::opt<cl::boolOrDefault>
-AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
- cl::init(cl::BOU_UNSET));
-
-static bool getVerboseAsm(bool VDef) {
- switch (AsmVerbose) {
- default:
- case cl::BOU_UNSET: return VDef;
- case cl::BOU_TRUE: return true;
- case cl::BOU_FALSE: return false;
- }
-}
+STATISTIC(EmittedInsts, "Number of machine instrs printed");
char AsmPrinter::ID = 0;
AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
- const MCAsmInfo *T, bool VDef)
- : MachineFunctionPass(&ID), FunctionNumber(0), O(o),
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+ : MachineFunctionPass(&ID), O(o),
TM(tm), MAI(T), TRI(tm.getRegisterInfo()),
-
- OutContext(*new MCContext()),
- // FIXME: Pass instprinter to streamer.
- OutStreamer(*createAsmStreamer(OutContext, O, *T,
- TM.getTargetData()->isLittleEndian(),
- getVerboseAsm(VDef), 0)),
-
+ OutContext(Ctx), OutStreamer(Streamer),
LastMI(0), LastFn(0), Counter(~0U), PrevDLT(NULL) {
DW = 0; MMI = 0;
- VerboseAsm = getVerboseAsm(VDef);
+ VerboseAsm = Streamer.isVerboseAsm();
}
AsmPrinter::~AsmPrinter() {
@@ -87,6 +75,12 @@ AsmPrinter::~AsmPrinter() {
delete &OutContext;
}
+/// getFunctionNumber - Return a unique ID for the current function.
+///
+unsigned AsmPrinter::getFunctionNumber() const {
+ return MF->getFunctionNumber();
+}
+
TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const {
return TM.getTargetLowering()->getObjFileLowering();
}
@@ -115,11 +109,11 @@ bool AsmPrinter::doInitialization(Module &M) {
// Allow the target to emit any magic that it wants at the start of the file.
EmitStartOfAsmFile(M);
+ // Very minimal debug info. It is ignored if we emit actual debug info. If we
+ // don't, this at least helps the user find where a global came from.
if (MAI->hasSingleParameterDotFile()) {
- // Very minimal debug info. It is ignored if we emit actual
- // debug info. If we don't, this at least helps the user find where
- // a function came from.
- O << "\t.file\t\"" << M.getModuleIdentifier() << "\"\n";
+ // .file "foo.c"
+ OutStreamer.EmitFileDirective(M.getModuleIdentifier());
}
GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
@@ -144,6 +138,52 @@ bool AsmPrinter::doInitialization(Module &M) {
return false;
}
+void AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const {
+ switch ((GlobalValue::LinkageTypes)Linkage) {
+ case GlobalValue::CommonLinkage:
+ case GlobalValue::LinkOnceAnyLinkage:
+ case GlobalValue::LinkOnceODRLinkage:
+ case GlobalValue::WeakAnyLinkage:
+ case GlobalValue::WeakODRLinkage:
+ case GlobalValue::LinkerPrivateLinkage:
+ if (MAI->getWeakDefDirective() != 0) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
+ // .weak_definition _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition);
+ } else if (const char *LinkOnce = MAI->getLinkOnceDirective()) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
+ // FIXME: linkonce should be a section attribute, handled by COFF Section
+ // assignment.
+ // http://sourceware.org/binutils/docs-2.20/as/Linkonce.html#Linkonce
+ // .linkonce discard
+ // FIXME: It would be nice to use .linkonce samesize for non-common
+ // globals.
+ O << LinkOnce;
+ } else {
+ // .weak _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
+ }
+ 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.
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
+ break;
+ case GlobalValue::PrivateLinkage:
+ case GlobalValue::InternalLinkage:
+ break;
+ default:
+ llvm_unreachable("Unknown linkage type!");
+ }
+}
+
+
/// EmitGlobalVariable - Emit the specified global variable to the .s file.
void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
if (!GV->hasInitializer()) // External globals require no code.
@@ -154,15 +194,10 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
return;
MCSymbol *GVSym = GetGlobalValueSymbol(GV);
- printVisibility(GVSym, GV->getVisibility());
+ EmitVisibility(GVSym, GV->getVisibility());
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type\t" << *GVSym;
- if (MAI->getCommentString()[0] != '@')
- O << ",@object\n";
- else
- O << ",%object\n";
- }
+ if (MAI->hasDotTypeDotSizeDirective())
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
@@ -224,47 +259,9 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
OutStreamer.SwitchSection(TheSection);
- // TODO: Factor into an 'emit linkage' thing that is shared with function
- // bodies.
- switch (GV->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- if (MAI->getWeakDefDirective() != 0) {
- // .globl _foo
- OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
- // .weak_definition _foo
- OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition);
- } else if (const char *LinkOnce = MAI->getLinkOnceDirective()) {
- // .globl _foo
- OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
- // .linkonce same_size
- O << LinkOnce;
- } else {
- // .weak _foo
- OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
- }
- 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.
- // .globl _foo
- OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
- break;
- case GlobalValue::PrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
+ EmitLinkage(GV->getLinkage(), GVSym);
EmitAlignment(AlignLog, GV);
+
if (VerboseAsm) {
WriteAsOperand(OutStreamer.GetCommentOS(), GV,
/*PrintType=*/false, GV->getParent());
@@ -275,7 +272,185 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
EmitGlobalConstant(GV->getInitializer());
if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << *GVSym << ", " << Size << '\n';
+ // .size foo, 42
+ OutStreamer.EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext));
+
+ OutStreamer.AddBlankLine();
+}
+
+/// EmitFunctionHeader - This method emits the header for the current
+/// function.
+void AsmPrinter::EmitFunctionHeader() {
+ // Print out constants referenced by the function
+ EmitConstantPool();
+
+ // Print the 'header' of function.
+ const Function *F = MF->getFunction();
+
+ OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
+ EmitVisibility(CurrentFnSym, F->getVisibility());
+
+ EmitLinkage(F->getLinkage(), CurrentFnSym);
+ EmitAlignment(MF->getAlignment(), F);
+
+ if (MAI->hasDotTypeDotSizeDirective())
+ OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
+
+ if (VerboseAsm) {
+ WriteAsOperand(OutStreamer.GetCommentOS(), F,
+ /*PrintType=*/false, F->getParent());
+ OutStreamer.GetCommentOS() << '\n';
+ }
+
+ // Emit the CurrentFnSym. This is a virtual function to allow targets to
+ // do their wild and crazy things as required.
+ EmitFunctionEntryLabel();
+
+ // Add some workaround for linkonce linkage on Cygwin\MinGW.
+ if (MAI->getLinkOnceDirective() != 0 &&
+ (F->hasLinkOnceLinkage() || F->hasWeakLinkage()))
+ // FIXME: What is this?
+ O << "Lllvm$workaround$fake$stub$" << *CurrentFnSym << ":\n";
+
+ // Emit pre-function debug and/or EH information.
+ if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
+ DW->BeginFunction(MF);
+}
+
+/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
+/// function. This can be overridden by targets as required to do custom stuff.
+void AsmPrinter::EmitFunctionEntryLabel() {
+ OutStreamer.EmitLabel(CurrentFnSym);
+}
+
+
+/// EmitComments - Pretty-print comments for instructions.
+static void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) {
+ const MachineFunction *MF = MI.getParent()->getParent();
+ const TargetMachine &TM = MF->getTarget();
+
+ if (!MI.getDebugLoc().isUnknown()) {
+ DILocation DLT = MF->getDILocation(MI.getDebugLoc());
+
+ // Print source line info.
+ DIScope Scope = DLT.getScope();
+ // Omit the directory, because it's likely to be long and uninteresting.
+ if (!Scope.isNull())
+ CommentOS << Scope.getFilename();
+ else
+ CommentOS << "<unknown>";
+ CommentOS << ':' << DLT.getLineNumber();
+ if (DLT.getColumnNumber() != 0)
+ CommentOS << ':' << DLT.getColumnNumber();
+ CommentOS << '\n';
+ }
+
+ // Check for spills and reloads
+ int FI;
+
+ const MachineFrameInfo *FrameInfo = MF->getFrameInfo();
+
+ // We assume a single instruction only has a spill or reload, not
+ // both.
+ const MachineMemOperand *MMO;
+ if (TM.getInstrInfo()->isLoadFromStackSlotPostFE(&MI, FI)) {
+ if (FrameInfo->isSpillSlotObjectIndex(FI)) {
+ MMO = *MI.memoperands_begin();
+ CommentOS << MMO->getSize() << "-byte Reload\n";
+ }
+ } else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, MMO, FI)) {
+ if (FrameInfo->isSpillSlotObjectIndex(FI))
+ CommentOS << MMO->getSize() << "-byte Folded Reload\n";
+ } else if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&MI, FI)) {
+ if (FrameInfo->isSpillSlotObjectIndex(FI)) {
+ MMO = *MI.memoperands_begin();
+ CommentOS << MMO->getSize() << "-byte Spill\n";
+ }
+ } else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, MMO, FI)) {
+ if (FrameInfo->isSpillSlotObjectIndex(FI))
+ CommentOS << MMO->getSize() << "-byte Folded Spill\n";
+ }
+
+ // Check for spill-induced copies
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (TM.getInstrInfo()->isMoveInstr(MI, SrcReg, DstReg,
+ SrcSubIdx, DstSubIdx)) {
+ if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse))
+ CommentOS << " Reload Reuse\n";
+ }
+}
+
+
+
+/// EmitFunctionBody - This method emits the body and trailer for a
+/// function.
+void AsmPrinter::EmitFunctionBody() {
+ // Emit target-specific gunk before the function body.
+ EmitFunctionBodyStart();
+
+ // 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.
+ EmitBasicBlockStart(I);
+ for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
+ II != IE; ++II) {
+ // Print the assembly for the instruction.
+ if (!II->isLabel())
+ HasAnyRealCode = true;
+
+ ++EmittedInsts;
+
+ // FIXME: Clean up processDebugLoc.
+ processDebugLoc(II, true);
+
+ if (VerboseAsm)
+ EmitComments(*II, OutStreamer.GetCommentOS());
+
+ switch (II->getOpcode()) {
+ case TargetOpcode::DBG_LABEL:
+ case TargetOpcode::EH_LABEL:
+ case TargetOpcode::GC_LABEL:
+ printLabelInst(II);
+ break;
+ case TargetOpcode::INLINEASM:
+ printInlineAsm(II);
+ break;
+ case TargetOpcode::IMPLICIT_DEF:
+ printImplicitDef(II);
+ break;
+ case TargetOpcode::KILL:
+ printKill(II);
+ break;
+ default:
+ EmitInstruction(II);
+ break;
+ }
+
+ // FIXME: Clean up processDebugLoc.
+ processDebugLoc(II, false);
+ }
+ }
+
+ // If the function is empty and the object file uses .subsections_via_symbols,
+ // then we need to emit *something* to the function body to prevent the
+ // labels from collapsing together. Just emit a 0 byte.
+ if (MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode)
+ OutStreamer.EmitIntValue(0, 1, 0/*addrspace*/);
+
+ // Emit target-specific gunk after the function body.
+ EmitFunctionBodyEnd();
+
+ if (MAI->hasDotTypeDotSizeDirective())
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
+
+ // Emit post-function debug information.
+ if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
+ DW->EndFunction(MF);
+
+ // Print out jump tables referenced by the function.
+ EmitJumpTableInfo();
OutStreamer.AddBlankLine();
}
@@ -313,7 +488,7 @@ bool AsmPrinter::doFinalization(Module &M) {
}
}
- if (MAI->getSetDirective()) {
+ if (MAI->hasSetDirective()) {
OutStreamer.AddBlankLine();
for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
I != E; ++I) {
@@ -329,9 +504,11 @@ bool AsmPrinter::doFinalization(Module &M) {
else
assert(I->hasLocalLinkage() && "Invalid alias linkage");
- printVisibility(Name, I->getVisibility());
+ EmitVisibility(Name, I->getVisibility());
- O << MAI->getSetDirective() << ' ' << *Name << ", " << *Target << '\n';
+ // Emit the directives as assignments aka .set:
+ OutStreamer.EmitAssignment(Name,
+ MCSymbolRefExpr::Create(Target, OutContext));
}
}
@@ -360,9 +537,9 @@ bool AsmPrinter::doFinalization(Module &M) {
}
void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
+ this->MF = &MF;
// Get the function symbol.
CurrentFnSym = GetGlobalValueSymbol(MF.getFunction());
- IncrementFunctionNumber();
if (VerboseAsm)
LI = &getAnalysis<MachineLoopInfo>();
@@ -383,7 +560,8 @@ namespace {
/// used to print out constants which have been "spilled to memory" by
/// the code generator.
///
-void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) {
+void AsmPrinter::EmitConstantPool() {
+ const MachineConstantPool *MCP = MF->getConstantPool();
const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
if (CP.empty()) return;
@@ -470,27 +648,26 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) {
/// EmitJumpTableInfo - Print assembly representations of the jump tables used
/// by the current function to the current output stream.
///
-void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI,
- MachineFunction &MF) {
+void AsmPrinter::EmitJumpTableInfo() {
+ const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+ if (MJTI == 0) return;
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
if (JT.empty()) return;
- bool IsPic = TM.getRelocationModel() == Reloc::PIC_;
-
// Pick the directive to use to print the jump table entries, and switch to
// the appropriate section.
- TargetLowering *LoweringInfo = TM.getTargetLowering();
-
- const Function *F = MF.getFunction();
+ const Function *F = MF->getFunction();
bool JTInDiffSection = false;
- if (F->isWeakForLinker() ||
- (IsPic && !LoweringInfo->usesGlobalOffsetTable())) {
- // In PIC mode, we need to emit the jump table to the same section as the
- // function body itself, otherwise the label differences won't make sense.
- // We should also do if the section name is NULL or function is declared in
- // discardable section.
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang,
- TM));
+ if (// In PIC mode, we need to emit the jump table to the same section as the
+ // function body itself, otherwise the label differences won't make sense.
+ // FIXME: Need a better predicate for this: what about custom entries?
+ MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
+ // We should also do if the section name is NULL or function is declared
+ // in discardable section
+ // FIXME: this isn't the right predicate, should be based on the MCSection
+ // for the function.
+ F->isWeakForLinker()) {
+ OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F,Mang,TM));
} else {
// Otherwise, drop it in the readonly section.
const MCSection *ReadOnlySection =
@@ -498,73 +675,106 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI,
OutStreamer.SwitchSection(ReadOnlySection);
JTInDiffSection = true;
}
+
+ EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData())));
- EmitAlignment(Log2_32(MJTI->getAlignment()));
-
- for (unsigned i = 0, e = JT.size(); i != e; ++i) {
- const std::vector<MachineBasicBlock*> &JTBBs = JT[i].MBBs;
+ for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
+ const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
// If this jump table was deleted, ignore it.
if (JTBBs.empty()) continue;
- // For PIC codegen, if possible we want to use the SetDirective to reduce
- // the number of relocations the assembler will generate for the jump table.
- // Set directives are all printed before the jump table itself.
- SmallPtrSet<MachineBasicBlock*, 16> EmittedSets;
- if (MAI->getSetDirective() && IsPic)
- for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii)
- if (EmittedSets.insert(JTBBs[ii]))
- printPICJumpTableSetLabel(i, JTBBs[ii]);
+ // For the EK_LabelDifference32 entry, if the target supports .set, emit a
+ // .set directive for each unique entry. This reduces the number of
+ // relocations the assembler will generate for the jump table.
+ if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 &&
+ MAI->hasSetDirective()) {
+ SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets;
+ const TargetLowering *TLI = TM.getTargetLowering();
+ const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext);
+ for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) {
+ const MachineBasicBlock *MBB = JTBBs[ii];
+ if (!EmittedSets.insert(MBB)) continue;
+
+ // .set LJTSet, LBB32-base
+ const MCExpr *LHS =
+ MCSymbolRefExpr::Create(MBB->getSymbol(OutContext), OutContext);
+ OutStreamer.EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()),
+ MCBinaryExpr::CreateSub(LHS, Base, OutContext));
+ }
+ }
// On some targets (e.g. Darwin) we want to emit two consequtive labels
// before each jump table. The first label is never referenced, but tells
// the assembler and linker the extents of the jump table object. The
// second label is actually referenced by the code.
if (JTInDiffSection && MAI->getLinkerPrivateGlobalPrefix()[0])
- OutStreamer.EmitLabel(GetJTISymbol(i, true));
+ // FIXME: This doesn't have to have any specific name, just any randomly
+ // named and numbered 'l' label would work. Simplify GetJTISymbol.
+ OutStreamer.EmitLabel(GetJTISymbol(JTI, true));
- OutStreamer.EmitLabel(GetJTISymbol(i));
+ OutStreamer.EmitLabel(GetJTISymbol(JTI));
- for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) {
- printPICJumpTableEntry(MJTI, JTBBs[ii], i);
- O << '\n';
- }
+ for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii)
+ EmitJumpTableEntry(MJTI, JTBBs[ii], JTI);
}
}
-void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
- const MachineBasicBlock *MBB,
- unsigned uid) const {
- bool isPIC = TM.getRelocationModel() == Reloc::PIC_;
-
- // Use JumpTableDirective otherwise honor the entry size from the jump table
- // info.
- const char *JTEntryDirective = MAI->getJumpTableDirective(isPIC);
- bool HadJTEntryDirective = JTEntryDirective != NULL;
- if (!HadJTEntryDirective) {
- JTEntryDirective = MJTI->getEntrySize() == 4 ?
- MAI->getData32bitsDirective() : MAI->getData64bitsDirective();
+/// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the
+/// current stream.
+void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
+ const MachineBasicBlock *MBB,
+ unsigned UID) const {
+ const MCExpr *Value = 0;
+ switch (MJTI->getEntryKind()) {
+ case MachineJumpTableInfo::EK_Custom32:
+ Value = TM.getTargetLowering()->LowerCustomJumpTableEntry(MJTI, MBB, UID,
+ OutContext);
+ break;
+ case MachineJumpTableInfo::EK_BlockAddress:
+ // EK_BlockAddress - Each entry is a plain address of block, e.g.:
+ // .word LBB123
+ Value = MCSymbolRefExpr::Create(MBB->getSymbol(OutContext), OutContext);
+ break;
+ case MachineJumpTableInfo::EK_GPRel32BlockAddress: {
+ // EK_GPRel32BlockAddress - Each entry is an address of block, encoded
+ // with a relocation as gp-relative, e.g.:
+ // .gprel32 LBB123
+ MCSymbol *MBBSym = MBB->getSymbol(OutContext);
+ OutStreamer.EmitGPRel32Value(MCSymbolRefExpr::Create(MBBSym, OutContext));
+ return;
}
- O << JTEntryDirective << ' ';
-
- // If we have emitted set directives for the jump table entries, print
- // them rather than the entries themselves. If we're emitting PIC, then
- // emit the table entries as differences between two text section labels.
- // If we're emitting non-PIC code, then emit the entries as direct
- // references to the target basic blocks.
- if (!isPIC) {
- O << *GetMBBSymbol(MBB->getNumber());
- } else if (MAI->getSetDirective()) {
- O << MAI->getPrivateGlobalPrefix() << getFunctionNumber()
- << '_' << uid << "_set_" << MBB->getNumber();
- } else {
- O << *GetMBBSymbol(MBB->getNumber());
- // If the arch uses custom Jump Table directives, don't calc relative to
- // JT.
- if (!HadJTEntryDirective)
- O << '-' << *GetJTISymbol(uid);
+ case MachineJumpTableInfo::EK_LabelDifference32: {
+ // EK_LabelDifference32 - Each entry is the address of the block minus
+ // the address of the jump table. This is used for PIC jump tables where
+ // gprel32 is not supported. e.g.:
+ // .word LBB123 - LJTI1_2
+ // If the .set directive is supported, this is emitted as:
+ // .set L4_5_set_123, LBB123 - LJTI1_2
+ // .word L4_5_set_123
+
+ // If we have emitted set directives for the jump table entries, print
+ // them rather than the entries themselves. If we're emitting PIC, then
+ // emit the table entries as differences between two text section labels.
+ if (MAI->hasSetDirective()) {
+ // If we used .set, reference the .set's symbol.
+ Value = MCSymbolRefExpr::Create(GetJTSetSymbol(UID, MBB->getNumber()),
+ OutContext);
+ break;
+ }
+ // Otherwise, use the difference as the jump table entry.
+ Value = MCSymbolRefExpr::Create(MBB->getSymbol(OutContext), OutContext);
+ const MCExpr *JTI = MCSymbolRefExpr::Create(GetJTISymbol(UID), OutContext);
+ Value = MCBinaryExpr::CreateSub(Value, JTI, OutContext);
+ break;
+ }
}
+
+ assert(Value && "Unknown entry kind!");
+
+ unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData());
+ OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0);
}
@@ -683,48 +893,6 @@ void AsmPrinter::EmitInt64(uint64_t Value) const {
OutStreamer.EmitIntValue(Value, 8, 0/*addrspace*/);
}
-
-/// toOctal - Convert the low order bits of X into an octal digit.
-///
-static inline char toOctal(int X) {
- return (X&7)+'0';
-}
-
-/// printStringChar - Print a char, escaped if necessary.
-///
-static void printStringChar(formatted_raw_ostream &O, unsigned char C) {
- if (C == '"') {
- O << "\\\"";
- } else if (C == '\\') {
- O << "\\\\";
- } else if (isprint((unsigned char)C)) {
- O << C;
- } else {
- switch(C) {
- case '\b': O << "\\b"; break;
- case '\f': O << "\\f"; break;
- case '\n': O << "\\n"; break;
- case '\r': O << "\\r"; break;
- case '\t': O << "\\t"; break;
- default:
- O << '\\';
- O << toOctal(C >> 6);
- O << toOctal(C >> 3);
- O << toOctal(C >> 0);
- break;
- }
- }
-}
-
-/// EmitFile - Emit a .file directive.
-void AsmPrinter::EmitFile(unsigned Number, StringRef Name) const {
- O << "\t.file\t" << Number << " \"";
- for (unsigned i = 0, N = Name.size(); i < N; ++i)
- printStringChar(O, Name[i]);
- O << '\"';
-}
-
-
//===----------------------------------------------------------------------===//
// EmitAlignment - Emit an alignment directive to the specified power of
@@ -779,15 +947,18 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) {
}
switch (CE->getOpcode()) {
- case Instruction::ZExt:
- case Instruction::SExt:
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::UIToFP:
- case Instruction::SIToFP:
- case Instruction::FPToUI:
- case Instruction::FPToSI:
- default: llvm_unreachable("FIXME: Don't support this constant cast expr");
+ default:
+ // If the code isn't optimized, there may be outstanding folding
+ // opportunities. Attempt to fold the expression using TargetData as a
+ // last resort before giving up.
+ if (Constant *C =
+ ConstantFoldConstantExpression(CE, AP.TM.getTargetData()))
+ if (C != CE)
+ return LowerConstant(C, AP);
+#ifndef NDEBUG
+ CE->dump();
+#endif
+ llvm_unreachable("FIXME: Don't support this constant expr");
case Instruction::GetElementPtr: {
const TargetData &TD = *AP.TM.getTargetData();
// Generate a symbolic expression for the byte address
@@ -851,8 +1022,14 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) {
return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx);
}
+ // The MC library also has a right-shift operator, but it isn't consistently
+ // signed or unsigned between different targets.
case Instruction::Add:
case Instruction::Sub:
+ case Instruction::Mul:
+ case Instruction::SDiv:
+ case Instruction::SRem:
+ case Instruction::Shl:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor: {
@@ -862,6 +1039,10 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) {
default: llvm_unreachable("Unknown binary operator constant cast expr");
case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx);
case Instruction::Sub: return MCBinaryExpr::CreateSub(LHS, RHS, Ctx);
+ case Instruction::Mul: return MCBinaryExpr::CreateMul(LHS, RHS, Ctx);
+ case Instruction::SDiv: return MCBinaryExpr::CreateDiv(LHS, RHS, Ctx);
+ case Instruction::SRem: return MCBinaryExpr::CreateMod(LHS, RHS, Ctx);
+ case Instruction::Shl: return MCBinaryExpr::CreateShl(LHS, RHS, Ctx);
case Instruction::And: return MCBinaryExpr::CreateAnd(LHS, RHS, Ctx);
case Instruction::Or: return MCBinaryExpr::CreateOr (LHS, RHS, Ctx);
case Instruction::Xor: return MCBinaryExpr::CreateXor(LHS, RHS, Ctx);
@@ -1012,6 +1193,7 @@ static void EmitGlobalConstantLargeInt(const ConstantInt *CI,
void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) {
uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
+ if (Size == 0) Size = 1; // An empty "_foo:" followed by a section is undef.
return OutStreamer.EmitZeros(Size, AddrSpace);
}
@@ -1295,7 +1477,7 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
++OpNo; // Skip over the ID number.
if (Modifier[0] == 'l') // labels are target independent
- O << *GetMBBSymbol(MI->getOperand(OpNo).getMBB()->getNumber());
+ O << *MI->getOperand(OpNo).getMBB()->getSymbol(OutContext);
else {
AsmPrinter *AP = const_cast<AsmPrinter*>(this);
if ((OpFlags & 7) == 4) {
@@ -1320,6 +1502,7 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
}
}
O << "\n\t" << MAI->getCommentString() << MAI->getInlineAsmEnd();
+ OutStreamer.AddBlankLine();
}
/// printImplicitDef - This method prints the specified machine instruction
@@ -1329,6 +1512,7 @@ void AsmPrinter::printImplicitDef(const MachineInstr *MI) const {
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << " implicit-def: "
<< TRI->getName(MI->getOperand(0).getReg());
+ OutStreamer.AddBlankLine();
}
void AsmPrinter::printKill(const MachineInstr *MI) const {
@@ -1340,12 +1524,14 @@ void AsmPrinter::printKill(const MachineInstr *MI) const {
assert(op.isReg() && "KILL instruction must have only register operands");
O << ' ' << TRI->getName(op.getReg()) << (op.isDef() ? "<def>" : "<kill>");
}
+ OutStreamer.AddBlankLine();
}
/// printLabel - This method prints a local label used by debug and
/// exception handling tables.
-void AsmPrinter::printLabel(const MachineInstr *MI) const {
+void AsmPrinter::printLabelInst(const MachineInstr *MI) const {
printLabel(MI->getOperand(0).getImm());
+ OutStreamer.AddBlankLine();
}
void AsmPrinter::printLabel(unsigned Id) const {
@@ -1368,14 +1554,12 @@ bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
return true;
}
-MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA,
- const char *Suffix) const {
- return GetBlockAddressSymbol(BA->getFunction(), BA->getBasicBlock(), Suffix);
+MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {
+ return GetBlockAddressSymbol(BA->getFunction(), BA->getBasicBlock());
}
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F,
- const BasicBlock *BB,
- const char *Suffix) const {
+ const BasicBlock *BB) const {
assert(BB->hasName() &&
"Address of anonymous basic block not supported yet!");
@@ -1389,19 +1573,12 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F,
SmallString<60> NameResult;
Mang->getNameWithPrefix(NameResult,
StringRef("BA") + Twine((unsigned)FnName.size()) +
- "_" + FnName.str() + "_" + BB->getName() + Suffix,
+ "_" + FnName.str() + "_" + BB->getName(),
Mangler::Private);
return OutContext.GetOrCreateSymbol(NameResult.str());
}
-MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const {
- SmallString<60> Name;
- raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BB"
- << getFunctionNumber() << '_' << MBBID;
- return OutContext.GetOrCreateSymbol(Name.str());
-}
-
/// GetCPISymbol - Return the symbol for the specified constant pool entry.
MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
SmallString<60> Name;
@@ -1412,11 +1589,15 @@ MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
/// GetJTISymbol - Return the symbol for the specified jump table entry.
MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const {
- const char *Prefix = isLinkerPrivate ? MAI->getLinkerPrivateGlobalPrefix() :
- MAI->getPrivateGlobalPrefix();
+ return MF->getJTISymbol(JTID, OutContext, isLinkerPrivate);
+}
+
+/// GetJTSetSymbol - Return the symbol for the specified jump table .set
+/// FIXME: privatize to AsmPrinter.
+MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const {
SmallString<60> Name;
- raw_svector_ostream(Name) << Prefix << "JTI" << getFunctionNumber() << '_'
- << JTID;
+ raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
+ << getFunctionNumber() << '_' << UID << "_set_" << MBBID;
return OutContext.GetOrCreateSymbol(Name.str());
}
@@ -1476,7 +1657,7 @@ static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop,
}
}
-/// EmitComments - Pretty-print comments for basic blocks.
+/// PrintBasicBlockLoopComments - Pretty-print comments for basic blocks.
static void PrintBasicBlockLoopComments(const MachineBasicBlock &MBB,
const MachineLoopInfo *LI,
const AsmPrinter &AP) {
@@ -1555,37 +1736,11 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
PrintBasicBlockLoopComments(*MBB, LI, *this);
}
- OutStreamer.EmitLabel(GetMBBSymbol(MBB->getNumber()));
+ OutStreamer.EmitLabel(MBB->getSymbol(OutContext));
}
}
-/// printPICJumpTableSetLabel - This method prints a set label for the
-/// specified MachineBasicBlock for a jumptable entry.
-void AsmPrinter::printPICJumpTableSetLabel(unsigned uid,
- const MachineBasicBlock *MBB) const {
- if (!MAI->getSetDirective())
- return;
-
- O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix()
- << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','
- << *GetMBBSymbol(MBB->getNumber())
- << '-' << *GetJTISymbol(uid) << '\n';
-}
-
-void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, unsigned uid2,
- const MachineBasicBlock *MBB) const {
- if (!MAI->getSetDirective())
- return;
-
- O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix()
- << getFunctionNumber() << '_' << uid << '_' << uid2
- << "_set_" << MBB->getNumber() << ','
- << *GetMBBSymbol(MBB->getNumber())
- << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << uid << '_' << uid2 << '\n';
-}
-
-void AsmPrinter::printVisibility(MCSymbol *Sym, unsigned Visibility) const {
+void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility) const {
MCSymbolAttr Attr = MCSA_Invalid;
switch (Visibility) {
@@ -1633,86 +1788,3 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
return 0;
}
-/// EmitComments - Pretty-print comments for instructions
-void AsmPrinter::EmitComments(const MachineInstr &MI) const {
- if (!VerboseAsm)
- return;
-
- bool Newline = false;
-
- if (!MI.getDebugLoc().isUnknown()) {
- DILocation DLT = MF->getDILocation(MI.getDebugLoc());
-
- // Print source line info.
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- DIScope Scope = DLT.getScope();
- // Omit the directory, because it's likely to be long and uninteresting.
- if (!Scope.isNull())
- O << Scope.getFilename();
- else
- O << "<unknown>";
- O << ':' << DLT.getLineNumber();
- if (DLT.getColumnNumber() != 0)
- O << ':' << DLT.getColumnNumber();
- Newline = true;
- }
-
- // Check for spills and reloads
- int FI;
-
- const MachineFrameInfo *FrameInfo =
- MI.getParent()->getParent()->getFrameInfo();
-
- // We assume a single instruction only has a spill or reload, not
- // both.
- const MachineMemOperand *MMO;
- if (TM.getInstrInfo()->isLoadFromStackSlotPostFE(&MI, FI)) {
- if (FrameInfo->isSpillSlotObjectIndex(FI)) {
- MMO = *MI.memoperands_begin();
- if (Newline) O << '\n';
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ' << MMO->getSize() << "-byte Reload";
- Newline = true;
- }
- }
- else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, MMO, FI)) {
- if (FrameInfo->isSpillSlotObjectIndex(FI)) {
- if (Newline) O << '\n';
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' '
- << MMO->getSize() << "-byte Folded Reload";
- Newline = true;
- }
- }
- else if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&MI, FI)) {
- if (FrameInfo->isSpillSlotObjectIndex(FI)) {
- MMO = *MI.memoperands_begin();
- if (Newline) O << '\n';
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ' << MMO->getSize() << "-byte Spill";
- Newline = true;
- }
- }
- else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, MMO, FI)) {
- if (FrameInfo->isSpillSlotObjectIndex(FI)) {
- if (Newline) O << '\n';
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' '
- << MMO->getSize() << "-byte Folded Spill";
- Newline = true;
- }
- }
-
- // Check for spill-induced copies
- unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
- if (TM.getInstrInfo()->isMoveInstr(MI, SrcReg, DstReg,
- SrcSubIdx, DstSubIdx)) {
- if (MI.getAsmPrinterFlag(ReloadReuse)) {
- if (Newline) O << '\n';
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " Reload Reuse";
- }
- }
-}
-
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index 349e0ac..63360c0 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -313,6 +313,7 @@ void DIESectionOffset::EmitValue(DwarfPrinter *D, unsigned Form) const {
D->EmitSectionOffset(Label.getTag(), Section.getTag(),
Label.getNumber(), Section.getNumber(),
IsSmall, IsEH, UseSet);
+ D->getAsm()->O << '\n'; // FIXME: Necesssary?
}
/// SizeOf - Determine size of delta value in bytes.
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 513987f..5093dd9 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -26,6 +26,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Timer.h"
#include "llvm/System/Path.h"
@@ -166,7 +167,8 @@ public:
class DbgScope {
DbgScope *Parent; // Parent to this scope.
DIDescriptor Desc; // Debug info descriptor for scope.
- MDNode * InlinedAtLocation; // Location at which scope is inlined.
+ // Location at which this scope is inlined.
+ AssertingVH<MDNode> InlinedAtLocation;
bool AbstractScope; // Abstract Scope
unsigned StartLabelID; // Label ID of the beginning of scope.
unsigned EndLabelID; // Label ID of the end of scope.
@@ -189,7 +191,7 @@ public:
void setParent(DbgScope *P) { Parent = P; }
DIDescriptor getDesc() const { return Desc; }
MDNode *getInlinedAt() const {
- return dyn_cast_or_null<MDNode>(InlinedAtLocation);
+ return InlinedAtLocation;
}
MDNode *getScopeNode() const { return Desc.getNode(); }
unsigned getStartLabelID() const { return StartLabelID; }
@@ -616,7 +618,7 @@ void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
1). Add the offset of the forwarding field.
- 2). Follow that pointer to get the the real __Block_byref_x_VarName
+ 2). Follow that pointer to get the real __Block_byref_x_VarName
struct to use (the real one may have been copied onto the heap).
3). Add the offset for the field VarName, to find the actual variable.
@@ -937,7 +939,16 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
DIE *ElemDie = NULL;
if (Element.getTag() == dwarf::DW_TAG_subprogram)
ElemDie = createSubprogramDIE(DISubprogram(Element.getNode()));
- else
+ else if (Element.getTag() == dwarf::DW_TAG_auto_variable) {
+ DIVariable DV(Element.getNode());
+ ElemDie = new DIE(dwarf::DW_TAG_variable);
+ addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
+ DV.getName());
+ addType(ElemDie, DV.getType());
+ addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
+ addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
+ addSourceLine(ElemDie, &DV);
+ } else
ElemDie = createMemberDIE(DIDerivedType(Element.getNode()));
Buffer.addChild(ElemDie);
}
@@ -949,6 +960,11 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
if (RLang)
addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
dwarf::DW_FORM_data1, RLang);
+
+ DICompositeType ContainingType = CTy.getContainingType();
+ if (!ContainingType.isNull())
+ addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
+ getOrCreateTypeDIE(DIType(ContainingType.getNode())));
break;
}
default:
@@ -959,7 +975,7 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
if (!Name.empty())
addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
- if (Tag == dwarf::DW_TAG_enumeration_type ||
+ if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type ||
Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) {
// Add size if non-zero (derived types might be zero-sized.)
if (Size)
@@ -1107,7 +1123,26 @@ DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
// This is not a bitfield.
addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
- addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
+ if (DT.getTag() == dwarf::DW_TAG_inheritance
+ && DT.isVirtual()) {
+
+ // For C++, virtual base classes are not at fixed offset. Use following
+ // expression to extract appropriate offset from vtable.
+ // BaseAddr = ObAddr + *((*ObAddr) - Offset)
+
+ DIEBlock *VBaseLocationDie = new DIEBlock();
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
+
+ addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
+ VBaseLocationDie);
+ } else
+ addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
if (DT.isProtected())
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
@@ -1179,12 +1214,17 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
if (SPTag == dwarf::DW_TAG_subroutine_type)
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
- addType(Arg, DIType(Args.getElement(i).getNode()));
- addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ??
+ DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
+ addType(Arg, ATy);
+ if (ATy.isArtificial())
+ addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
SPDie->addChild(Arg);
}
}
+ if (SP.isArtificial())
+ addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
+
// DW_TAG_inlined_subroutine may refer to this DIE.
ModuleCU->insertDIE(SP.getNode(), SPDie);
return SPDie;
@@ -1289,7 +1329,13 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
DIE *SPDie = ModuleCU->getDIE(SPNode);
assert (SPDie && "Unable to find subprogram DIE!");
DISubprogram SP(SPNode);
- if (SP.isDefinition() && !SP.getContext().isCompileUnit()) {
+ // There is not any need to generate specification DIE for a function
+ // defined at compile unit level. If a function is defined inside another
+ // function then gdb prefers the definition at top level and but does not
+ // expect specification DIE in parent function. So avoid creating
+ // specification DIE for a function defined inside a function.
+ if (SP.isDefinition() && !SP.getContext().isCompileUnit()
+ && !SP.getContext().isSubprogram()) {
addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
// Add arguments.
DICompositeType SPTy = SP.getType();
@@ -1298,8 +1344,10 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
if (SPTag == dwarf::DW_TAG_subroutine_type)
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
- addType(Arg, DIType(Args.getElement(i).getNode()));
- addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ??
+ DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
+ addType(Arg, ATy);
+ if (ATy.isArtificial())
+ addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
SPDie->addChild(Arg);
}
DIE *SPDeclDie = SPDie;
@@ -1308,7 +1356,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
SPDeclDie);
ModuleCU->addDie(SPDie);
}
-
+
addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
DWLabel("func_begin", SubprogramCount));
addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
@@ -1471,6 +1519,9 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
else
addAddress(VariableDie, dwarf::DW_AT_location, Location);
}
+
+ if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial())
+ addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
DV->setDIE(VariableDie);
return VariableDie;
@@ -1669,6 +1720,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
addObjectLabel(Block, 0, dwarf::DW_FORM_udata,
Asm->GetGlobalValueSymbol(DI_GV.getGlobal()));
addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
+ addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
ModuleCU->addDie(VariableSpecDIE);
} else {
DIEBlock *Block = new DIEBlock();
@@ -1779,8 +1831,7 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
FullPath.appendComponent(getSourceFileName(Id.second));
assert(AppendOk && "Could not append filename to directory!");
AppendOk = false;
- Asm->EmitFile(i, FullPath.str());
- Asm->O << '\n';
+ Asm->OutStreamer.EmitDwarfFileDirective(i, FullPath.str());
}
}
@@ -1986,7 +2037,7 @@ void DwarfDebug::createDbgScope(MDNode *Scope, MDNode *InlinedAt) {
/// extractScopeInformation - Scan machine instructions in this function
/// and collect DbgScopes. Return true, if atleast one scope was found.
-bool DwarfDebug::extractScopeInformation(MachineFunction *MF) {
+bool DwarfDebug::extractScopeInformation() {
// If scope information was extracted using .dbg intrinsics then there is not
// any need to extract these information by scanning each instruction.
if (!DbgScopeMap.empty())
@@ -2081,7 +2132,7 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) {
/// beginFunction - Gather pre-function debug information. Assumes being
/// emitted immediately after the function entry point.
-void DwarfDebug::beginFunction(MachineFunction *MF) {
+void DwarfDebug::beginFunction(const MachineFunction *MF) {
this->MF = MF;
if (!ShouldEmitDwarfDebug()) return;
@@ -2089,14 +2140,11 @@ void DwarfDebug::beginFunction(MachineFunction *MF) {
if (TimePassesIsEnabled)
DebugTimer->startTimer();
- if (!extractScopeInformation(MF))
+ if (!extractScopeInformation())
return;
collectVariableInfo();
- // Begin accumulating function debug information.
- MMI->BeginFunction(MF);
-
// Assumes in correct section after the entry point.
EmitLabel("func_begin", ++SubprogramCount);
@@ -2123,7 +2171,7 @@ void DwarfDebug::beginFunction(MachineFunction *MF) {
/// endFunction - Gather and emit post-function debug information.
///
-void DwarfDebug::endFunction(MachineFunction *MF) {
+void DwarfDebug::endFunction(const MachineFunction *MF) {
if (!ShouldEmitDwarfDebug()) return;
if (TimePassesIsEnabled)
@@ -2366,6 +2414,9 @@ void DwarfDebug::emitDIE(DIE *Die) {
unsigned Form = AbbrevData[i].getForm();
assert(Form && "Too many attributes for DIE (check abbreviation)");
+ if (Asm->VerboseAsm)
+ Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr));
+
switch (Attr) {
case dwarf::DW_AT_sibling:
Asm->EmitInt32(Die->getSiblingOffset());
@@ -2380,10 +2431,9 @@ void DwarfDebug::emitDIE(DIE *Die) {
default:
// Emit an attribute using the defined form.
Values[i]->EmitValue(this, Form);
+ O << "\n"; // REMOVE This once all EmitValue impls emit their own newline.
break;
}
-
- EOL(dwarf::AttributeString(Attr));
}
// Emit the DIE children if any.
@@ -2767,7 +2817,8 @@ void DwarfDebug::emitDebugPubTypes() {
EmitLabel("pubtypes_begin", ModuleCU->getID());
- Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF Version");
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DWARF Version");
+ Asm->EmitInt16(dwarf::DWARF_VERSION);
EmitSectionOffset("info_begin", "section_info",
ModuleCU->getID(), 0, true, false);
@@ -2783,10 +2834,11 @@ void DwarfDebug::emitDebugPubTypes() {
const char *Name = GI->getKeyData();
DIE * Entity = GI->second;
- Asm->EmitInt32(Entity->getOffset()); EOL("DIE offset");
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DIE offset");
+ Asm->EmitInt32(Entity->getOffset());
if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("External Name");
- Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)), 0);
+ Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
}
Asm->EmitInt32(0); EOL("End Mark");
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index e723621..55baa92 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -103,7 +103,7 @@ class DwarfDebug : public DwarfPrinter {
///
SmallVector<std::pair<unsigned, unsigned>, 8> SourceIds;
- /// Lines - List of of source line correspondence.
+ /// Lines - List of source line correspondence.
std::vector<SrcLineInfo> Lines;
/// DIEValues - A list of all the unique values in use.
@@ -523,11 +523,11 @@ public:
/// beginFunction - Gather pre-function debug information. Assumes being
/// emitted immediately after the function entry point.
- void beginFunction(MachineFunction *MF);
+ void beginFunction(const MachineFunction *MF);
/// endFunction - Gather and emit post-function debug information.
///
- void endFunction(MachineFunction *MF);
+ void endFunction(const MachineFunction *MF);
/// recordSourceLine - Records location information and associates it with a
/// label. Returns a unique label ID used to generate a label and provide
@@ -550,7 +550,7 @@ public:
/// extractScopeInformation - Scan machine instructions in this function
/// and collect DbgScopes. Return true, if atleast one scope was found.
- bool extractScopeInformation(MachineFunction *MF);
+ bool extractScopeInformation();
/// collectVariableInfo - Populate DbgScope entries with variables' info.
void collectVariableInfo();
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index 2ae16c0..c6c59f5 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -34,6 +34,7 @@
#include "llvm/Support/Timer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Twine.h"
using namespace llvm;
DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A,
@@ -49,26 +50,6 @@ DwarfException::~DwarfException() {
delete ExceptionTimer;
}
-/// SizeOfEncodedValue - Return the size of the encoding in bytes.
-unsigned DwarfException::SizeOfEncodedValue(unsigned Encoding) {
- if (Encoding == dwarf::DW_EH_PE_omit)
- return 0;
-
- switch (Encoding & 0x07) {
- case dwarf::DW_EH_PE_absptr:
- return TD->getPointerSize();
- case dwarf::DW_EH_PE_udata2:
- return 2;
- case dwarf::DW_EH_PE_udata4:
- return 4;
- case dwarf::DW_EH_PE_udata8:
- return 8;
- }
-
- assert(0 && "Invalid encoded value.");
- return 0;
-}
-
/// CreateLabelDiff - Emit a label and subtract it from the expression we
/// already have. This is equivalent to emitting "foo - .", but we have to emit
/// the label for "." directly.
@@ -99,7 +80,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
TD->getPointerSize() : -TD->getPointerSize();
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
-
+
// Begin eh frame section.
Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection());
@@ -127,30 +108,16 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
// The personality presence indicates that language specific information will
// show up in the eh frame. Find out how we are supposed to lower the
// personality function reference:
- const MCExpr *PersonalityRef = 0;
- bool IsPersonalityIndirect = false, IsPersonalityPCRel = false;
- if (PersonalityFn) {
- // FIXME: HANDLE STATIC CODEGEN MODEL HERE.
-
- // In non-static mode, ask the object file how to represent this reference.
- PersonalityRef =
- TLOF.getSymbolForDwarfGlobalReference(PersonalityFn, Asm->Mang,
- Asm->MMI,
- IsPersonalityIndirect,
- IsPersonalityPCRel);
- }
-
- unsigned PerEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
- if (IsPersonalityIndirect)
- PerEncoding |= dwarf::DW_EH_PE_indirect;
- unsigned LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
- unsigned FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+
+ unsigned LSDAEncoding = TLOF.getLSDAEncoding();
+ unsigned FDEEncoding = TLOF.getFDEEncoding();
+ unsigned PerEncoding = TLOF.getPersonalityEncoding();
char Augmentation[6] = { 0 };
unsigned AugmentationSize = 0;
char *APtr = Augmentation + 1;
- if (PersonalityRef) {
+ if (PersonalityFn) {
// There is a personality function.
*APtr++ = 'P';
AugmentationSize += 1 + SizeOfEncodedValue(PerEncoding);
@@ -180,20 +147,19 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
EOL("CIE Return Address Column");
- EmitULEB128(AugmentationSize, "Augmentation Size");
- EmitEncodingByte(PerEncoding, "Personality");
-
- // If there is a personality, we need to indicate the function's location.
- if (PersonalityRef) {
- if (!IsPersonalityPCRel)
- PersonalityRef = CreateLabelDiff(PersonalityRef, "personalityref_addr",
- Index);
-
- O << MAI->getData32bitsDirective() << *PersonalityRef;
- EOL("Personality");
+ if (Augmentation[0]) {
+ EmitULEB128(AugmentationSize, "Augmentation Size");
- EmitEncodingByte(LSDAEncoding, "LSDA");
- EmitEncodingByte(FDEEncoding, "FDE");
+ // If there is a personality, we need to indicate the function's location.
+ if (PersonalityFn) {
+ EmitEncodingByte(PerEncoding, "Personality");
+ EmitReference(PersonalityFn, PerEncoding);
+ EOL("Personality");
+ }
+ if (UsesLSDA[Index])
+ EmitEncodingByte(LSDAEncoding, "LSDA");
+ if (FDEEncoding != dwarf::DW_EH_PE_absptr)
+ EmitEncodingByte(FDEEncoding, "FDE");
}
// Indicate locations of general callee saved registers in frame.
@@ -215,8 +181,12 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
"Should not emit 'available externally' functions at all");
const Function *TheFunc = EHFrameInfo.function;
+ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
- Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getEHFrameSection());
+ unsigned LSDAEncoding = TLOF.getLSDAEncoding();
+ unsigned FDEEncoding = TLOF.getFDEEncoding();
+
+ Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection());
// Externally visible entry into the functions eh frame info. If the
// corresponding function is static, this should not be externally visible.
@@ -254,7 +224,8 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// EH frame header.
EmitDifference("eh_frame_end", EHFrameInfo.Number,
- "eh_frame_begin", EHFrameInfo.Number, true);
+ "eh_frame_begin", EHFrameInfo.Number,
+ true);
EOL("Length of Frame Information Entry");
EmitLabel("eh_frame_begin", EHFrameInfo.Number);
@@ -265,33 +236,23 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
EOL("FDE CIE offset");
- EmitReference("eh_func_begin", EHFrameInfo.Number, true, true);
+ EmitReference("eh_func_begin", EHFrameInfo.Number, FDEEncoding);
EOL("FDE initial location");
EmitDifference("eh_func_end", EHFrameInfo.Number,
- "eh_func_begin", EHFrameInfo.Number, true);
+ "eh_func_begin", EHFrameInfo.Number,
+ SizeOfEncodedValue(FDEEncoding) == 4);
EOL("FDE address range");
// If there is a personality and landing pads then point to the language
// specific data area in the exception table.
if (MMI->getPersonalities()[0] != NULL) {
+ unsigned Size = SizeOfEncodedValue(LSDAEncoding);
- if (Asm->TM.getLSDAEncoding() != DwarfLSDAEncoding::EightByte) {
- EmitULEB128(4, "Augmentation size");
-
- if (EHFrameInfo.hasLandingPads)
- EmitReference("exception", EHFrameInfo.Number, true, true);
- else
- Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
- } else {
- EmitULEB128(TD->getPointerSize(), "Augmentation size");
-
- if (EHFrameInfo.hasLandingPads) {
- EmitReference("exception", EHFrameInfo.Number, true, false);
- } else {
- Asm->OutStreamer.EmitIntValue(0, TD->getPointerSize(),
- 0/*addrspace*/);
- }
- }
+ EmitULEB128(Size, "Augmentation size");
+ if (EHFrameInfo.hasLandingPads)
+ EmitReference("exception", EHFrameInfo.Number, LSDAEncoding);
+ else
+ Asm->OutStreamer.EmitIntValue(0, Size/*size*/, 0/*addrspace*/);
EOL("Language Specific Data Area");
} else {
@@ -406,20 +367,22 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
if (NumShared < TypeIds.size()) {
unsigned SizeAction = 0;
- ActionEntry *PrevAction = 0;
+ unsigned PrevAction = (unsigned)-1;
if (NumShared) {
const unsigned SizePrevIds = PrevLPI->TypeIds.size();
assert(Actions.size());
- PrevAction = &Actions.back();
- SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) +
- MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
+ PrevAction = Actions.size() - 1;
+ SizeAction =
+ MCAsmInfo::getSLEB128Size(Actions[PrevAction].NextAction) +
+ MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID);
for (unsigned j = NumShared; j != SizePrevIds; ++j) {
+ assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!");
SizeAction -=
- MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
- SizeAction += -PrevAction->NextAction;
- PrevAction = PrevAction->Previous;
+ MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID);
+ SizeAction += -Actions[PrevAction].NextAction;
+ PrevAction = Actions[PrevAction].Previous;
}
}
@@ -436,7 +399,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
ActionEntry Action = { ValueForTypeID, NextAction, PrevAction };
Actions.push_back(Action);
- PrevAction = &Actions.back();
+ PrevAction = Actions.size() - 1;
}
// Record the first action of the landing pad site.
@@ -446,7 +409,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
// Information used when created the call-site table. The action record
// field of the call site record is the offset of the first associated
// action record, relative to the start of the actions table. This value is
- // biased by 1 (1 in dicating the start of the actions table), and 0
+ // biased by 1 (1 indicating the start of the actions table), and 0
// indicates that there are no actions.
FirstActions.push_back(FirstAction);
@@ -579,7 +542,16 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
}
// Otherwise, create a new call-site.
- CallSites.push_back(Site);
+ if (MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf)
+ CallSites.push_back(Site);
+ else {
+ // SjLj EH must maintain the call sites in the order assigned
+ // to them by the SjLjPrepare pass.
+ unsigned SiteNo = MMI->getCallSiteBeginLabel(BeginLabel);
+ if (CallSites.size() < SiteNo)
+ CallSites.resize(SiteNo);
+ CallSites[SiteNo - 1] = Site;
+ }
PreviousIsInvoke = true;
} else {
// Create a gap.
@@ -638,8 +610,7 @@ void DwarfException::EmitExceptionTable() {
// landing pad site.
SmallVector<ActionEntry, 32> Actions;
SmallVector<unsigned, 64> FirstActions;
- unsigned SizeActions = ComputeActionsTable(LandingPads, Actions,
- FirstActions);
+ unsigned SizeActions=ComputeActionsTable(LandingPads, Actions, FirstActions);
// Invokes and nounwind calls have entries in PadMap (due to being bracketed
// by try-range labels when lowered). Ordinary calls do not, so appropriate
@@ -683,13 +654,13 @@ void DwarfException::EmitExceptionTable() {
// Type infos.
const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection();
- unsigned TTypeFormat;
+ unsigned TTypeEncoding;
unsigned TypeFormatSize;
if (!HaveTTData) {
// For SjLj exceptions, if there is no TypeInfo, then we just explicitly say
// that we're omitting that bit.
- TTypeFormat = dwarf::DW_EH_PE_omit;
+ TTypeEncoding = dwarf::DW_EH_PE_omit;
TypeFormatSize = SizeOfEncodedValue(dwarf::DW_EH_PE_absptr);
} else {
// Okay, we have actual filters or typeinfos to emit. As such, we need to
@@ -719,14 +690,8 @@ void DwarfException::EmitExceptionTable() {
// somewhere. This predicate should be moved to a shared location that is
// in target-independent code.
//
- if (LSDASection->getKind().isWriteable() ||
- Asm->TM.getRelocationModel() == Reloc::Static)
- TTypeFormat = dwarf::DW_EH_PE_absptr;
- else
- TTypeFormat = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
- dwarf::DW_EH_PE_sdata4;
-
- TypeFormatSize = SizeOfEncodedValue(TTypeFormat);
+ TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding();
+ TypeFormatSize = SizeOfEncodedValue(TTypeEncoding);
}
// Begin the exception table.
@@ -752,7 +717,7 @@ void DwarfException::EmitExceptionTable() {
// does, instead output it before the table.
unsigned SizeTypes = TypeInfos.size() * TypeFormatSize;
unsigned TyOffset = sizeof(int8_t) + // Call site format
- MCAsmInfo::getULEB128Size(SizeSites) + // Call-site table length
+ MCAsmInfo::getULEB128Size(SizeSites) + // Call site table length
SizeSites + SizeActions + SizeTypes;
unsigned TotalSize = sizeof(int8_t) + // LPStart format
sizeof(int8_t) + // TType format
@@ -777,7 +742,7 @@ void DwarfException::EmitExceptionTable() {
// Emit the header.
EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
- EmitEncodingByte(TTypeFormat, "@TType");
+ EmitEncodingByte(TTypeEncoding, "@TType");
if (HaveTTData)
EmitULEB128(TyOffset, "@TType base offset");
@@ -826,7 +791,7 @@ void DwarfException::EmitExceptionTable() {
// Emit the landing pad call site table.
EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
- EmitULEB128(SizeSites, "Call site table size");
+ EmitULEB128(SizeSites, "Call site table length");
for (SmallVectorImpl<CallSiteEntry>::const_iterator
I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
@@ -859,13 +824,14 @@ void DwarfException::EmitExceptionTable() {
// Offset of the landing pad, counted in 16-byte bundles relative to the
// @LPStart address.
- if (!S.PadLabel)
+ if (!S.PadLabel) {
+ Asm->OutStreamer.AddComment("Landing pad");
Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
- else
+ } else {
EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount,
true, true);
-
- EOL("Landing pad");
+ EOL("Landing pad");
+ }
// Offset of the first associated action record, relative to the start of
// the action table. This value is biased by 1 (1 indicates the start of
@@ -875,38 +841,43 @@ void DwarfException::EmitExceptionTable() {
}
// Emit the Action Table.
+ if (Actions.size() != 0) EOL("-- Action Record Table --");
for (SmallVectorImpl<ActionEntry>::const_iterator
I = Actions.begin(), E = Actions.end(); I != E; ++I) {
const ActionEntry &Action = *I;
+ EOL("Action Record:");
// Type Filter
//
// Used by the runtime to match the type of the thrown exception to the
// type of the catch clauses or the types in the exception specification.
- EmitSLEB128(Action.ValueForTypeID, "TypeInfo index");
+ EmitSLEB128(Action.ValueForTypeID, " TypeInfo index");
// Action Record
//
// Self-relative signed displacement in bytes of the next action record,
// or 0 if there is no next action record.
- EmitSLEB128(Action.NextAction, "Next action");
+ EmitSLEB128(Action.NextAction, " Next action");
}
// Emit the Catch TypeInfos.
+ if (!TypeInfos.empty()) EOL("-- Catch TypeInfos --");
for (std::vector<GlobalVariable *>::const_reverse_iterator
I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
const GlobalVariable *GV = *I;
- PrintRelDirective();
- if (GV)
- O << *Asm->GetGlobalValueSymbol(GV);
- else
+ if (GV) {
+ EmitReference(GV, TTypeEncoding);
+ EOL("TypeInfo");
+ } else {
+ PrintRelDirective(TTypeEncoding);
O << "0x0";
-
- EOL("TypeInfo");
+ EOL("");
+ }
}
// Emit the Exception Specifications.
+ if (!FilterIds.empty()) EOL("-- Filter IDs --");
for (std::vector<unsigned>::const_iterator
I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
unsigned TypeID = *I;
@@ -943,7 +914,7 @@ void DwarfException::EndModule() {
/// BeginFunction - Gather pre-function exception information. Assumes it's
/// being emitted immediately after the function entry point.
-void DwarfException::BeginFunction(MachineFunction *MF) {
+void DwarfException::BeginFunction(const MachineFunction *MF) {
if (!MMI || !MAI->doesSupportExceptionHandling()) return;
if (TimePassesIsEnabled)
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index 3921e91..3db1a00 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -76,9 +76,6 @@ class DwarfException : public DwarfPrinter {
/// ExceptionTimer - Timer for the Dwarf exception writer.
Timer *ExceptionTimer;
- /// SizeOfEncodedValue - Return the size of the encoding in bytes.
- unsigned SizeOfEncodedValue(unsigned Encoding);
-
/// EmitCIE - Emit a Common Information Entry (CIE). This holds information
/// that is shared among many Frame Description Entries. There is at least
/// one CIE in every non-empty .debug_frame section.
@@ -103,7 +100,7 @@ class DwarfException : public DwarfPrinter {
/// exception. If it matches then the exception and type id are passed
/// on to the landing pad. Otherwise the next action is looked up. This
/// chain is terminated with a next action of zero. If no type id is
- /// found the the frame is unwound and handling continues.
+ /// found the frame is unwound and handling continues.
/// 3. Type id table contains references to all the C++ typeinfo for all
/// catches in the function. This tables is reversed indexed base 1.
@@ -135,7 +132,7 @@ class DwarfException : public DwarfPrinter {
struct ActionEntry {
int ValueForTypeID; // The value to write - may not be equal to the type id.
int NextAction;
- struct ActionEntry *Previous;
+ unsigned Previous;
};
/// CallSiteEntry - Structure describing an entry in the call-site table.
@@ -197,7 +194,7 @@ public:
/// BeginFunction - Gather pre-function exception information. Assumes being
/// emitted immediately after the function entry point.
- void BeginFunction(MachineFunction *MF);
+ void BeginFunction(const MachineFunction *MF);
/// EndFunction - Gather and emit post-function exception information.
void EndFunction();
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
index d204bba..1299d04 100644
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// Emit general DWARF directives.
-//
+//
//===----------------------------------------------------------------------===//
#include "DwarfPrinter.h"
@@ -18,13 +18,17 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/ADT/SmallString.h"
using namespace llvm;
DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T,
@@ -33,6 +37,26 @@ DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T,
RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL),
SubprogramCount(0), Flavor(flavor), SetCounter(1) {}
+/// SizeOfEncodedValue - Return the size of the encoding in bytes.
+unsigned DwarfPrinter::SizeOfEncodedValue(unsigned Encoding) const {
+ if (Encoding == dwarf::DW_EH_PE_omit)
+ return 0;
+
+ switch (Encoding & 0x07) {
+ case dwarf::DW_EH_PE_absptr:
+ return TD->getPointerSize();
+ case dwarf::DW_EH_PE_udata2:
+ return 2;
+ case dwarf::DW_EH_PE_udata4:
+ return 4;
+ case dwarf::DW_EH_PE_udata8:
+ return 8;
+ }
+
+ assert(0 && "Invalid encoded value.");
+ return 0;
+}
+
void DwarfPrinter::PrintRelDirective(bool Force32Bit, bool isInSection) const {
if (isInSection && MAI->getDwarfSectionOffsetDirective())
O << MAI->getDwarfSectionOffsetDirective();
@@ -42,6 +66,14 @@ void DwarfPrinter::PrintRelDirective(bool Force32Bit, bool isInSection) const {
O << MAI->getData64bitsDirective();
}
+void DwarfPrinter::PrintRelDirective(unsigned Encoding) const {
+ unsigned Size = SizeOfEncodedValue(Encoding);
+ assert((Size == 4 || Size == 8) && "Do not support other types or rels!");
+
+ O << (Size == 4 ?
+ MAI->getData32bitsDirective() : MAI->getData64bitsDirective());
+}
+
/// EOL - Print a newline character to asm stream. If a comment is present
/// then it will be printed first. Comments should not contain '\n'.
void DwarfPrinter::EOL(const Twine &Comment) const {
@@ -195,13 +227,38 @@ void DwarfPrinter::EmitReference(const MCSymbol *Sym, bool IsPCRelative,
if (IsPCRelative) O << "-" << MAI->getPCSymbol();
}
-/// EmitDifference - Emit the difference between two labels. Some assemblers do
-/// not behave with absolute expressions with data directives, so there is an
-/// option (needsSet) to use an intermediary set expression.
+void DwarfPrinter::EmitReference(const char *Tag, unsigned Number,
+ unsigned Encoding) const {
+ SmallString<64> Name;
+ raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
+ << Tag << Number;
+
+ MCSymbol *Sym = Asm->OutContext.GetOrCreateSymbol(Name.str());
+ EmitReference(Sym, Encoding);
+}
+
+void DwarfPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const {
+ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+
+ PrintRelDirective(Encoding);
+ O << *TLOF.getSymbolForDwarfReference(Sym, Asm->MMI, Encoding);;
+}
+
+void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const {
+ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+
+ PrintRelDirective(Encoding);
+ O << *TLOF.getSymbolForDwarfGlobalReference(GV, Asm->Mang,
+ Asm->MMI, Encoding);;
+}
+
+/// EmitDifference - Emit the difference between two labels. If this assembler
+/// supports .set, we emit a .set of a temporary and then use it in the .word.
void DwarfPrinter::EmitDifference(const char *TagHi, unsigned NumberHi,
const char *TagLo, unsigned NumberLo,
bool IsSmall) {
- if (MAI->needsSet()) {
+ if (MAI->hasSetDirective()) {
+ // FIXME: switch to OutStreamer.EmitAssignment.
O << "\t.set\t";
PrintLabelName("set", SetCounter, Flavor);
O << ",";
@@ -232,7 +289,8 @@ void DwarfPrinter::EmitSectionOffset(const char* Label, const char* Section,
else
printAbsolute = MAI->isAbsoluteDebugSectionOffsets();
- if (MAI->needsSet() && useSet) {
+ if (MAI->hasSetDirective() && useSet) {
+ // FIXME: switch to OutStreamer.EmitAssignment.
O << "\t.set\t";
PrintLabelName("set", SetCounter, Flavor);
O << ",";
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
index 86fe2ab..73de398 100644
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
@@ -28,11 +28,14 @@ class Module;
class MCAsmInfo;
class TargetData;
class TargetRegisterInfo;
+class GlobalValue;
class MCSymbol;
class Twine;
class DwarfPrinter {
protected:
+ ~DwarfPrinter() {}
+
//===-------------------------------------------------------------==---===//
// Core attributes used by the DWARF printer.
//
@@ -56,7 +59,7 @@ protected:
Module *M;
/// MF - Current machine function.
- MachineFunction *MF;
+ const MachineFunction *MF;
/// MMI - Collected machine module information.
MachineModuleInfo *MMI;
@@ -83,6 +86,10 @@ public:
const MCAsmInfo *getMCAsmInfo() const { return MAI; }
const TargetData *getTargetData() const { return TD; }
+ /// SizeOfEncodedValue - Return the size of the encoding in bytes.
+ unsigned SizeOfEncodedValue(unsigned Encoding) const;
+
+ void PrintRelDirective(unsigned Encoding) const;
void PrintRelDirective(bool Force32Bit = false,
bool isInSection = false) const;
@@ -138,9 +145,11 @@ public:
void EmitReference(const MCSymbol *Sym, bool IsPCRelative = false,
bool Force32Bit = false) const;
- /// EmitDifference - Emit the difference between two labels. Some
- /// assemblers do not behave with absolute expressions with data directives,
- /// so there is an option (needsSet) to use an intermediary set expression.
+ void EmitReference(const char *Tag, unsigned Number, unsigned Encoding) const;
+ void EmitReference(const MCSymbol *Sym, unsigned Encoding) const;
+ void EmitReference(const GlobalValue *GV, unsigned Encoding) const;
+
+ /// EmitDifference - Emit the difference between two labels.
void EmitDifference(const DWLabel &LabelHi, const DWLabel &LabelLo,
bool IsSmall = false) {
EmitDifference(LabelHi.getTag(), LabelHi.getNumber(),
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
index dd8d88a..08e1bbc 100644
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
@@ -57,14 +57,14 @@ void DwarfWriter::EndModule() {
/// BeginFunction - Gather pre-function debug information. Assumes being
/// emitted immediately after the function entry point.
-void DwarfWriter::BeginFunction(MachineFunction *MF) {
+void DwarfWriter::BeginFunction(const MachineFunction *MF) {
DE->BeginFunction(MF);
DD->beginFunction(MF);
}
/// EndFunction - Gather and emit post-function debug information.
///
-void DwarfWriter::EndFunction(MachineFunction *MF) {
+void DwarfWriter::EndFunction(const MachineFunction *MF) {
DD->endFunction(MF);
DE->EndFunction();
diff --git a/lib/CodeGen/AsmPrinter/Makefile b/lib/CodeGen/AsmPrinter/Makefile
index b0071d0..60aa6cb 100644
--- a/lib/CodeGen/AsmPrinter/Makefile
+++ b/lib/CodeGen/AsmPrinter/Makefile
@@ -9,6 +9,5 @@
LEVEL = ../../..
LIBRARYNAME = LLVMAsmPrinter
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index 92849d3..faf4d95 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -133,7 +133,7 @@ bool BranchFolder::OptimizeImpDefsBlock(MachineBasicBlock *MBB) {
SmallSet<unsigned, 4> ImpDefRegs;
MachineBasicBlock::iterator I = MBB->begin();
while (I != MBB->end()) {
- if (I->getOpcode() != TargetInstrInfo::IMPLICIT_DEF)
+ if (!I->isImplicitDef())
break;
unsigned Reg = I->getOperand(0).getReg();
ImpDefRegs.insert(Reg);
@@ -206,53 +206,56 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
// See if any jump tables have become mergable or dead as the code generator
// did its thing.
MachineJumpTableInfo *JTI = MF.getJumpTableInfo();
+ if (JTI == 0) {
+ delete RS;
+ return MadeChange;
+ }
+
const std::vector<MachineJumpTableEntry> &JTs = JTI->getJumpTables();
- if (!JTs.empty()) {
- // Figure out how these jump tables should be merged.
- std::vector<unsigned> JTMapping;
- JTMapping.reserve(JTs.size());
-
- // We always keep the 0th jump table.
- JTMapping.push_back(0);
-
- // Scan the jump tables, seeing if there are any duplicates. Note that this
- // is N^2, which should be fixed someday.
- for (unsigned i = 1, e = JTs.size(); i != e; ++i) {
- if (JTs[i].MBBs.empty())
- JTMapping.push_back(i);
- else
- JTMapping.push_back(JTI->getJumpTableIndex(JTs[i].MBBs));
- }
-
- // If a jump table was merge with another one, walk the function rewriting
- // references to jump tables to reference the new JT ID's. Keep track of
- // whether we see a jump table idx, if not, we can delete the JT.
- BitVector JTIsLive(JTs.size());
- for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
- BB != E; ++BB) {
- for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
- I != E; ++I)
- for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
- MachineOperand &Op = I->getOperand(op);
- if (!Op.isJTI()) continue;
- unsigned NewIdx = JTMapping[Op.getIndex()];
- Op.setIndex(NewIdx);
-
- // Remember that this JT is live.
- JTIsLive.set(NewIdx);
- }
- }
+ // Figure out how these jump tables should be merged.
+ std::vector<unsigned> JTMapping;
+ JTMapping.reserve(JTs.size());
+
+ // We always keep the 0th jump table.
+ JTMapping.push_back(0);
+
+ // Scan the jump tables, seeing if there are any duplicates. Note that this
+ // is N^2, which should be fixed someday.
+ for (unsigned i = 1, e = JTs.size(); i != e; ++i) {
+ if (JTs[i].MBBs.empty())
+ JTMapping.push_back(i);
+ else
+ JTMapping.push_back(JTI->getJumpTableIndex(JTs[i].MBBs));
+ }
- // Finally, remove dead jump tables. This happens either because the
- // indirect jump was unreachable (and thus deleted) or because the jump
- // table was merged with some other one.
- for (unsigned i = 0, e = JTIsLive.size(); i != e; ++i)
- if (!JTIsLive.test(i)) {
- JTI->RemoveJumpTable(i);
- MadeChange = true;
+ // If a jump table was merge with another one, walk the function rewriting
+ // references to jump tables to reference the new JT ID's. Keep track of
+ // whether we see a jump table idx, if not, we can delete the JT.
+ BitVector JTIsLive(JTs.size());
+ for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
+ BB != E; ++BB) {
+ for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
+ I != E; ++I)
+ for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
+ MachineOperand &Op = I->getOperand(op);
+ if (!Op.isJTI()) continue;
+ unsigned NewIdx = JTMapping[Op.getIndex()];
+ Op.setIndex(NewIdx);
+
+ // Remember that this JT is live.
+ JTIsLive.set(NewIdx);
}
}
+ // Finally, remove dead jump tables. This happens either because the
+ // indirect jump was unreachable (and thus deleted) or because the jump
+ // table was merged with some other one.
+ for (unsigned i = 0, e = JTIsLive.size(); i != e; ++i)
+ if (!JTIsLive.test(i)) {
+ JTI->RemoveJumpTable(i);
+ MadeChange = true;
+ }
+
delete RS;
return MadeChange;
}
@@ -337,7 +340,7 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
// relative order. This is untenable because normal compiler
// optimizations (like this one) may reorder and/or merge these
// directives.
- I1->getOpcode() == TargetInstrInfo::INLINEASM) {
+ I1->isInlineAsm()) {
++I1; ++I2;
break;
}
@@ -957,7 +960,8 @@ ReoptimizeBlock:
}
// If MBB was the target of a jump table, update jump tables to go to the
// fallthrough instead.
- MF.getJumpTableInfo()->ReplaceMBBInJumpTables(MBB, FallThrough);
+ if (MachineJumpTableInfo *MJTI = MF.getJumpTableInfo())
+ MJTI->ReplaceMBBInJumpTables(MBB, FallThrough);
MadeChange = true;
}
return MadeChange;
@@ -1191,7 +1195,8 @@ ReoptimizeBlock:
}
// Change any jumptables to go to the new MBB.
- MF.getJumpTableInfo()->ReplaceMBBInJumpTables(MBB, CurTBB);
+ if (MachineJumpTableInfo *MJTI = MF.getJumpTableInfo())
+ MJTI->ReplaceMBBInJumpTables(MBB, CurTBB);
if (DidChange) {
++NumBranchOpts;
MadeChange = true;
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 17072d3..62cf339 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -21,7 +21,6 @@ add_llvm_library(LLVMCodeGen
LiveStackAnalysis.cpp
LiveVariables.cpp
LowerSubregs.cpp
- MachOWriter.cpp
MachineBasicBlock.cpp
MachineDominators.cpp
MachineFunction.cpp
@@ -40,6 +39,7 @@ add_llvm_library(LLVMCodeGen
ObjectCodeEmitter.cpp
OcamlGC.cpp
OptimizeExts.cpp
+ OptimizePHIs.cpp
PHIElimination.cpp
Passes.cpp
PostRASchedulerList.cpp
@@ -67,6 +67,7 @@ add_llvm_library(LLVMCodeGen
StrongPHIElimination.cpp
TailDuplication.cpp
TargetInstrInfoImpl.cpp
+ TargetLoweringObjectFileImpl.cpp
TwoAddressInstructionPass.cpp
UnreachableBlockElim.cpp
VirtRegMap.cpp
diff --git a/lib/CodeGen/CalcSpillWeights.cpp b/lib/CodeGen/CalcSpillWeights.cpp
index b8ef219..2bedd04 100644
--- a/lib/CodeGen/CalcSpillWeights.cpp
+++ b/lib/CodeGen/CalcSpillWeights.cpp
@@ -20,8 +20,8 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
-
using namespace llvm;
char CalculateSpillWeights::ID = 0;
@@ -58,10 +58,7 @@ bool CalculateSpillWeights::runOnMachineFunction(MachineFunction &fn) {
for (MachineBasicBlock::const_iterator mii = mbb->begin(), mie = mbb->end();
mii != mie; ++mii) {
const MachineInstr *mi = mii;
- if (tii->isIdentityCopy(*mi))
- continue;
-
- if (mi->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
+ if (tii->isIdentityCopy(*mi) || mi->isImplicitDef() || mi->isDebugValue())
continue;
for (unsigned i = 0, e = mi->getNumOperands(); i != e; ++i) {
diff --git a/lib/CodeGen/CodePlacementOpt.cpp b/lib/CodeGen/CodePlacementOpt.cpp
index 126700b..a13a310 100644
--- a/lib/CodeGen/CodePlacementOpt.cpp
+++ b/lib/CodeGen/CodePlacementOpt.cpp
@@ -106,7 +106,7 @@ bool CodePlacementOpt::HasAnalyzableTerminator(MachineBasicBlock *MBB) {
// At the time of this writing, there are blocks which AnalyzeBranch
// thinks end in single uncoditional branches, yet which have two CFG
// successors. Code in this file is not prepared to reason about such things.
- if (!MBB->empty() && MBB->back().getOpcode() == TargetInstrInfo::EH_LABEL)
+ if (!MBB->empty() && MBB->back().isEHLabel())
return false;
// Aggressively handle return blocks and similar constructs.
@@ -115,7 +115,7 @@ bool CodePlacementOpt::HasAnalyzableTerminator(MachineBasicBlock *MBB) {
// Ask the target's AnalyzeBranch if it can handle this block.
MachineBasicBlock *TBB = 0, *FBB = 0;
SmallVector<MachineOperand, 4> Cond;
- // Make the the terminator is understood.
+ // Make sure the terminator is understood.
if (TII->AnalyzeBranch(*MBB, TBB, FBB, Cond))
return false;
// Make sure we have the option of reversing the condition.
diff --git a/lib/CodeGen/DeadMachineInstructionElim.cpp b/lib/CodeGen/DeadMachineInstructionElim.cpp
index 0982eab..a215a19 100644
--- a/lib/CodeGen/DeadMachineInstructionElim.cpp
+++ b/lib/CodeGen/DeadMachineInstructionElim.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "codegen-dce"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Pass.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -19,8 +20,11 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/Statistic.h"
using namespace llvm;
+STATISTIC(NumDeletes, "Number of dead instructions deleted");
+
namespace {
class DeadMachineInstructionElim : public MachineFunctionPass {
virtual bool runOnMachineFunction(MachineFunction &MF);
@@ -51,7 +55,7 @@ FunctionPass *llvm::createDeadMachineInstructionElimPass() {
bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const {
// Don't delete instructions with side effects.
bool SawStore = false;
- if (!MI->isSafeToMove(TII, SawStore, 0))
+ if (!MI->isSafeToMove(TII, SawStore, 0) && !MI->isPHI())
return false;
// Examine each operand.
@@ -60,8 +64,8 @@ bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const {
if (MO.isReg() && MO.isDef()) {
unsigned Reg = MO.getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg) ?
- LivePhysRegs[Reg] : !MRI->use_empty(Reg)) {
- // This def has a use. Don't delete the instruction!
+ LivePhysRegs[Reg] : !MRI->use_nodbg_empty(Reg)) {
+ // This def has a non-debug use. Don't delete the instruction!
return false;
}
}
@@ -110,8 +114,31 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
// If the instruction is dead, delete it!
if (isDead(MI)) {
DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << *MI);
+ // It is possible that some DBG_VALUE instructions refer to this
+ // instruction. Examine each def operand for such references;
+ // if found, mark the DBG_VALUE as undef (but don't delete it).
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.isDef())
+ continue;
+ unsigned Reg = MO.getReg();
+ if (!TargetRegisterInfo::isVirtualRegister(Reg))
+ continue;
+ MachineRegisterInfo::use_iterator nextI;
+ for (MachineRegisterInfo::use_iterator I = MRI->use_begin(Reg),
+ E = MRI->use_end(); I!=E; I=nextI) {
+ nextI = llvm::next(I); // I is invalidated by the setReg
+ MachineOperand& Use = I.getOperand();
+ MachineInstr *UseMI = Use.getParent();
+ if (UseMI==MI)
+ continue;
+ assert(Use.isDebug());
+ UseMI->getOperand(0).setReg(0U);
+ }
+ }
AnyChanges = true;
MI->eraseFromParent();
+ ++NumDeletes;
MIE = MBB->rend();
// MII is now pointing to the next instruction to process,
// so don't increment it.
diff --git a/lib/CodeGen/ELFCodeEmitter.cpp b/lib/CodeGen/ELFCodeEmitter.cpp
index 11a85a0..8416d3b 100644
--- a/lib/CodeGen/ELFCodeEmitter.cpp
+++ b/lib/CodeGen/ELFCodeEmitter.cpp
@@ -62,7 +62,8 @@ void ELFCodeEmitter::startFunction(MachineFunction &MF) {
// They need to be emitted before the function because in some targets
// the later may reference JT or CP entry address.
emitConstantPool(MF.getConstantPool());
- emitJumpTables(MF.getJumpTableInfo());
+ if (MF.getJumpTableInfo())
+ emitJumpTables(MF.getJumpTableInfo());
}
/// finishFunction - This callback is invoked after the function is completely
@@ -84,7 +85,7 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
// Patch up Jump Table Section relocations to use the real MBBs offsets
// now that the MBB label offsets inside the function are known.
- if (!MF.getJumpTableInfo()->isEmpty()) {
+ if (MF.getJumpTableInfo()) {
ELFSection &JTSection = EW.getJumpTableSection();
for (std::vector<MachineRelocation>::iterator MRI = JTRelocations.begin(),
MRE = JTRelocations.end(); MRI != MRE; ++MRI) {
@@ -172,7 +173,7 @@ void ELFCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
"PIC codegen not yet handled for elf jump tables!");
const TargetELFWriterInfo *TEW = TM.getELFWriterInfo();
- unsigned EntrySize = MJTI->getEntrySize();
+ unsigned EntrySize = 4; //MJTI->getEntrySize();
// Get the ELF Section to emit the jump table
ELFSection &JTSection = EW.getJumpTableSection();
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index de45e09..0979c04 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -37,7 +37,6 @@
#include "llvm/PassManager.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/BinaryObject.h"
-#include "llvm/CodeGen/FileWriters.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
@@ -59,15 +58,6 @@ using namespace llvm;
char ELFWriter::ID = 0;
-/// AddELFWriter - Add the ELF writer to the function pass manager
-ObjectCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
- raw_ostream &O,
- TargetMachine &TM) {
- ELFWriter *EW = new ELFWriter(O, TM);
- PM.add(EW);
- return EW->getObjectCodeEmitter();
-}
-
//===----------------------------------------------------------------------===//
// ELFWriter Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/ExactHazardRecognizer.cpp b/lib/CodeGen/ExactHazardRecognizer.cpp
index 266c74c..61959bb 100644
--- a/lib/CodeGen/ExactHazardRecognizer.cpp
+++ b/lib/CodeGen/ExactHazardRecognizer.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This implements a a hazard recognizer using the instructions itineraries
+// This implements a hazard recognizer using the instructions itineraries
// defined for the current target.
//
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/GCStrategy.cpp b/lib/CodeGen/GCStrategy.cpp
index 79b2986..b5006fd 100644
--- a/lib/CodeGen/GCStrategy.cpp
+++ b/lib/CodeGen/GCStrategy.cpp
@@ -335,7 +335,7 @@ unsigned MachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB,
unsigned Label = MMI->NextLabelID();
BuildMI(MBB, MI, DL,
- TII->get(TargetInstrInfo::GC_LABEL)).addImm(Label);
+ TII->get(TargetOpcode::GC_LABEL)).addImm(Label);
return Label;
}
diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp
index 9997a48..87ab7ef 100644
--- a/lib/CodeGen/IntrinsicLowering.cpp
+++ b/lib/CodeGen/IntrinsicLowering.cpp
@@ -155,7 +155,7 @@ void IntrinsicLowering::AddPrototypes(Module &M) {
/// LowerBSWAP - Emit the code to lower bswap of V before the specified
/// instruction IP.
static Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) {
- assert(V->getType()->isInteger() && "Can't bswap a non-integer type!");
+ assert(V->getType()->isIntegerTy() && "Can't bswap a non-integer type!");
unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
@@ -251,7 +251,7 @@ static Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) {
/// LowerCTPOP - Emit the code to lower ctpop of V before the specified
/// instruction IP.
static Value *LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP) {
- assert(V->getType()->isInteger() && "Can't ctpop a non-integer type!");
+ assert(V->getType()->isIntegerTy() && "Can't ctpop a non-integer type!");
static const uint64_t MaskValues[6] = {
0x5555555555555555ULL, 0x3333333333333333ULL,
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 837e184..278de02 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -14,16 +14,20 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
+#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/FileWriters.h"
#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormattedStream.h"
@@ -57,14 +61,24 @@ static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
cl::desc("Print LLVM IR produced by the loop-reduce pass"));
static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
cl::desc("Print LLVM IR input to isel pass"));
-static cl::opt<bool> PrintEmittedAsm("print-emitted-asm", cl::Hidden,
- cl::desc("Dump emitter generated instructions as assembly"));
static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden,
cl::desc("Dump garbage collector data"));
static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
cl::desc("Verify generated machine code"),
cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL));
+static cl::opt<cl::boolOrDefault>
+AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
+ cl::init(cl::BOU_UNSET));
+
+static bool getVerboseAsm() {
+ switch (AsmVerbose) {
+ default:
+ case cl::BOU_UNSET: return TargetMachine::getAsmVerbosityDefault();
+ case cl::BOU_TRUE: return true;
+ case cl::BOU_FALSE: return false;
+ }
+}
// Enable or disable FastISel. Both options are needed, because
// FastISel is enabled by default with -fast, and we wish to be
@@ -98,139 +112,81 @@ LLVMTargetMachine::setCodeModelForStatic() {
setCodeModel(CodeModel::Small);
}
-FileModel::Model
-LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
- formatted_raw_ostream &Out,
- CodeGenFileType FileType,
- CodeGenOpt::Level OptLevel) {
+bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
+ formatted_raw_ostream &Out,
+ CodeGenFileType FileType,
+ CodeGenOpt::Level OptLevel) {
// Add common CodeGen passes.
if (addCommonCodeGenPasses(PM, OptLevel))
- return FileModel::Error;
+ return true;
+ OwningPtr<MCContext> Context(new MCContext());
+ OwningPtr<MCStreamer> AsmStreamer;
+
+ formatted_raw_ostream *LegacyOutput;
switch (FileType) {
- default:
+ default: return true;
+ case CGFT_AssemblyFile: {
+ const MCAsmInfo &MAI = *getMCAsmInfo();
+ MCInstPrinter *InstPrinter =
+ getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, Out);
+ AsmStreamer.reset(createAsmStreamer(*Context, Out, MAI,
+ getTargetData()->isLittleEndian(),
+ getVerboseAsm(), InstPrinter,
+ /*codeemitter*/0));
+ // Set the AsmPrinter's "O" to the output file.
+ LegacyOutput = &Out;
break;
- case TargetMachine::AssemblyFile:
- if (addAssemblyEmitter(PM, OptLevel, getAsmVerbosityDefault(), Out))
- return FileModel::Error;
- return FileModel::AsmFile;
- case TargetMachine::ObjectFile:
- if (!addObjectFileEmitter(PM, OptLevel, Out))
- return FileModel::MachOFile;
- else if (getELFWriterInfo())
- return FileModel::ElfFile;
}
- return FileModel::Error;
-}
-
-bool LLVMTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- bool Verbose,
- formatted_raw_ostream &Out) {
+ case CGFT_ObjectFile: {
+ // Create the code emitter for the target if it exists. If not, .o file
+ // emission fails.
+ MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this, *Context);
+ if (MCE == 0)
+ return true;
+
+ AsmStreamer.reset(createMachOStreamer(*Context, Out, MCE));
+
+ // Any output to the asmprinter's "O" stream is bad and needs to be fixed,
+ // force it to come out stderr.
+ // FIXME: this is horrible and leaks, eventually remove the raw_ostream from
+ // asmprinter.
+ LegacyOutput = new formatted_raw_ostream(errs());
+ break;
+ }
+ case CGFT_Null:
+ // The Null output is intended for use for performance analysis and testing,
+ // not real users.
+ AsmStreamer.reset(createNullStreamer(*Context));
+ // Any output to the asmprinter's "O" stream is bad and needs to be fixed,
+ // force it to come out stderr.
+ // FIXME: this is horrible and leaks, eventually remove the raw_ostream from
+ // asmprinter.
+ LegacyOutput = new formatted_raw_ostream(errs());
+ break;
+ }
+
+ // Create the AsmPrinter, which takes ownership of Context and AsmStreamer
+ // if successful.
FunctionPass *Printer =
- getTarget().createAsmPrinter(Out, *this, getMCAsmInfo(), Verbose);
- if (!Printer)
- return true;
-
- PM.add(Printer);
- return false;
-}
-
-bool LLVMTargetMachine::addObjectFileEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- formatted_raw_ostream &Out) {
- MCCodeEmitter *Emitter = getTarget().createCodeEmitter(*this);
- if (!Emitter)
+ getTarget().createAsmPrinter(*LegacyOutput, *this, *Context, *AsmStreamer,
+ getMCAsmInfo());
+ if (Printer == 0)
return true;
- PM.add(createMachOWriter(Out, *this, getMCAsmInfo(), Emitter));
- return false;
-}
-
-/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
-/// be split up (e.g., to add an object writer pass), this method can be used to
-/// finish up adding passes to emit the file, if necessary.
-bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
- MachineCodeEmitter *MCE,
- CodeGenOpt::Level OptLevel) {
- // Make sure the code model is set.
- setCodeModelForStatic();
+ // If successful, createAsmPrinter took ownership of AsmStreamer and Context.
+ Context.take(); AsmStreamer.take();
- if (MCE)
- addSimpleCodeEmitter(PM, OptLevel, *MCE);
- if (PrintEmittedAsm)
- addAssemblyEmitter(PM, OptLevel, true, ferrs());
-
- PM.add(createGCInfoDeleter());
-
- return false; // success!
-}
-
-/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
-/// be split up (e.g., to add an object writer pass), this method can be used to
-/// finish up adding passes to emit the file, if necessary.
-bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
- JITCodeEmitter *JCE,
- CodeGenOpt::Level OptLevel) {
- // Make sure the code model is set.
- setCodeModelForJIT();
+ PM.add(Printer);
- if (JCE)
- addSimpleCodeEmitter(PM, OptLevel, *JCE);
- if (PrintEmittedAsm)
- addAssemblyEmitter(PM, OptLevel, true, ferrs());
-
- PM.add(createGCInfoDeleter());
-
- return false; // success!
-}
-
-/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
-/// be split up (e.g., to add an object writer pass), this method can be used to
-/// finish up adding passes to emit the file, if necessary.
-bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
- ObjectCodeEmitter *OCE,
- CodeGenOpt::Level OptLevel) {
// Make sure the code model is set.
setCodeModelForStatic();
-
- if (OCE)
- addSimpleCodeEmitter(PM, OptLevel, *OCE);
- if (PrintEmittedAsm)
- addAssemblyEmitter(PM, OptLevel, true, ferrs());
-
- PM.add(createGCInfoDeleter());
-
- return false; // success!
-}
-
-/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
-/// get machine code emitted. This uses a MachineCodeEmitter object to handle
-/// actually outputting the machine code and resolving things like the address
-/// of functions. This method should returns true if machine code emission is
-/// not supported.
-///
-bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
- MachineCodeEmitter &MCE,
- CodeGenOpt::Level OptLevel) {
- // Make sure the code model is set.
- setCodeModelForJIT();
-
- // Add common CodeGen passes.
- if (addCommonCodeGenPasses(PM, OptLevel))
- return true;
-
- addCodeEmitter(PM, OptLevel, MCE);
- if (PrintEmittedAsm)
- addAssemblyEmitter(PM, OptLevel, true, ferrs());
-
PM.add(createGCInfoDeleter());
-
- return false; // success!
+ return false;
}
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
-/// get machine code emitted. This uses a MachineCodeEmitter object to handle
+/// get machine code emitted. This uses a JITCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
/// of functions. This method should returns true if machine code emission is
/// not supported.
@@ -246,9 +202,6 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
return true;
addCodeEmitter(PM, OptLevel, JCE);
- if (PrintEmittedAsm)
- addAssemblyEmitter(PM, OptLevel, true, ferrs());
-
PM.add(createGCInfoDeleter());
return false; // success!
@@ -282,6 +235,9 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
PM.add(createLoopStrengthReducePass(getTargetLowering()));
if (PrintLSR)
PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &dbgs()));
+#ifndef NDEBUG
+ PM.add(createVerifierPass());
+#endif
}
// Turn exception handling constructs into something the code generators can
@@ -339,6 +295,16 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
printAndVerify(PM, "After Instruction Selection",
/* allowDoubleDefs= */ true);
+ // Optimize PHIs before DCE: removing dead PHI cycles may make more
+ // instructions dead.
+ if (OptLevel != CodeGenOpt::None)
+ PM.add(createOptimizePHIsPass());
+
+ // Delete dead machine instructions regardless of optimization level.
+ PM.add(createDeadMachineInstructionElimPass());
+ printAndVerify(PM, "After codegen DCE pass",
+ /* allowDoubleDefs= */ true);
+
if (OptLevel != CodeGenOpt::None) {
PM.add(createOptimizeExtsPass());
if (!DisableMachineLICM)
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 8746bf9..f6bf433 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -140,7 +140,7 @@ void LiveIntervals::printInstrs(raw_ostream &OS) const {
<< ":\t\t# derived from " << mbbi->getName() << "\n";
for (MachineBasicBlock::iterator mii = mbbi->begin(),
mie = mbbi->end(); mii != mie; ++mii) {
- if (mii->getOpcode()==TargetInstrInfo::DEBUG_VALUE)
+ if (mii->isDebugValue())
OS << SlotIndex::getEmptyKey() << '\t' << *mii;
else
OS << getInstructionIndex(mii) << '\t' << *mii;
@@ -288,9 +288,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
VNInfo *ValNo;
MachineInstr *CopyMI = NULL;
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
- if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
- mi->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- mi->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
+ if (mi->isExtractSubreg() || mi->isInsertSubreg() || mi->isSubregToReg() ||
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
CopyMI = mi;
// Earlyclobbers move back one.
@@ -460,9 +458,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
VNInfo *ValNo;
MachineInstr *CopyMI = NULL;
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
- if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
- mi->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- mi->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
+ if (mi->isExtractSubreg() || mi->isInsertSubreg() || mi->isSubregToReg()||
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
CopyMI = mi;
ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator);
@@ -516,6 +512,8 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
baseIndex = baseIndex.getNextIndex();
while (++mi != MBB->end()) {
+ if (mi->isDebugValue())
+ continue;
if (getInstructionFromIndex(baseIndex) == 0)
baseIndex = indexes_->getNextNonNullIndex(baseIndex);
@@ -531,8 +529,8 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
end = baseIndex.getDefIndex();
} else {
// Another instruction redefines the register before it is ever read.
- // Then the register is essentially dead at the instruction that defines
- // it. Hence its interval is:
+ // Then the register is essentially dead at the instruction that
+ // defines it. Hence its interval is:
// [defSlot(def), defSlot(def)+1)
DEBUG(dbgs() << " dead");
end = start.getStoreIndex();
@@ -577,9 +575,7 @@ void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
else if (allocatableRegs_[MO.getReg()]) {
MachineInstr *CopyMI = NULL;
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
- if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
- MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
+ if (MI->isExtractSubreg() || MI->isInsertSubreg() || MI->isSubregToReg() ||
tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
CopyMI = MI;
handlePhysicalRegisterDef(MBB, MI, MIIdx, MO,
@@ -612,8 +608,16 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
SlotIndex end = baseIndex;
bool SeenDefUse = false;
-
- while (mi != MBB->end()) {
+
+ MachineBasicBlock::iterator E = MBB->end();
+ while (mi != E) {
+ if (mi->isDebugValue()) {
+ ++mi;
+ if (mi != E && !mi->isDebugValue()) {
+ baseIndex = indexes_->getNextNonNullIndex(baseIndex);
+ }
+ continue;
+ }
if (mi->killsRegister(interval.reg, tri_)) {
DEBUG(dbgs() << " killed");
end = baseIndex.getDefIndex();
@@ -631,7 +635,7 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
}
++mi;
- if (mi != MBB->end()) {
+ if (mi != E && !mi->isDebugValue()) {
baseIndex = indexes_->getNextNonNullIndex(baseIndex);
}
}
@@ -671,6 +675,9 @@ void LiveIntervals::computeIntervals() {
for (MachineFunction::iterator MBBI = mf_->begin(), E = mf_->end();
MBBI != E; ++MBBI) {
MachineBasicBlock *MBB = MBBI;
+ if (MBB->empty())
+ continue;
+
// Track the index of the current machine instr.
SlotIndex MIIndex = getMBBStartIdx(MBB);
DEBUG(dbgs() << MBB->getName() << ":\n");
@@ -693,7 +700,7 @@ void LiveIntervals::computeIntervals() {
for (MachineBasicBlock::iterator MI = MBB->begin(), miEnd = MBB->end();
MI != miEnd; ++MI) {
DEBUG(dbgs() << MIIndex << "\t" << *MI);
- if (MI->getOpcode()==TargetInstrInfo::DEBUG_VALUE)
+ if (MI->isDebugValue())
continue;
// Handle defs.
@@ -742,7 +749,7 @@ unsigned LiveIntervals::getVNInfoSourceReg(const VNInfo *VNI) const {
if (!VNI->getCopy())
return 0;
- if (VNI->getCopy()->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ if (VNI->getCopy()->isExtractSubreg()) {
// If it's extracting out of a physical register, return the sub-register.
unsigned Reg = VNI->getCopy()->getOperand(1).getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
@@ -756,8 +763,8 @@ unsigned LiveIntervals::getVNInfoSourceReg(const VNInfo *VNI) const {
Reg = tri_->getSubReg(Reg, VNI->getCopy()->getOperand(2).getImm());
}
return Reg;
- } else if (VNI->getCopy()->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- VNI->getCopy()->getOpcode() == TargetInstrInfo::SUBREG_TO_REG)
+ } else if (VNI->getCopy()->isInsertSubreg() ||
+ VNI->getCopy()->isSubregToReg())
return VNI->getCopy()->getOperand(2).getReg();
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
@@ -919,7 +926,7 @@ bool LiveIntervals::tryFoldMemoryOperand(MachineInstr* &MI,
SmallVector<unsigned, 2> &Ops,
bool isSS, int Slot, unsigned Reg) {
// If it is an implicit def instruction, just delete it.
- if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
+ if (MI->isImplicitDef()) {
RemoveMachineInstrFromMaps(MI);
vrm.RemoveMachineInstrFromMaps(MI);
MI->eraseFromParent();
@@ -1059,7 +1066,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
// If this is the rematerializable definition MI itself and
// all of its uses are rematerialized, simply delete it.
if (MI == ReMatOrigDefMI && CanDelete) {
- DEBUG(dbgs() << "\t\t\t\tErasing re-materlizable def: "
+ DEBUG(dbgs() << "\t\t\t\tErasing re-materializable def: "
<< MI << '\n');
RemoveMachineInstrFromMaps(MI);
vrm.RemoveMachineInstrFromMaps(MI);
@@ -1302,6 +1309,12 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
MachineInstr *MI = &*ri;
MachineOperand &O = ri.getOperand();
++ri;
+ if (MI->isDebugValue()) {
+ // Remove debug info for now.
+ O.setReg(0U);
+ DEBUG(dbgs() << "Removing debug info due to spill:" << "\t" << *MI);
+ continue;
+ }
assert(!O.isImplicit() && "Spilling register that's used as implicit use?");
SlotIndex index = getInstructionIndex(MI);
if (index < start || index >= end)
@@ -1525,7 +1538,7 @@ LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
MachineInstr *MI = &*ri;
++ri;
if (O.isDef()) {
- assert(MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF &&
+ assert(MI->isImplicitDef() &&
"Register def was not rewritten?");
RemoveMachineInstrFromMaps(MI);
vrm.RemoveMachineInstrFromMaps(MI);
@@ -2056,7 +2069,7 @@ bool LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li,
std::string msg;
raw_string_ostream Msg(msg);
Msg << "Ran out of registers during register allocation!";
- if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
+ if (MI->isInlineAsm()) {
Msg << "\nPlease check your inline asm statement for invalid "
<< "constraints:\n";
MI->print(Msg, tm_);
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index b44a220..8a124dc 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -543,6 +543,8 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
I != E; ++I) {
MachineInstr *MI = I;
+ if (MI->isDebugValue())
+ continue;
DistanceMap.insert(std::make_pair(MI, Dist++));
// Process all of the operands of the instruction...
@@ -550,7 +552,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
// Unless it is a PHI node. In this case, ONLY process the DEF, not any
// of the uses. They will be handled in other basic blocks.
- if (MI->getOpcode() == TargetInstrInfo::PHI)
+ if (MI->isPHI())
NumOperandsToProcess = 1;
SmallVector<unsigned, 4> UseRegs;
@@ -692,7 +694,7 @@ void LiveVariables::analyzePHINodes(const MachineFunction& Fn) {
for (MachineFunction::const_iterator I = Fn.begin(), E = Fn.end();
I != E; ++I)
for (MachineBasicBlock::const_iterator BBI = I->begin(), BBE = I->end();
- BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI)
+ BBI != BBE && BBI->isPHI(); ++BBI)
for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
PHIVarInfo[BBI->getOperand(i + 1).getMBB()->getNumber()]
.push_back(BBI->getOperand(i).getReg());
@@ -771,8 +773,7 @@ void LiveVariables::addNewBlock(MachineBasicBlock *BB,
// All registers used by PHI nodes in SuccBB must be live through BB.
for (MachineBasicBlock::const_iterator BBI = SuccBB->begin(),
- BBE = SuccBB->end();
- BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI)
+ BBE = SuccBB->end(); BBI != BBE && BBI->isPHI(); ++BBI)
for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
if (BBI->getOperand(i+1).getMBB() == BB)
getVarInfo(BBI->getOperand(i).getReg()).AliveBlocks.set(NumNew);
diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp
index 1121d9b..b4ef648 100644
--- a/lib/CodeGen/LowerSubregs.cpp
+++ b/lib/CodeGen/LowerSubregs.cpp
@@ -129,7 +129,7 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) {
if (MI->getOperand(1).isKill()) {
// We must make sure the super-register gets killed. Replace the
// instruction with KILL.
- MI->setDesc(TII->get(TargetInstrInfo::KILL));
+ MI->setDesc(TII->get(TargetOpcode::KILL));
MI->RemoveOperand(2); // SubIdx
DEBUG(dbgs() << "subreg: replace by: " << *MI);
return true;
@@ -242,7 +242,7 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
// <undef>, we need to make sure it is alive by inserting a KILL
if (MI->getOperand(1).isUndef() && !MI->getOperand(0).isDead()) {
MachineInstrBuilder MIB = BuildMI(*MBB, MI, MI->getDebugLoc(),
- TII->get(TargetInstrInfo::KILL), DstReg);
+ TII->get(TargetOpcode::KILL), DstReg);
if (MI->getOperand(2).isUndef())
MIB.addReg(InsReg, RegState::Undef);
else
@@ -260,7 +260,7 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
// If the source register being inserted is undef, then this becomes a
// KILL.
BuildMI(*MBB, MI, MI->getDebugLoc(),
- TII->get(TargetInstrInfo::KILL), DstSubReg);
+ TII->get(TargetOpcode::KILL), DstSubReg);
else {
bool Emitted = TII->copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1);
(void)Emitted;
@@ -314,11 +314,11 @@ bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) {
mi != me;) {
MachineBasicBlock::iterator nmi = llvm::next(mi);
MachineInstr *MI = mi;
- if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ if (MI->isExtractSubreg()) {
MadeChange |= LowerExtract(MI);
- } else if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
+ } else if (MI->isInsertSubreg()) {
MadeChange |= LowerInsert(MI);
- } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) {
+ } else if (MI->isSubregToReg()) {
MadeChange |= LowerSubregToReg(MI);
}
mi = nmi;
diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp
deleted file mode 100644
index e8bbe21..0000000
--- a/lib/CodeGen/MachOWriter.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-//===-- MachOWriter.cpp - Target-independent Mach-O Writer code -----------===//
-//
-// 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 target-independent Mach-O writer. This file writes
-// out the Mach-O file in the following order:
-//
-// #1 FatHeader (universal-only)
-// #2 FatArch (universal-only, 1 per universal arch)
-// Per arch:
-// #3 Header
-// #4 Load Commands
-// #5 Sections
-// #6 Relocations
-// #7 Symbols
-// #8 Strings
-//
-//===----------------------------------------------------------------------===//
-
-#include "MachOWriter.h"
-#include "llvm/Function.h"
-#include "llvm/CodeGen/FileWriters.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCCodeEmitter.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-using namespace llvm;
-
-namespace llvm {
-MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O,
- TargetMachine &TM,
- const MCAsmInfo *T,
- MCCodeEmitter *MCE) {
- return new MachOWriter(O, TM, T, MCE);
-}
-}
-
-//===----------------------------------------------------------------------===//
-// MachOWriter Implementation
-//===----------------------------------------------------------------------===//
-
-char MachOWriter::ID = 0;
-
-MachOWriter::MachOWriter(formatted_raw_ostream &o, TargetMachine &tm,
- const MCAsmInfo *T, MCCodeEmitter *MCE)
- : MachineFunctionPass(&ID), O(o), TM(tm), MAI(T), MCCE(MCE),
- OutContext(*new MCContext()),
- OutStreamer(*createMachOStreamer(OutContext, O, MCCE)) {
-}
-
-MachOWriter::~MachOWriter() {
- delete &OutStreamer;
- delete &OutContext;
- delete MCCE;
-}
-
-bool MachOWriter::doInitialization(Module &M) {
- // Initialize TargetLoweringObjectFile.
- TM.getTargetLowering()->getObjFileLowering().Initialize(OutContext, TM);
-
- return false;
-}
-
-/// doFinalization - Now that the module has been completely processed, emit
-/// the Mach-O file to 'O'.
-bool MachOWriter::doFinalization(Module &M) {
- OutStreamer.Finish();
- return false;
-}
-
-bool MachOWriter::runOnMachineFunction(MachineFunction &MF) {
- const Function *F = MF.getFunction();
- TargetLoweringObjectFile &TLOF = TM.getTargetLowering()->getObjFileLowering();
- const MCSection *S = TLOF.SectionForGlobal(F, Mang, TM);
- OutStreamer.SwitchSection(S);
-
- for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
- I != E; ++I) {
- // Print a label for the basic block.
- for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
- II != IE; ++II) {
- const MachineInstr *MI = II;
- MCInst OutMI;
- OutMI.setOpcode(MI->getOpcode());
-
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = MI->getOperand(i);
- MCOperand MCOp;
-
- switch (MO.getType()) {
- default:
- MI->dump();
- llvm_unreachable("unknown operand type");
- case MachineOperand::MO_Register:
- // Ignore all implicit register operands.
- if (MO.isImplicit()) continue;
- MCOp = MCOperand::CreateReg(MO.getReg());
- break;
- case MachineOperand::MO_Immediate:
- MCOp = MCOperand::CreateImm(MO.getImm());
- break;
- }
- OutMI.addOperand(MCOp);
- }
-
- OutStreamer.EmitInstruction(OutMI);
- }
- }
-
- return false;
-}
diff --git a/lib/CodeGen/MachOWriter.h b/lib/CodeGen/MachOWriter.h
deleted file mode 100644
index 2e7e67d..0000000
--- a/lib/CodeGen/MachOWriter.h
+++ /dev/null
@@ -1,88 +0,0 @@
-//=== MachOWriter.h - Target-independent Mach-O writer support --*- 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 MachOWriter class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MACHOWRITER_H
-#define MACHOWRITER_H
-
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Target/TargetMachine.h"
-
-namespace llvm {
- class GlobalVariable;
- class Mangler;
- class MCCodeEmitter;
- class MCContext;
- class MCStreamer;
-
- /// MachOWriter - This class implements the common target-independent code for
- /// writing Mach-O files. Targets should derive a class from this to
- /// parameterize the output format.
- ///
- class MachOWriter : public MachineFunctionPass {
- static char ID;
-
- protected:
- /// Output stream to send the resultant object file to.
- ///
- formatted_raw_ostream &O;
-
- /// Target machine description.
- ///
- TargetMachine &TM;
-
- /// Target Asm Printer information.
- ///
- const MCAsmInfo *MAI;
-
- /// MCCE - The MCCodeEmitter object that we are exposing to emit machine
- /// code for functions to the .o file.
- MCCodeEmitter *MCCE;
-
- /// OutContext - This is the context for the output file that we are
- /// streaming. This owns all of the global MC-related objects for the
- /// generated translation unit.
- MCContext &OutContext;
-
- /// OutStreamer - This is the MCStreamer object for the file we are
- /// generating. This contains the transient state for the current
- /// translation unit that we are generating (such as the current section
- /// etc).
- MCStreamer &OutStreamer;
-
- /// Name-mangler for global names.
- ///
- Mangler *Mang;
-
- /// doInitialization - Emit the file header and all of the global variables
- /// for the module to the Mach-O file.
- bool doInitialization(Module &M);
-
- /// doFinalization - Now that the module has been completely processed, emit
- /// the Mach-O file to 'O'.
- bool doFinalization(Module &M);
-
- bool runOnMachineFunction(MachineFunction &MF);
-
- public:
- explicit MachOWriter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, MCCodeEmitter *MCE);
-
- virtual ~MachOWriter();
-
- virtual const char *getPassName() const {
- return "Mach-O Writer";
- }
- };
-}
-
-#endif
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index 9215bd5..655a0bf 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -14,15 +14,18 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/BasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetInstrDesc.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/LeakDetector.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Assembly/Writer.h"
#include <algorithm>
using namespace llvm;
@@ -36,6 +39,18 @@ MachineBasicBlock::~MachineBasicBlock() {
LeakDetector::removeGarbageObject(this);
}
+/// getSymbol - Return the MCSymbol for this basic block.
+///
+MCSymbol *MachineBasicBlock::getSymbol(MCContext &Ctx) const {
+ SmallString<60> Name;
+ const MachineFunction *MF = getParent();
+ raw_svector_ostream(Name)
+ << MF->getTarget().getMCAsmInfo()->getPrivateGlobalPrefix() << "BB"
+ << MF->getFunctionNumber() << '_' << getNumber();
+ return Ctx.GetOrCreateSymbol(Name.str());
+}
+
+
raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineBasicBlock &MBB) {
MBB.print(OS);
return OS;
@@ -525,7 +540,7 @@ bool MachineBasicBlock::CorrectExtraCFGEdges(MachineBasicBlock *DestA,
}
/// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
-/// any DEBUG_VALUE instructions. Return UnknownLoc if there is none.
+/// any DBG_VALUE instructions. Return UnknownLoc if there is none.
DebugLoc
MachineBasicBlock::findDebugLoc(MachineBasicBlock::iterator &MBBI) {
DebugLoc DL;
@@ -533,8 +548,7 @@ MachineBasicBlock::findDebugLoc(MachineBasicBlock::iterator &MBBI) {
if (MBBI != E) {
// Skip debug declarations, we don't want a DebugLoc from them.
MachineBasicBlock::iterator MBBI2 = MBBI;
- while (MBBI2 != E &&
- MBBI2->getOpcode()==TargetInstrInfo::DEBUG_VALUE)
+ while (MBBI2 != E && MBBI2->isDebugValue())
MBBI2++;
if (MBBI2 != E)
DL = MBBI2->getDebugLoc();
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index 1e3e314..f141c56 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -16,7 +16,6 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/config.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -26,12 +25,16 @@
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -70,9 +73,9 @@ FunctionPass *llvm::createMachineFunctionPrinterPass(raw_ostream &OS,
return new Printer(OS, Banner);
}
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
// MachineFunction implementation
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
// Out of line virtual method.
MachineFunctionInfo::~MachineFunctionInfo() {}
@@ -81,8 +84,8 @@ void ilist_traits<MachineBasicBlock>::deleteNode(MachineBasicBlock *MBB) {
MBB->getParent()->DeleteMachineBasicBlock(MBB);
}
-MachineFunction::MachineFunction(Function *F,
- const TargetMachine &TM)
+MachineFunction::MachineFunction(Function *F, const TargetMachine &TM,
+ unsigned FunctionNum)
: Fn(F), Target(TM) {
if (TM.getRegisterInfo())
RegInfo = new (Allocator.Allocate<MachineRegisterInfo>())
@@ -95,16 +98,8 @@ MachineFunction::MachineFunction(Function *F,
ConstantPool = new (Allocator.Allocate<MachineConstantPool>())
MachineConstantPool(TM.getTargetData());
Alignment = TM.getTargetLowering()->getFunctionAlignment(F);
-
- // Set up jump table.
- const TargetData &TD = *TM.getTargetData();
- bool IsPic = TM.getRelocationModel() == Reloc::PIC_;
- unsigned EntrySize = IsPic ? 4 : TD.getPointerSize();
- unsigned TyAlignment = IsPic ?
- TD.getABITypeAlignment(Type::getInt32Ty(F->getContext()))
- : TD.getPointerABIAlignment();
- JumpTableInfo = new (Allocator.Allocate<MachineJumpTableInfo>())
- MachineJumpTableInfo(EntrySize, TyAlignment);
+ FunctionNumber = FunctionNum;
+ JumpTableInfo = 0;
}
MachineFunction::~MachineFunction() {
@@ -121,9 +116,23 @@ MachineFunction::~MachineFunction() {
}
FrameInfo->~MachineFrameInfo(); Allocator.Deallocate(FrameInfo);
ConstantPool->~MachineConstantPool(); Allocator.Deallocate(ConstantPool);
- JumpTableInfo->~MachineJumpTableInfo(); Allocator.Deallocate(JumpTableInfo);
+
+ if (JumpTableInfo) {
+ JumpTableInfo->~MachineJumpTableInfo();
+ Allocator.Deallocate(JumpTableInfo);
+ }
}
+/// getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it
+/// does already exist, allocate one.
+MachineJumpTableInfo *MachineFunction::
+getOrCreateJumpTableInfo(unsigned EntryKind) {
+ if (JumpTableInfo) return JumpTableInfo;
+
+ JumpTableInfo = new (Allocator.Allocate<MachineJumpTableInfo>())
+ MachineJumpTableInfo((MachineJumpTableInfo::JTEntryKind)EntryKind);
+ return JumpTableInfo;
+}
/// RenumberBlocks - This discards all of the MachineBasicBlock numbers and
/// recomputes them. This guarantees that the MBB numbers are sequential,
@@ -178,7 +187,7 @@ MachineFunction::CreateMachineInstr(const TargetInstrDesc &TID,
}
/// CloneMachineInstr - Create a new MachineInstr which is a copy of the
-/// 'Orig' instruction, identical in all ways except the the instruction
+/// 'Orig' instruction, identical in all ways except the instruction
/// has no parent, prev, or next.
///
MachineInstr *
@@ -311,7 +320,8 @@ void MachineFunction::print(raw_ostream &OS) const {
FrameInfo->print(*this, OS);
// Print JumpTable Information
- JumpTableInfo->print(OS);
+ if (JumpTableInfo)
+ JumpTableInfo->print(OS);
// Print Constant Pool
ConstantPool->print(OS);
@@ -435,6 +445,26 @@ DILocation MachineFunction::getDILocation(DebugLoc DL) const {
return DILocation(DebugLocInfo.DebugLocations[Idx]);
}
+
+/// getJTISymbol - Return the MCSymbol for the specified non-empty jump table.
+/// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a
+/// normal 'L' label is returned.
+MCSymbol *MachineFunction::getJTISymbol(unsigned JTI, MCContext &Ctx,
+ bool isLinkerPrivate) const {
+ assert(JumpTableInfo && "No jump tables");
+
+ assert(JTI < JumpTableInfo->getJumpTables().size() && "Invalid JTI!");
+ const MCAsmInfo &MAI = *getTarget().getMCAsmInfo();
+
+ const char *Prefix = isLinkerPrivate ? MAI.getLinkerPrivateGlobalPrefix() :
+ MAI.getPrivateGlobalPrefix();
+ SmallString<60> Name;
+ raw_svector_ostream(Name)
+ << Prefix << "JTI" << getFunctionNumber() << '_' << JTI;
+ return Ctx.GetOrCreateSymbol(Name.str());
+}
+
+
//===----------------------------------------------------------------------===//
// MachineFrameInfo implementation
//===----------------------------------------------------------------------===//
@@ -528,6 +558,39 @@ void MachineFrameInfo::dump(const MachineFunction &MF) const {
// MachineJumpTableInfo implementation
//===----------------------------------------------------------------------===//
+/// getEntrySize - Return the size of each entry in the jump table.
+unsigned MachineJumpTableInfo::getEntrySize(const TargetData &TD) const {
+ // The size of a jump table entry is 4 bytes unless the entry is just the
+ // address of a block, in which case it is the pointer size.
+ switch (getEntryKind()) {
+ case MachineJumpTableInfo::EK_BlockAddress:
+ return TD.getPointerSize();
+ case MachineJumpTableInfo::EK_GPRel32BlockAddress:
+ case MachineJumpTableInfo::EK_LabelDifference32:
+ case MachineJumpTableInfo::EK_Custom32:
+ return 4;
+ }
+ assert(0 && "Unknown jump table encoding!");
+ return ~0;
+}
+
+/// getEntryAlignment - Return the alignment of each entry in the jump table.
+unsigned MachineJumpTableInfo::getEntryAlignment(const TargetData &TD) const {
+ // The alignment of a jump table entry is the alignment of int32 unless the
+ // entry is just the address of a block, in which case it is the pointer
+ // alignment.
+ switch (getEntryKind()) {
+ case MachineJumpTableInfo::EK_BlockAddress:
+ return TD.getPointerABIAlignment();
+ case MachineJumpTableInfo::EK_GPRel32BlockAddress:
+ case MachineJumpTableInfo::EK_LabelDifference32:
+ case MachineJumpTableInfo::EK_Custom32:
+ return TD.getABIIntegerTypeAlignment(32);
+ }
+ assert(0 && "Unknown jump table encoding!");
+ return ~0;
+}
+
/// getJumpTableIndex - Create a new jump table entry in the jump table info
/// or return an existing one.
///
@@ -538,11 +601,11 @@ unsigned MachineJumpTableInfo::getJumpTableIndex(
return JumpTables.size()-1;
}
+
/// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update
/// the jump tables to branch to New instead.
-bool
-MachineJumpTableInfo::ReplaceMBBInJumpTables(MachineBasicBlock *Old,
- MachineBasicBlock *New) {
+bool MachineJumpTableInfo::ReplaceMBBInJumpTables(MachineBasicBlock *Old,
+ MachineBasicBlock *New) {
assert(Old != New && "Not making a change?");
bool MadeChange = false;
for (size_t i = 0, e = JumpTables.size(); i != e; ++i)
@@ -552,10 +615,9 @@ MachineJumpTableInfo::ReplaceMBBInJumpTables(MachineBasicBlock *Old,
/// ReplaceMBBInJumpTable - If Old is a target of the jump tables, update
/// the jump table to branch to New instead.
-bool
-MachineJumpTableInfo::ReplaceMBBInJumpTable(unsigned Idx,
- MachineBasicBlock *Old,
- MachineBasicBlock *New) {
+bool MachineJumpTableInfo::ReplaceMBBInJumpTable(unsigned Idx,
+ MachineBasicBlock *Old,
+ MachineBasicBlock *New) {
assert(Old != New && "Not making a change?");
bool MadeChange = false;
MachineJumpTableEntry &JTE = JumpTables[Idx];
diff --git a/lib/CodeGen/MachineFunctionAnalysis.cpp b/lib/CodeGen/MachineFunctionAnalysis.cpp
index f5febc5..8d87e3e 100644
--- a/lib/CodeGen/MachineFunctionAnalysis.cpp
+++ b/lib/CodeGen/MachineFunctionAnalysis.cpp
@@ -36,7 +36,7 @@ MachineFunctionAnalysis::~MachineFunctionAnalysis() {
bool MachineFunctionAnalysis::runOnFunction(Function &F) {
assert(!MF && "MachineFunctionAnalysis already initialized!");
- MF = new MachineFunction(&F, TM);
+ MF = new MachineFunction(&F, TM, NextFnNum++);
return false;
}
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index ef2fcee..b6d98e8 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -127,7 +127,8 @@ void MachineOperand::ChangeToImmediate(int64_t ImmVal) {
/// the specified value. If an operand is known to be an register already,
/// the setReg method should be used.
void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
- bool isKill, bool isDead, bool isUndef) {
+ bool isKill, bool isDead, bool isUndef,
+ bool isDebug) {
// If this operand is already a register operand, use setReg to update the
// register's use/def lists.
if (isReg()) {
@@ -152,6 +153,7 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
IsDead = isDead;
IsUndef = isUndef;
IsEarlyClobber = false;
+ IsDebug = isDebug;
SubReg = 0;
}
@@ -303,7 +305,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {
MachineMemOperand::MachineMemOperand(const Value *v, unsigned int f,
int64_t o, uint64_t s, unsigned int a)
: Offset(o), Size(s), V(v),
- Flags((f & 7) | ((Log2_32(a) + 1) << 3)) {
+ Flags((f & ((1 << MOMaxBits) - 1)) | ((Log2_32(a) + 1) << MOMaxBits)) {
assert(getBaseAlignment() == a && "Alignment is not a power of 2!");
assert((isLoad() || isStore()) && "Not a load/store!");
}
@@ -325,7 +327,8 @@ void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
if (MMO->getBaseAlignment() >= getBaseAlignment()) {
// Update the alignment value.
- Flags = (Flags & 7) | ((Log2_32(MMO->getBaseAlignment()) + 1) << 3);
+ Flags = (Flags & ((1 << MOMaxBits) - 1)) |
+ ((Log2_32(MMO->getBaseAlignment()) + 1) << MOMaxBits);
// Also update the base and offset, because the new alignment may
// not be applicable with the old ones.
V = MMO->getValue();
@@ -740,20 +743,6 @@ unsigned MachineInstr::getNumExplicitOperands() const {
}
-/// isLabel - Returns true if the MachineInstr represents a label.
-///
-bool MachineInstr::isLabel() const {
- return getOpcode() == TargetInstrInfo::DBG_LABEL ||
- getOpcode() == TargetInstrInfo::EH_LABEL ||
- getOpcode() == TargetInstrInfo::GC_LABEL;
-}
-
-/// isDebugLabel - Returns true if the MachineInstr represents a debug label.
-///
-bool MachineInstr::isDebugLabel() const {
- return getOpcode() == TargetInstrInfo::DBG_LABEL;
-}
-
/// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of
/// the specific register or -1 if it is not found. It further tightens
/// the search criteria to a use that kills the register if isKill is true.
@@ -819,7 +808,7 @@ int MachineInstr::findFirstPredOperandIdx() const {
/// first tied use operand index by reference is UseOpIdx is not null.
bool MachineInstr::
isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const {
- if (getOpcode() == TargetInstrInfo::INLINEASM) {
+ if (isInlineAsm()) {
assert(DefOpIdx >= 2);
const MachineOperand &MO = getOperand(DefOpIdx);
if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0)
@@ -878,7 +867,7 @@ isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const {
/// operand index by reference.
bool MachineInstr::
isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const {
- if (getOpcode() == TargetInstrInfo::INLINEASM) {
+ if (isInlineAsm()) {
const MachineOperand &MO = getOperand(UseOpIdx);
if (!MO.isReg() || !MO.isUse() || MO.getReg() == 0)
return false;
@@ -1046,7 +1035,7 @@ bool MachineInstr::hasVolatileMemoryRef() const {
/// isInvariantLoad - Return true if this instruction is loading from a
/// location whose value is invariant across the function. For example,
-/// loading a value from the constant pool or from from the argument area
+/// loading a value from the constant pool or from the argument area
/// of a function if it does not change. This should only return true of
/// *all* loads the instruction does are invariant (if it does multiple loads).
bool MachineInstr::isInvariantLoad(AliasAnalysis *AA) const {
@@ -1088,7 +1077,7 @@ bool MachineInstr::isInvariantLoad(AliasAnalysis *AA) const {
/// merges together the same virtual register, return the register, otherwise
/// return 0.
unsigned MachineInstr::isConstantValuePHI() const {
- if (getOpcode() != TargetInstrInfo::PHI)
+ if (!isPHI())
return 0;
assert(getNumOperands() >= 3 &&
"It's illegal to have a PHI without source operands");
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp
index ffcc8ab..92c84f3 100644
--- a/lib/CodeGen/MachineLICM.cpp
+++ b/lib/CodeGen/MachineLICM.cpp
@@ -336,7 +336,7 @@ static bool HasPHIUses(unsigned Reg, MachineRegisterInfo *RegInfo) {
for (MachineRegisterInfo::use_iterator UI = RegInfo->use_begin(Reg),
UE = RegInfo->use_end(); UI != UE; ++UI) {
MachineInstr *UseMI = &*UI;
- if (UseMI->getOpcode() == TargetInstrInfo::PHI)
+ if (UseMI->isPHI())
return true;
}
return false;
@@ -363,7 +363,7 @@ bool MachineLICM::isLoadFromConstantMemory(MachineInstr *MI) {
/// IsProfitableToHoist - Return true if it is potentially profitable to hoist
/// the given loop invariant.
bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) {
- if (MI.getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
+ if (MI.isImplicitDef())
return false;
// FIXME: For now, only hoist re-materilizable instructions. LICM will
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index ed5bb5e..5052af7 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -40,6 +40,7 @@ MachineModuleInfoImpl::~MachineModuleInfoImpl() {}
MachineModuleInfo::MachineModuleInfo()
: ImmutablePass(&ID)
, ObjFileMMI(0)
+, CurCallSite(0)
, CallsEHReturn(0)
, CallsUnwindInit(0)
, DbgInfoAvailable(false) {
@@ -71,6 +72,7 @@ void MachineModuleInfo::EndFunction() {
// Clean up exception info.
LandingPads.clear();
+ CallSiteMap.clear();
TypeInfos.clear();
FilterIds.clear();
FilterEnds.clear();
diff --git a/lib/CodeGen/MachineModuleInfoImpls.cpp b/lib/CodeGen/MachineModuleInfoImpls.cpp
index 7a62929..39d2c75 100644
--- a/lib/CodeGen/MachineModuleInfoImpls.cpp
+++ b/lib/CodeGen/MachineModuleInfoImpls.cpp
@@ -22,22 +22,23 @@ using namespace llvm;
// Out of line virtual method.
void MachineModuleInfoMachO::Anchor() {}
-
+void MachineModuleInfoELF::Anchor() {}
static int SortSymbolPair(const void *LHS, const void *RHS) {
const MCSymbol *LHSS =
- ((const std::pair<const MCSymbol*, const MCSymbol*>*)LHS)->first;
+ ((const std::pair<MCSymbol*, MCSymbol*>*)LHS)->first;
const MCSymbol *RHSS =
- ((const std::pair<const MCSymbol*, const MCSymbol*>*)RHS)->first;
+ ((const std::pair<MCSymbol*, MCSymbol*>*)RHS)->first;
return LHSS->getName().compare(RHSS->getName());
}
/// GetSortedStubs - Return the entries from a DenseMap in a deterministic
/// sorted orer.
-MachineModuleInfoMachO::SymbolListTy
-MachineModuleInfoMachO::GetSortedStubs(const DenseMap<const MCSymbol*,
- const MCSymbol*> &Map) {
- MachineModuleInfoMachO::SymbolListTy List(Map.begin(), Map.end());
+MachineModuleInfoImpl::SymbolListTy
+MachineModuleInfoImpl::GetSortedStubs(const DenseMap<MCSymbol*,
+ MCSymbol*> &Map) {
+ MachineModuleInfoImpl::SymbolListTy List(Map.begin(), Map.end());
+
if (!List.empty())
qsort(&List[0], List.size(), sizeof(List[0]), SortSymbolPair);
return List;
diff --git a/lib/CodeGen/MachineSSAUpdater.cpp b/lib/CodeGen/MachineSSAUpdater.cpp
index 467ea5d..2255dc3 100644
--- a/lib/CodeGen/MachineSSAUpdater.cpp
+++ b/lib/CodeGen/MachineSSAUpdater.cpp
@@ -20,6 +20,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -92,13 +93,13 @@ unsigned LookForIdenticalPHI(MachineBasicBlock *BB,
return 0;
MachineBasicBlock::iterator I = BB->front();
- if (I->getOpcode() != TargetInstrInfo::PHI)
+ if (!I->isPHI())
return 0;
AvailableValsTy AVals;
for (unsigned i = 0, e = PredValues.size(); i != e; ++i)
AVals[PredValues[i].first] = PredValues[i].second;
- while (I != BB->end() && I->getOpcode() == TargetInstrInfo::PHI) {
+ while (I != BB->end() && I->isPHI()) {
bool Same = true;
for (unsigned i = 1, e = I->getNumOperands(); i != e; i += 2) {
unsigned SrcReg = I->getOperand(i).getReg();
@@ -155,7 +156,7 @@ unsigned MachineSSAUpdater::GetValueInMiddleOfBlock(MachineBasicBlock *BB) {
// If there are no predecessors, just return undef.
if (BB->pred_empty()) {
// Insert an implicit_def to represent an undef value.
- MachineInstr *NewDef = InsertNewDef(TargetInstrInfo::IMPLICIT_DEF,
+ MachineInstr *NewDef = InsertNewDef(TargetOpcode::IMPLICIT_DEF,
BB, BB->getFirstTerminator(),
VRC, MRI, TII);
return NewDef->getOperand(0).getReg();
@@ -192,7 +193,7 @@ unsigned MachineSSAUpdater::GetValueInMiddleOfBlock(MachineBasicBlock *BB) {
// Otherwise, we do need a PHI: insert one now.
MachineBasicBlock::iterator Loc = BB->empty() ? BB->end() : BB->front();
- MachineInstr *InsertedPHI = InsertNewDef(TargetInstrInfo::PHI, BB,
+ MachineInstr *InsertedPHI = InsertNewDef(TargetOpcode::PHI, BB,
Loc, VRC, MRI, TII);
// Fill in all the predecessors of the PHI.
@@ -231,7 +232,7 @@ MachineBasicBlock *findCorrespondingPred(const MachineInstr *MI,
void MachineSSAUpdater::RewriteUse(MachineOperand &U) {
MachineInstr *UseMI = U.getParent();
unsigned NewVR = 0;
- if (UseMI->getOpcode() == TargetInstrInfo::PHI) {
+ if (UseMI->isPHI()) {
MachineBasicBlock *SourceBB = findCorrespondingPred(UseMI, &U);
NewVR = GetValueAtEndOfBlockInternal(SourceBB);
} else {
@@ -277,7 +278,7 @@ unsigned MachineSSAUpdater::GetValueAtEndOfBlockInternal(MachineBasicBlock *BB){
// it. When we get back to the first instance of the recursion we will fill
// in the PHI node.
MachineBasicBlock::iterator Loc = BB->empty() ? BB->end() : BB->front();
- MachineInstr *NewPHI = InsertNewDef(TargetInstrInfo::PHI, BB, Loc,
+ MachineInstr *NewPHI = InsertNewDef(TargetOpcode::PHI, BB, Loc,
VRC, MRI,TII);
unsigned NewVR = NewPHI->getOperand(0).getReg();
InsertRes.first->second = NewVR;
@@ -289,7 +290,7 @@ unsigned MachineSSAUpdater::GetValueAtEndOfBlockInternal(MachineBasicBlock *BB){
// be invalidated.
if (BB->pred_empty()) {
// Insert an implicit_def to represent an undef value.
- MachineInstr *NewDef = InsertNewDef(TargetInstrInfo::IMPLICIT_DEF,
+ MachineInstr *NewDef = InsertNewDef(TargetOpcode::IMPLICIT_DEF,
BB, BB->getFirstTerminator(),
VRC, MRI, TII);
return InsertRes.first->second = NewDef->getOperand(0).getReg();
@@ -358,7 +359,7 @@ unsigned MachineSSAUpdater::GetValueAtEndOfBlockInternal(MachineBasicBlock *BB){
MachineInstr *InsertedPHI;
if (InsertedVal == 0) {
MachineBasicBlock::iterator Loc = BB->empty() ? BB->end() : BB->front();
- InsertedPHI = InsertNewDef(TargetInstrInfo::PHI, BB, Loc,
+ InsertedPHI = InsertNewDef(TargetOpcode::PHI, BB, Loc,
VRC, MRI, TII);
InsertedVal = InsertedPHI->getOperand(0).getReg();
} else {
diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp
index c177e3c..c391576 100644
--- a/lib/CodeGen/MachineSink.cpp
+++ b/lib/CodeGen/MachineSink.cpp
@@ -77,7 +77,7 @@ bool MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
// Determine the block of the use.
MachineInstr *UseInst = &*I;
MachineBasicBlock *UseBlock = UseInst->getParent();
- if (UseInst->getOpcode() == TargetInstrInfo::PHI) {
+ if (UseInst->isPHI()) {
// PHI nodes use the operand in the predecessor block, not the block with
// the PHI.
UseBlock = UseInst->getOperand(I.getOperandNo()+1).getMBB();
@@ -269,8 +269,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
// Determine where to insert into. Skip phi nodes.
MachineBasicBlock::iterator InsertPos = SuccToSinkTo->begin();
- while (InsertPos != SuccToSinkTo->end() &&
- InsertPos->getOpcode() == TargetInstrInfo::PHI)
+ while (InsertPos != SuccToSinkTo->end() && InsertPos->isPHI())
++InsertPos;
// Move the instruction.
diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp
index 584c21b..434a1e8 100644
--- a/lib/CodeGen/MachineVerifier.cpp
+++ b/lib/CodeGen/MachineVerifier.cpp
@@ -590,7 +590,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
// must be live in. PHI instructions are handled separately.
if (MInfo.regsKilled.count(Reg))
report("Using a killed virtual register", MO, MONum);
- else if (MI->getOpcode() != TargetInstrInfo::PHI)
+ else if (!MI->isPHI())
MInfo.vregsLiveIn.insert(std::make_pair(Reg, MI));
}
}
@@ -650,10 +650,8 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
}
case MachineOperand::MO_MachineBasicBlock:
- if (MI->getOpcode() == TargetInstrInfo::PHI) {
- if (!MO->getMBB()->isSuccessor(MI->getParent()))
- report("PHI operand is not in the CFG", MO, MONum);
- }
+ if (MI->isPHI() && !MO->getMBB()->isSuccessor(MI->getParent()))
+ report("PHI operand is not in the CFG", MO, MONum);
break;
default:
@@ -783,7 +781,7 @@ void MachineVerifier::calcRegsRequired() {
// calcRegsPassed has been run so BBInfo::isLiveOut is valid.
void MachineVerifier::checkPHIOps(const MachineBasicBlock *MBB) {
for (MachineBasicBlock::const_iterator BBI = MBB->begin(), BBE = MBB->end();
- BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) {
+ BBI != BBE && BBI->isPHI(); ++BBI) {
DenseSet<const MachineBasicBlock*> seen;
for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) {
diff --git a/lib/CodeGen/Makefile b/lib/CodeGen/Makefile
index 8c0204c..4ab3e3c 100644
--- a/lib/CodeGen/Makefile
+++ b/lib/CodeGen/Makefile
@@ -11,7 +11,6 @@ LEVEL = ../..
LIBRARYNAME = LLVMCodeGen
PARALLEL_DIRS = SelectionDAG AsmPrinter
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/CodeGen/OptimizeExts.cpp b/lib/CodeGen/OptimizeExts.cpp
index 096f9d4..acb6869 100644
--- a/lib/CodeGen/OptimizeExts.cpp
+++ b/lib/CodeGen/OptimizeExts.cpp
@@ -110,7 +110,7 @@ bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB,
MachineInstr *UseMI = &*UI;
if (UseMI == MI)
continue;
- if (UseMI->getOpcode() == TargetInstrInfo::PHI) {
+ if (UseMI->isPHI()) {
ExtendLife = false;
continue;
}
@@ -150,7 +150,7 @@ bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB,
UI = MRI->use_begin(DstReg);
for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
++UI)
- if (UI->getOpcode() == TargetInstrInfo::PHI)
+ if (UI->isPHI())
PHIBBs.insert(UI->getParent());
const TargetRegisterClass *RC = MRI->getRegClass(SrcReg);
@@ -162,7 +162,7 @@ bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB,
continue;
unsigned NewVR = MRI->createVirtualRegister(RC);
BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(),
- TII->get(TargetInstrInfo::EXTRACT_SUBREG), NewVR)
+ TII->get(TargetOpcode::EXTRACT_SUBREG), NewVR)
.addReg(DstReg).addImm(SubIdx);
UseMO->setReg(NewVR);
++NumReuse;
diff --git a/lib/CodeGen/OptimizePHIs.cpp b/lib/CodeGen/OptimizePHIs.cpp
new file mode 100644
index 0000000..2717d4d
--- /dev/null
+++ b/lib/CodeGen/OptimizePHIs.cpp
@@ -0,0 +1,189 @@
+//===-- OptimizePHIs.cpp - Optimize machine instruction PHIs --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass optimizes machine instruction PHIs to take advantage of
+// opportunities created during DAG legalization.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "phi-opt"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Function.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/Statistic.h"
+using namespace llvm;
+
+STATISTIC(NumPHICycles, "Number of PHI cycles replaced");
+STATISTIC(NumDeadPHICycles, "Number of dead PHI cycles");
+
+namespace {
+ class OptimizePHIs : public MachineFunctionPass {
+ MachineRegisterInfo *MRI;
+ const TargetInstrInfo *TII;
+
+ public:
+ static char ID; // Pass identification
+ OptimizePHIs() : MachineFunctionPass(&ID) {}
+
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ private:
+ typedef SmallPtrSet<MachineInstr*, 16> InstrSet;
+ typedef SmallPtrSetIterator<MachineInstr*> InstrSetIterator;
+
+ bool IsSingleValuePHICycle(MachineInstr *MI, unsigned &SingleValReg,
+ InstrSet &PHIsInCycle);
+ bool IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle);
+ bool OptimizeBB(MachineBasicBlock &MBB);
+ };
+}
+
+char OptimizePHIs::ID = 0;
+static RegisterPass<OptimizePHIs>
+X("opt-phis", "Optimize machine instruction PHIs");
+
+FunctionPass *llvm::createOptimizePHIsPass() { return new OptimizePHIs(); }
+
+bool OptimizePHIs::runOnMachineFunction(MachineFunction &Fn) {
+ MRI = &Fn.getRegInfo();
+ TII = Fn.getTarget().getInstrInfo();
+
+ // Find dead PHI cycles and PHI cycles that can be replaced by a single
+ // value. InstCombine does these optimizations, but DAG legalization may
+ // introduce new opportunities, e.g., when i64 values are split up for
+ // 32-bit targets.
+ bool Changed = false;
+ for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
+ Changed |= OptimizeBB(*I);
+
+ return Changed;
+}
+
+/// IsSingleValuePHICycle - Check if MI is a PHI where all the source operands
+/// are copies of SingleValReg, possibly via copies through other PHIs. If
+/// SingleValReg is zero on entry, it is set to the register with the single
+/// non-copy value. PHIsInCycle is a set used to keep track of the PHIs that
+/// have been scanned.
+bool OptimizePHIs::IsSingleValuePHICycle(MachineInstr *MI,
+ unsigned &SingleValReg,
+ InstrSet &PHIsInCycle) {
+ assert(MI->isPHI() && "IsSingleValuePHICycle expects a PHI instruction");
+ unsigned DstReg = MI->getOperand(0).getReg();
+
+ // See if we already saw this register.
+ if (!PHIsInCycle.insert(MI))
+ return true;
+
+ // Don't scan crazily complex things.
+ if (PHIsInCycle.size() == 16)
+ return false;
+
+ // Scan the PHI operands.
+ for (unsigned i = 1; i != MI->getNumOperands(); i += 2) {
+ unsigned SrcReg = MI->getOperand(i).getReg();
+ if (SrcReg == DstReg)
+ continue;
+ MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
+
+ // Skip over register-to-register moves.
+ unsigned MvSrcReg, MvDstReg, SrcSubIdx, DstSubIdx;
+ if (SrcMI &&
+ TII->isMoveInstr(*SrcMI, MvSrcReg, MvDstReg, SrcSubIdx, DstSubIdx) &&
+ SrcSubIdx == 0 && DstSubIdx == 0 &&
+ TargetRegisterInfo::isVirtualRegister(MvSrcReg))
+ SrcMI = MRI->getVRegDef(MvSrcReg);
+ if (!SrcMI)
+ return false;
+
+ if (SrcMI->isPHI()) {
+ if (!IsSingleValuePHICycle(SrcMI, SingleValReg, PHIsInCycle))
+ return false;
+ } else {
+ // Fail if there is more than one non-phi/non-move register.
+ if (SingleValReg != 0)
+ return false;
+ SingleValReg = SrcReg;
+ }
+ }
+ return true;
+}
+
+/// IsDeadPHICycle - Check if the register defined by a PHI is only used by
+/// other PHIs in a cycle.
+bool OptimizePHIs::IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle) {
+ assert(MI->isPHI() && "IsDeadPHICycle expects a PHI instruction");
+ unsigned DstReg = MI->getOperand(0).getReg();
+ assert(TargetRegisterInfo::isVirtualRegister(DstReg) &&
+ "PHI destination is not a virtual register");
+
+ // See if we already saw this register.
+ if (!PHIsInCycle.insert(MI))
+ return true;
+
+ // Don't scan crazily complex things.
+ if (PHIsInCycle.size() == 16)
+ return false;
+
+ for (MachineRegisterInfo::use_iterator I = MRI->use_begin(DstReg),
+ E = MRI->use_end(); I != E; ++I) {
+ MachineInstr *UseMI = &*I;
+ if (!UseMI->isPHI() || !IsDeadPHICycle(UseMI, PHIsInCycle))
+ return false;
+ }
+
+ return true;
+}
+
+/// OptimizeBB - Remove dead PHI cycles and PHI cycles that can be replaced by
+/// a single value.
+bool OptimizePHIs::OptimizeBB(MachineBasicBlock &MBB) {
+ bool Changed = false;
+ for (MachineBasicBlock::iterator
+ MII = MBB.begin(), E = MBB.end(); MII != E; ) {
+ MachineInstr *MI = &*MII++;
+ if (!MI->isPHI())
+ break;
+
+ // Check for single-value PHI cycles.
+ unsigned SingleValReg = 0;
+ InstrSet PHIsInCycle;
+ if (IsSingleValuePHICycle(MI, SingleValReg, PHIsInCycle) &&
+ SingleValReg != 0) {
+ MRI->replaceRegWith(MI->getOperand(0).getReg(), SingleValReg);
+ MI->eraseFromParent();
+ ++NumPHICycles;
+ Changed = true;
+ continue;
+ }
+
+ // Check for dead PHI cycles.
+ PHIsInCycle.clear();
+ if (IsDeadPHICycle(MI, PHIsInCycle)) {
+ for (InstrSetIterator PI = PHIsInCycle.begin(), PE = PHIsInCycle.end();
+ PI != PE; ++PI) {
+ MachineInstr *PhiMI = *PI;
+ if (&*MII == PhiMI)
+ ++MII;
+ PhiMI->eraseFromParent();
+ }
+ ++NumDeadPHICycles;
+ Changed = true;
+ }
+ }
+ return Changed;
+}
diff --git a/lib/CodeGen/PBQP/AnnotatedGraph.h b/lib/CodeGen/PBQP/AnnotatedGraph.h
deleted file mode 100644
index 738dea0..0000000
--- a/lib/CodeGen/PBQP/AnnotatedGraph.h
+++ /dev/null
@@ -1,184 +0,0 @@
-//===-- AnnotatedGraph.h - Annotated PBQP Graph -----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Annotated PBQP Graph class. This class is used internally by the PBQP solver
-// to cache information to speed up reduction.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_PBQP_ANNOTATEDGRAPH_H
-#define LLVM_CODEGEN_PBQP_ANNOTATEDGRAPH_H
-
-#include "GraphBase.h"
-
-namespace PBQP {
-
-
-template <typename NodeData, typename EdgeData> class AnnotatedEdge;
-
-template <typename NodeData, typename EdgeData>
-class AnnotatedNode : public NodeBase<AnnotatedNode<NodeData, EdgeData>,
- AnnotatedEdge<NodeData, EdgeData> > {
-private:
-
- NodeData nodeData;
-
-public:
-
- AnnotatedNode(const Vector &costs, const NodeData &nodeData) :
- NodeBase<AnnotatedNode<NodeData, EdgeData>,
- AnnotatedEdge<NodeData, EdgeData> >(costs),
- nodeData(nodeData) {}
-
- NodeData& getNodeData() { return nodeData; }
- const NodeData& getNodeData() const { return nodeData; }
-
-};
-
-template <typename NodeData, typename EdgeData>
-class AnnotatedEdge : public EdgeBase<AnnotatedNode<NodeData, EdgeData>,
- AnnotatedEdge<NodeData, EdgeData> > {
-private:
-
- typedef typename GraphBase<AnnotatedNode<NodeData, EdgeData>,
- AnnotatedEdge<NodeData, EdgeData> >::NodeIterator
- NodeIterator;
-
- EdgeData edgeData;
-
-public:
-
-
- AnnotatedEdge(const NodeIterator &node1Itr, const NodeIterator &node2Itr,
- const Matrix &costs, const EdgeData &edgeData) :
- EdgeBase<AnnotatedNode<NodeData, EdgeData>,
- AnnotatedEdge<NodeData, EdgeData> >(node1Itr, node2Itr, costs),
- edgeData(edgeData) {}
-
- EdgeData& getEdgeData() { return edgeData; }
- const EdgeData& getEdgeData() const { return edgeData; }
-
-};
-
-template <typename NodeData, typename EdgeData>
-class AnnotatedGraph : public GraphBase<AnnotatedNode<NodeData, EdgeData>,
- AnnotatedEdge<NodeData, EdgeData> > {
-private:
-
- typedef GraphBase<AnnotatedNode<NodeData, EdgeData>,
- AnnotatedEdge<NodeData, EdgeData> > PGraph;
-
- typedef AnnotatedNode<NodeData, EdgeData> NodeEntry;
- typedef AnnotatedEdge<NodeData, EdgeData> EdgeEntry;
-
-
- void copyFrom(const AnnotatedGraph &other) {
- if (!other.areNodeIDsValid()) {
- other.assignNodeIDs();
- }
- std::vector<NodeIterator> newNodeItrs(other.getNumNodes());
-
- for (ConstNodeIterator nItr = other.nodesBegin(), nEnd = other.nodesEnd();
- nItr != nEnd; ++nItr) {
- newNodeItrs[other.getNodeID(nItr)] = addNode(other.getNodeCosts(nItr));
- }
-
- for (ConstEdgeIterator eItr = other.edgesBegin(), eEnd = other.edgesEnd();
- eItr != eEnd; ++eItr) {
-
- unsigned node1ID = other.getNodeID(other.getEdgeNode1(eItr)),
- node2ID = other.getNodeID(other.getEdgeNode2(eItr));
-
- addEdge(newNodeItrs[node1ID], newNodeItrs[node2ID],
- other.getEdgeCosts(eItr), other.getEdgeData(eItr));
- }
-
- }
-
-public:
-
- typedef typename PGraph::NodeIterator NodeIterator;
- typedef typename PGraph::ConstNodeIterator ConstNodeIterator;
- typedef typename PGraph::EdgeIterator EdgeIterator;
- typedef typename PGraph::ConstEdgeIterator ConstEdgeIterator;
-
- AnnotatedGraph() {}
-
- AnnotatedGraph(const AnnotatedGraph &other) {
- copyFrom(other);
- }
-
- AnnotatedGraph& operator=(const AnnotatedGraph &other) {
- PGraph::clear();
- copyFrom(other);
- return *this;
- }
-
- NodeIterator addNode(const Vector &costs, const NodeData &data) {
- return PGraph::addConstructedNode(NodeEntry(costs, data));
- }
-
- EdgeIterator addEdge(const NodeIterator &node1Itr,
- const NodeIterator &node2Itr,
- const Matrix &costs, const EdgeData &data) {
- return PGraph::addConstructedEdge(EdgeEntry(node1Itr, node2Itr,
- costs, data));
- }
-
- NodeData& getNodeData(const NodeIterator &nodeItr) {
- return PGraph::getNodeEntry(nodeItr).getNodeData();
- }
-
- const NodeData& getNodeData(const NodeIterator &nodeItr) const {
- return PGraph::getNodeEntry(nodeItr).getNodeData();
- }
-
- EdgeData& getEdgeData(const EdgeIterator &edgeItr) {
- return PGraph::getEdgeEntry(edgeItr).getEdgeData();
- }
-
- const EdgeEntry& getEdgeData(const EdgeIterator &edgeItr) const {
- return PGraph::getEdgeEntry(edgeItr).getEdgeData();
- }
-
- SimpleGraph toSimpleGraph() const {
- SimpleGraph g;
-
- if (!PGraph::areNodeIDsValid()) {
- PGraph::assignNodeIDs();
- }
- std::vector<SimpleGraph::NodeIterator> newNodeItrs(PGraph::getNumNodes());
-
- for (ConstNodeIterator nItr = PGraph::nodesBegin(),
- nEnd = PGraph::nodesEnd();
- nItr != nEnd; ++nItr) {
-
- newNodeItrs[getNodeID(nItr)] = g.addNode(getNodeCosts(nItr));
- }
-
- for (ConstEdgeIterator
- eItr = PGraph::edgesBegin(), eEnd = PGraph::edgesEnd();
- eItr != eEnd; ++eItr) {
-
- unsigned node1ID = getNodeID(getEdgeNode1(eItr)),
- node2ID = getNodeID(getEdgeNode2(eItr));
-
- g.addEdge(newNodeItrs[node1ID], newNodeItrs[node2ID],
- getEdgeCosts(eItr));
- }
-
- return g;
- }
-
-};
-
-
-}
-
-#endif // LLVM_CODEGEN_PBQP_ANNOTATEDGRAPH_H
diff --git a/lib/CodeGen/PBQP/ExhaustiveSolver.h b/lib/CodeGen/PBQP/ExhaustiveSolver.h
deleted file mode 100644
index 35ec4f1..0000000
--- a/lib/CodeGen/PBQP/ExhaustiveSolver.h
+++ /dev/null
@@ -1,110 +0,0 @@
-//===-- ExhaustiveSolver.h - Brute Force PBQP Solver ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Uses a trivial brute force algorithm to solve a PBQP problem.
-// PBQP is NP-HARD - This solver should only be used for debugging small
-// problems.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_PBQP_EXHAUSTIVESOLVER_H
-#define LLVM_CODEGEN_PBQP_EXHAUSTIVESOLVER_H
-
-#include "Solver.h"
-
-namespace PBQP {
-
-/// A brute force PBQP solver. This solver takes exponential time. It should
-/// only be used for debugging purposes.
-class ExhaustiveSolverImpl {
-private:
-
- const SimpleGraph &g;
-
- PBQPNum getSolutionCost(const Solution &solution) const {
- PBQPNum cost = 0.0;
-
- for (SimpleGraph::ConstNodeIterator
- nodeItr = g.nodesBegin(), nodeEnd = g.nodesEnd();
- nodeItr != nodeEnd; ++nodeItr) {
-
- unsigned nodeId = g.getNodeID(nodeItr);
-
- cost += g.getNodeCosts(nodeItr)[solution.getSelection(nodeId)];
- }
-
- for (SimpleGraph::ConstEdgeIterator
- edgeItr = g.edgesBegin(), edgeEnd = g.edgesEnd();
- edgeItr != edgeEnd; ++edgeItr) {
-
- SimpleGraph::ConstNodeIterator n1 = g.getEdgeNode1Itr(edgeItr),
- n2 = g.getEdgeNode2Itr(edgeItr);
- unsigned sol1 = solution.getSelection(g.getNodeID(n1)),
- sol2 = solution.getSelection(g.getNodeID(n2));
-
- cost += g.getEdgeCosts(edgeItr)[sol1][sol2];
- }
-
- return cost;
- }
-
-public:
-
- ExhaustiveSolverImpl(const SimpleGraph &g) : g(g) {}
-
- Solution solve() const {
- Solution current(g.getNumNodes(), true), optimal(current);
-
- PBQPNum bestCost = std::numeric_limits<PBQPNum>::infinity();
- bool finished = false;
-
- while (!finished) {
- PBQPNum currentCost = getSolutionCost(current);
-
- if (currentCost < bestCost) {
- optimal = current;
- bestCost = currentCost;
- }
-
- // assume we're done.
- finished = true;
-
- for (unsigned i = 0; i < g.getNumNodes(); ++i) {
- if (current.getSelection(i) ==
- (g.getNodeCosts(g.getNodeItr(i)).getLength() - 1)) {
- current.setSelection(i, 0);
- }
- else {
- current.setSelection(i, current.getSelection(i) + 1);
- finished = false;
- break;
- }
- }
-
- }
-
- optimal.setSolutionCost(bestCost);
-
- return optimal;
- }
-
-};
-
-class ExhaustiveSolver : public Solver {
-public:
- ~ExhaustiveSolver() {}
- Solution solve(const SimpleGraph &g) const {
- ExhaustiveSolverImpl solver(g);
- return solver.solve();
- }
-};
-
-}
-
-#endif // LLVM_CODGEN_PBQP_EXHAUSTIVESOLVER_HPP
diff --git a/lib/CodeGen/PBQP/Graph.h b/lib/CodeGen/PBQP/Graph.h
new file mode 100644
index 0000000..b2224cb
--- /dev/null
+++ b/lib/CodeGen/PBQP/Graph.h
@@ -0,0 +1,425 @@
+//===-------------------- Graph.h - PBQP Graph ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// PBQP Graph class.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_PBQP_GRAPH_H
+#define LLVM_CODEGEN_PBQP_GRAPH_H
+
+#include "Math.h"
+
+#include <list>
+#include <vector>
+#include <map>
+
+namespace PBQP {
+
+ /// PBQP Graph class.
+ /// Instances of this class describe PBQP problems.
+ class Graph {
+ private:
+
+ // ----- TYPEDEFS -----
+ class NodeEntry;
+ class EdgeEntry;
+
+ typedef std::list<NodeEntry> NodeList;
+ typedef std::list<EdgeEntry> EdgeList;
+
+ public:
+
+ typedef NodeList::iterator NodeItr;
+ typedef NodeList::const_iterator ConstNodeItr;
+
+ typedef EdgeList::iterator EdgeItr;
+ typedef EdgeList::const_iterator ConstEdgeItr;
+
+ private:
+
+ typedef std::list<EdgeItr> AdjEdgeList;
+
+ public:
+
+ typedef AdjEdgeList::iterator AdjEdgeItr;
+
+ private:
+
+ class NodeEntry {
+ private:
+ Vector costs;
+ AdjEdgeList adjEdges;
+ unsigned degree;
+ void *data;
+ public:
+ NodeEntry(const Vector &costs) : costs(costs), degree(0) {}
+ Vector& getCosts() { return costs; }
+ const Vector& getCosts() const { return costs; }
+ unsigned getDegree() const { return degree; }
+ AdjEdgeItr edgesBegin() { return adjEdges.begin(); }
+ AdjEdgeItr edgesEnd() { return adjEdges.end(); }
+ AdjEdgeItr addEdge(EdgeItr e) {
+ ++degree;
+ return adjEdges.insert(adjEdges.end(), e);
+ }
+ void removeEdge(AdjEdgeItr ae) {
+ --degree;
+ adjEdges.erase(ae);
+ }
+ void setData(void *data) { this->data = data; }
+ void* getData() { return data; }
+ };
+
+ class EdgeEntry {
+ private:
+ NodeItr node1, node2;
+ Matrix costs;
+ AdjEdgeItr node1AEItr, node2AEItr;
+ void *data;
+ public:
+ EdgeEntry(NodeItr node1, NodeItr node2, const Matrix &costs)
+ : node1(node1), node2(node2), costs(costs) {}
+ NodeItr getNode1() const { return node1; }
+ NodeItr getNode2() const { return node2; }
+ Matrix& getCosts() { return costs; }
+ const Matrix& getCosts() const { return costs; }
+ void setNode1AEItr(AdjEdgeItr ae) { node1AEItr = ae; }
+ AdjEdgeItr getNode1AEItr() { return node1AEItr; }
+ void setNode2AEItr(AdjEdgeItr ae) { node2AEItr = ae; }
+ AdjEdgeItr getNode2AEItr() { return node2AEItr; }
+ void setData(void *data) { this->data = data; }
+ void *getData() { return data; }
+ };
+
+ // ----- MEMBERS -----
+
+ NodeList nodes;
+ unsigned numNodes;
+
+ EdgeList edges;
+ unsigned numEdges;
+
+ // ----- INTERNAL METHODS -----
+
+ NodeEntry& getNode(NodeItr nItr) { return *nItr; }
+ const NodeEntry& getNode(ConstNodeItr nItr) const { return *nItr; }
+
+ EdgeEntry& getEdge(EdgeItr eItr) { return *eItr; }
+ const EdgeEntry& getEdge(ConstEdgeItr eItr) const { return *eItr; }
+
+ NodeItr addConstructedNode(const NodeEntry &n) {
+ ++numNodes;
+ return nodes.insert(nodes.end(), n);
+ }
+
+ EdgeItr addConstructedEdge(const EdgeEntry &e) {
+ assert(findEdge(e.getNode1(), e.getNode2()) == edges.end() &&
+ "Attempt to add duplicate edge.");
+ ++numEdges;
+ EdgeItr edgeItr = edges.insert(edges.end(), e);
+ EdgeEntry &ne = getEdge(edgeItr);
+ NodeEntry &n1 = getNode(ne.getNode1());
+ NodeEntry &n2 = getNode(ne.getNode2());
+ // Sanity check on matrix dimensions:
+ assert((n1.getCosts().getLength() == ne.getCosts().getRows()) &&
+ (n2.getCosts().getLength() == ne.getCosts().getCols()) &&
+ "Edge cost dimensions do not match node costs dimensions.");
+ ne.setNode1AEItr(n1.addEdge(edgeItr));
+ ne.setNode2AEItr(n2.addEdge(edgeItr));
+ return edgeItr;
+ }
+
+ inline void copyFrom(const Graph &other);
+ public:
+
+ /// \brief Construct an empty PBQP graph.
+ Graph() : numNodes(0), numEdges(0) {}
+
+ /// \brief Copy construct this graph from "other". Note: Does not copy node
+ /// and edge data, only graph structure and costs.
+ /// @param other Source graph to copy from.
+ Graph(const Graph &other) : numNodes(0), numEdges(0) {
+ copyFrom(other);
+ }
+
+ /// \brief Make this graph a copy of "other". Note: Does not copy node and
+ /// edge data, only graph structure and costs.
+ /// @param other The graph to copy from.
+ /// @return A reference to this graph.
+ ///
+ /// This will clear the current graph, erasing any nodes and edges added,
+ /// before copying from other.
+ Graph& operator=(const Graph &other) {
+ clear();
+ copyFrom(other);
+ return *this;
+ }
+
+ /// \brief Add a node with the given costs.
+ /// @param costs Cost vector for the new node.
+ /// @return Node iterator for the added node.
+ NodeItr addNode(const Vector &costs) {
+ return addConstructedNode(NodeEntry(costs));
+ }
+
+ /// \brief Add an edge between the given nodes with the given costs.
+ /// @param n1Itr First node.
+ /// @param n2Itr Second node.
+ /// @return Edge iterator for the added edge.
+ EdgeItr addEdge(Graph::NodeItr n1Itr, Graph::NodeItr n2Itr,
+ const Matrix &costs) {
+ assert(getNodeCosts(n1Itr).getLength() == costs.getRows() &&
+ getNodeCosts(n2Itr).getLength() == costs.getCols() &&
+ "Matrix dimensions mismatch.");
+ return addConstructedEdge(EdgeEntry(n1Itr, n2Itr, costs));
+ }
+
+ /// \brief Get the number of nodes in the graph.
+ /// @return Number of nodes in the graph.
+ unsigned getNumNodes() const { return numNodes; }
+
+ /// \brief Get the number of edges in the graph.
+ /// @return Number of edges in the graph.
+ unsigned getNumEdges() const { return numEdges; }
+
+ /// \brief Get a node's cost vector.
+ /// @param nItr Node iterator.
+ /// @return Node cost vector.
+ Vector& getNodeCosts(NodeItr nItr) { return getNode(nItr).getCosts(); }
+
+ /// \brief Get a node's cost vector (const version).
+ /// @param nItr Node iterator.
+ /// @return Node cost vector.
+ const Vector& getNodeCosts(ConstNodeItr nItr) const {
+ return getNode(nItr).getCosts();
+ }
+
+ /// \brief Set a node's data pointer.
+ /// @param nItr Node iterator.
+ /// @param data Pointer to node data.
+ ///
+ /// Typically used by a PBQP solver to attach data to aid in solution.
+ void setNodeData(NodeItr nItr, void *data) { getNode(nItr).setData(data); }
+
+ /// \brief Get the node's data pointer.
+ /// @param nItr Node iterator.
+ /// @return Pointer to node data.
+ void* getNodeData(NodeItr nItr) { return getNode(nItr).getData(); }
+
+ /// \brief Get an edge's cost matrix.
+ /// @param eItr Edge iterator.
+ /// @return Edge cost matrix.
+ Matrix& getEdgeCosts(EdgeItr eItr) { return getEdge(eItr).getCosts(); }
+
+ /// \brief Get an edge's cost matrix (const version).
+ /// @param eItr Edge iterator.
+ /// @return Edge cost matrix.
+ const Matrix& getEdgeCosts(ConstEdgeItr eItr) const {
+ return getEdge(eItr).getCosts();
+ }
+
+ /// \brief Set an edge's data pointer.
+ /// @param eItr Edge iterator.
+ /// @param data Pointer to edge data.
+ ///
+ /// Typically used by a PBQP solver to attach data to aid in solution.
+ void setEdgeData(EdgeItr eItr, void *data) { getEdge(eItr).setData(data); }
+
+ /// \brief Get an edge's data pointer.
+ /// @param eItr Edge iterator.
+ /// @return Pointer to edge data.
+ void* getEdgeData(EdgeItr eItr) { return getEdge(eItr).getData(); }
+
+ /// \brief Get a node's degree.
+ /// @param nItr Node iterator.
+ /// @return The degree of the node.
+ unsigned getNodeDegree(NodeItr nItr) const {
+ return getNode(nItr).getDegree();
+ }
+
+ /// \brief Begin iterator for node set.
+ NodeItr nodesBegin() { return nodes.begin(); }
+
+ /// \brief Begin const iterator for node set.
+ ConstNodeItr nodesBegin() const { return nodes.begin(); }
+
+ /// \brief End iterator for node set.
+ NodeItr nodesEnd() { return nodes.end(); }
+
+ /// \brief End const iterator for node set.
+ ConstNodeItr nodesEnd() const { return nodes.end(); }
+
+ /// \brief Begin iterator for edge set.
+ EdgeItr edgesBegin() { return edges.begin(); }
+
+ /// \brief End iterator for edge set.
+ EdgeItr edgesEnd() { return edges.end(); }
+
+ /// \brief Get begin iterator for adjacent edge set.
+ /// @param nItr Node iterator.
+ /// @return Begin iterator for the set of edges connected to the given node.
+ AdjEdgeItr adjEdgesBegin(NodeItr nItr) {
+ return getNode(nItr).edgesBegin();
+ }
+
+ /// \brief Get end iterator for adjacent edge set.
+ /// @param nItr Node iterator.
+ /// @return End iterator for the set of edges connected to the given node.
+ AdjEdgeItr adjEdgesEnd(NodeItr nItr) {
+ return getNode(nItr).edgesEnd();
+ }
+
+ /// \brief Get the first node connected to this edge.
+ /// @param eItr Edge iterator.
+ /// @return The first node connected to the given edge.
+ NodeItr getEdgeNode1(EdgeItr eItr) {
+ return getEdge(eItr).getNode1();
+ }
+
+ /// \brief Get the second node connected to this edge.
+ /// @param eItr Edge iterator.
+ /// @return The second node connected to the given edge.
+ NodeItr getEdgeNode2(EdgeItr eItr) {
+ return getEdge(eItr).getNode2();
+ }
+
+ /// \brief Get the "other" node connected to this edge.
+ /// @param eItr Edge iterator.
+ /// @param nItr Node iterator for the "given" node.
+ /// @return The iterator for the "other" node connected to this edge.
+ NodeItr getEdgeOtherNode(EdgeItr eItr, NodeItr nItr) {
+ EdgeEntry &e = getEdge(eItr);
+ if (e.getNode1() == nItr) {
+ return e.getNode2();
+ } // else
+ return e.getNode1();
+ }
+
+ /// \brief Get the edge connecting two nodes.
+ /// @param n1Itr First node iterator.
+ /// @param n2Itr Second node iterator.
+ /// @return An iterator for edge (n1Itr, n2Itr) if such an edge exists,
+ /// otherwise returns edgesEnd().
+ EdgeItr findEdge(NodeItr n1Itr, NodeItr n2Itr) {
+ for (AdjEdgeItr aeItr = adjEdgesBegin(n1Itr), aeEnd = adjEdgesEnd(n1Itr);
+ aeItr != aeEnd; ++aeItr) {
+ if ((getEdgeNode1(*aeItr) == n2Itr) ||
+ (getEdgeNode2(*aeItr) == n2Itr)) {
+ return *aeItr;
+ }
+ }
+ return edges.end();
+ }
+
+ /// \brief Remove a node from the graph.
+ /// @param nItr Node iterator.
+ void removeNode(NodeItr nItr) {
+ NodeEntry &n = getNode(nItr);
+ for (AdjEdgeItr itr = n.edgesBegin(), end = n.edgesEnd(); itr != end;) {
+ EdgeItr eItr = *itr;
+ ++itr;
+ removeEdge(eItr);
+ }
+ nodes.erase(nItr);
+ --numNodes;
+ }
+
+ /// \brief Remove an edge from the graph.
+ /// @param eItr Edge iterator.
+ void removeEdge(EdgeItr eItr) {
+ EdgeEntry &e = getEdge(eItr);
+ NodeEntry &n1 = getNode(e.getNode1());
+ NodeEntry &n2 = getNode(e.getNode2());
+ n1.removeEdge(e.getNode1AEItr());
+ n2.removeEdge(e.getNode2AEItr());
+ edges.erase(eItr);
+ --numEdges;
+ }
+
+ /// \brief Remove all nodes and edges from the graph.
+ void clear() {
+ nodes.clear();
+ edges.clear();
+ numNodes = numEdges = 0;
+ }
+
+ /// \brief Print a representation of this graph in DOT format.
+ /// @param os Output stream to print on.
+ template <typename OStream>
+ void printDot(OStream &os) {
+
+ os << "graph {\n";
+
+ for (NodeItr nodeItr = nodesBegin(), nodeEnd = nodesEnd();
+ nodeItr != nodeEnd; ++nodeItr) {
+
+ os << " node" << nodeItr << " [ label=\""
+ << nodeItr << ": " << getNodeCosts(nodeItr) << "\" ]\n";
+ }
+
+ os << " edge [ len=" << getNumNodes() << " ]\n";
+
+ for (EdgeItr edgeItr = edgesBegin(), edgeEnd = edgesEnd();
+ edgeItr != edgeEnd; ++edgeItr) {
+
+ os << " node" << getEdgeNode1(edgeItr)
+ << " -- node" << getEdgeNode2(edgeItr)
+ << " [ label=\"";
+
+ const Matrix &edgeCosts = getEdgeCosts(edgeItr);
+
+ for (unsigned i = 0; i < edgeCosts.getRows(); ++i) {
+ os << edgeCosts.getRowAsVector(i) << "\\n";
+ }
+ os << "\" ]\n";
+ }
+ os << "}\n";
+ }
+
+ };
+
+ class NodeItrComparator {
+ public:
+ bool operator()(Graph::NodeItr n1, Graph::NodeItr n2) const {
+ return &*n1 < &*n2;
+ }
+
+ bool operator()(Graph::ConstNodeItr n1, Graph::ConstNodeItr n2) const {
+ return &*n1 < &*n2;
+ }
+ };
+
+ class EdgeItrCompartor {
+ public:
+ bool operator()(Graph::EdgeItr e1, Graph::EdgeItr e2) const {
+ return &*e1 < &*e2;
+ }
+
+ bool operator()(Graph::ConstEdgeItr e1, Graph::ConstEdgeItr e2) const {
+ return &*e1 < &*e2;
+ }
+ };
+
+ void Graph::copyFrom(const Graph &other) {
+ std::map<Graph::ConstNodeItr, Graph::NodeItr,
+ NodeItrComparator> nodeMap;
+
+ for (Graph::ConstNodeItr nItr = other.nodesBegin(),
+ nEnd = other.nodesEnd();
+ nItr != nEnd; ++nItr) {
+ nodeMap[nItr] = addNode(other.getNodeCosts(nItr));
+ }
+
+ }
+
+}
+
+#endif // LLVM_CODEGEN_PBQP_GRAPH_HPP
diff --git a/lib/CodeGen/PBQP/GraphBase.h b/lib/CodeGen/PBQP/GraphBase.h
deleted file mode 100644
index becd98a..0000000
--- a/lib/CodeGen/PBQP/GraphBase.h
+++ /dev/null
@@ -1,582 +0,0 @@
-//===-- GraphBase.h - Abstract Base PBQP Graph ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Base class for PBQP Graphs.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CODEGEN_PBQP_GRAPHBASE_H
-#define LLVM_CODEGEN_PBQP_GRAPHBASE_H
-
-#include "PBQPMath.h"
-
-#include <list>
-#include <vector>
-
-namespace PBQP {
-
-// UGLY, but I'm not sure there's a good way around this: We need to be able to
-// look up a Node's "adjacent edge list" structure type before the Node type is
-// fully constructed. We can enable this by pushing the choice of data type
-// out into this traits class.
-template <typename Graph>
-class NodeBaseTraits {
- public:
- typedef std::list<typename Graph::EdgeIterator> AdjEdgeList;
- typedef typename AdjEdgeList::iterator AdjEdgeIterator;
- typedef typename AdjEdgeList::const_iterator ConstAdjEdgeIterator;
-};
-
-/// \brief Base for concrete graph classes. Provides a basic set of graph
-/// operations which are useful for PBQP solvers.
-template <typename NodeEntry, typename EdgeEntry>
-class GraphBase {
-private:
-
- typedef GraphBase<NodeEntry, EdgeEntry> ThisGraphT;
-
- typedef std::list<NodeEntry> NodeList;
- typedef std::list<EdgeEntry> EdgeList;
-
- NodeList nodeList;
- unsigned nodeListSize;
-
- EdgeList edgeList;
- unsigned edgeListSize;
-
- GraphBase(const ThisGraphT &other) { abort(); }
- void operator=(const ThisGraphT &other) { abort(); }
-
-public:
-
- /// \brief Iterates over the nodes of a graph.
- typedef typename NodeList::iterator NodeIterator;
- /// \brief Iterates over the nodes of a const graph.
- typedef typename NodeList::const_iterator ConstNodeIterator;
- /// \brief Iterates over the edges of a graph.
- typedef typename EdgeList::iterator EdgeIterator;
- /// \brief Iterates over the edges of a const graph.
- typedef typename EdgeList::const_iterator ConstEdgeIterator;
-
- /// \brief Iterates over the edges attached to a node.
- typedef typename NodeBaseTraits<ThisGraphT>::AdjEdgeIterator
- AdjEdgeIterator;
-
- /// \brief Iterates over the edges attached to a node in a const graph.
- typedef typename NodeBaseTraits<ThisGraphT>::ConstAdjEdgeIterator
- ConstAdjEdgeIterator;
-
-private:
-
- typedef std::vector<NodeIterator> IDToNodeMap;
-
- IDToNodeMap idToNodeMap;
- bool nodeIDsValid;
-
- void invalidateNodeIDs() {
- if (nodeIDsValid) {
- idToNodeMap.clear();
- nodeIDsValid = false;
- }
- }
-
- template <typename ItrT>
- bool iteratorInRange(ItrT itr, const ItrT &begin, const ItrT &end) {
- for (ItrT t = begin; t != end; ++t) {
- if (itr == t)
- return true;
- }
-
- return false;
- }
-
-protected:
-
- GraphBase() : nodeListSize(0), edgeListSize(0), nodeIDsValid(false) {}
-
- NodeEntry& getNodeEntry(const NodeIterator &nodeItr) { return *nodeItr; }
- const NodeEntry& getNodeEntry(const ConstNodeIterator &nodeItr) const {
- return *nodeItr;
- }
-
- EdgeEntry& getEdgeEntry(const EdgeIterator &edgeItr) { return *edgeItr; }
- const EdgeEntry& getEdgeEntry(const ConstEdgeIterator &edgeItr) const {
- return *edgeItr;
- }
-
- NodeIterator addConstructedNode(const NodeEntry &nodeEntry) {
- ++nodeListSize;
-
- invalidateNodeIDs();
-
- NodeIterator newNodeItr = nodeList.insert(nodeList.end(), nodeEntry);
-
- return newNodeItr;
- }
-
- EdgeIterator addConstructedEdge(const EdgeEntry &edgeEntry) {
-
- assert((findEdge(edgeEntry.getNode1Itr(), edgeEntry.getNode2Itr())
- == edgeList.end()) && "Attempt to add duplicate edge.");
-
- ++edgeListSize;
-
- // Add the edge to the graph.
- EdgeIterator edgeItr = edgeList.insert(edgeList.end(), edgeEntry);
-
- // Get a reference to the version in the graph.
- EdgeEntry &newEdgeEntry = getEdgeEntry(edgeItr);
-
- // Node entries:
- NodeEntry &node1Entry = getNodeEntry(newEdgeEntry.getNode1Itr()),
- &node2Entry = getNodeEntry(newEdgeEntry.getNode2Itr());
-
- // Sanity check on matrix dimensions.
- assert((node1Entry.getCosts().getLength() ==
- newEdgeEntry.getCosts().getRows()) &&
- (node2Entry.getCosts().getLength() ==
- newEdgeEntry.getCosts().getCols()) &&
- "Matrix dimensions do not match cost vector dimensions.");
-
- // Create links between nodes and edges.
- newEdgeEntry.setNode1ThisEdgeItr(
- node1Entry.addAdjEdge(edgeItr));
- newEdgeEntry.setNode2ThisEdgeItr(
- node2Entry.addAdjEdge(edgeItr));
-
- return edgeItr;
- }
-
-public:
-
- /// \brief Returns the number of nodes in this graph.
- unsigned getNumNodes() const { return nodeListSize; }
-
- /// \brief Returns the number of edges in this graph.
- unsigned getNumEdges() const { return edgeListSize; }
-
- /// \brief Return the cost vector for the given node.
- Vector& getNodeCosts(const NodeIterator &nodeItr) {
- return getNodeEntry(nodeItr).getCosts();
- }
-
- /// \brief Return the cost vector for the give node.
- const Vector& getNodeCosts(const ConstNodeIterator &nodeItr) const {
- return getNodeEntry(nodeItr).getCosts();
- }
-
- /// \brief Return the degree of the given node.
- unsigned getNodeDegree(const NodeIterator &nodeItr) const {
- return getNodeEntry(nodeItr).getDegree();
- }
-
- /// \brief Assigns sequential IDs to the nodes, starting at 0, which
- /// remain valid until the next addition or removal of a node.
- void assignNodeIDs() {
- unsigned curID = 0;
- idToNodeMap.resize(getNumNodes());
- for (NodeIterator nodeItr = nodesBegin(), nodeEnd = nodesEnd();
- nodeItr != nodeEnd; ++nodeItr, ++curID) {
- getNodeEntry(nodeItr).setID(curID);
- idToNodeMap[curID] = nodeItr;
- }
- nodeIDsValid = true;
- }
-
- /// \brief Assigns sequential IDs to the nodes using the ordering of the
- /// given vector.
- void assignNodeIDs(const std::vector<NodeIterator> &nodeOrdering) {
- assert((getNumNodes() == nodeOrdering.size()) &&
- "Wrong number of nodes in node ordering.");
- idToNodeMap = nodeOrdering;
- for (unsigned nodeID = 0; nodeID < idToNodeMap.size(); ++nodeID) {
- getNodeEntry(idToNodeMap[nodeID]).setID(nodeID);
- }
- nodeIDsValid = true;
- }
-
- /// \brief Returns true if valid node IDs are assigned, false otherwise.
- bool areNodeIDsValid() const { return nodeIDsValid; }
-
- /// \brief Return the numeric ID of the given node.
- ///
- /// Calls to this method will result in an assertion failure if there have
- /// been any node additions or removals since the last call to
- /// assignNodeIDs().
- unsigned getNodeID(const ConstNodeIterator &nodeItr) const {
- assert(nodeIDsValid && "Attempt to retrieve invalid ID.");
- return getNodeEntry(nodeItr).getID();
- }
-
- /// \brief Returns the iterator associated with the given node ID.
- NodeIterator getNodeItr(unsigned nodeID) {
- assert(nodeIDsValid && "Attempt to retrieve iterator with invalid ID.");
- return idToNodeMap[nodeID];
- }
-
- /// \brief Returns the iterator associated with the given node ID.
- ConstNodeIterator getNodeItr(unsigned nodeID) const {
- assert(nodeIDsValid && "Attempt to retrieve iterator with invalid ID.");
- return idToNodeMap[nodeID];
- }
-
- /// \brief Removes the given node (and all attached edges) from the graph.
- void removeNode(const NodeIterator &nodeItr) {
- assert(iteratorInRange(nodeItr, nodeList.begin(), nodeList.end()) &&
- "Iterator does not belong to this graph!");
-
- invalidateNodeIDs();
-
- NodeEntry &nodeEntry = getNodeEntry(nodeItr);
-
- // We need to copy this out because it will be destroyed as the edges are
- // removed.
- typedef std::vector<EdgeIterator> AdjEdgeList;
- typedef typename AdjEdgeList::iterator AdjEdgeListItr;
-
- AdjEdgeList adjEdges;
- adjEdges.reserve(nodeEntry.getDegree());
- std::copy(nodeEntry.adjEdgesBegin(), nodeEntry.adjEdgesEnd(),
- std::back_inserter(adjEdges));
-
- // Iterate over the copied out edges and remove them from the graph.
- for (AdjEdgeListItr itr = adjEdges.begin(), end = adjEdges.end();
- itr != end; ++itr) {
- removeEdge(*itr);
- }
-
- // Erase the node from the nodelist.
- nodeList.erase(nodeItr);
- --nodeListSize;
- }
-
- NodeIterator nodesBegin() { return nodeList.begin(); }
- ConstNodeIterator nodesBegin() const { return nodeList.begin(); }
- NodeIterator nodesEnd() { return nodeList.end(); }
- ConstNodeIterator nodesEnd() const { return nodeList.end(); }
-
- AdjEdgeIterator adjEdgesBegin(const NodeIterator &nodeItr) {
- return getNodeEntry(nodeItr).adjEdgesBegin();
- }
-
- ConstAdjEdgeIterator adjEdgesBegin(const ConstNodeIterator &nodeItr) const {
- return getNodeEntry(nodeItr).adjEdgesBegin();
- }
-
- AdjEdgeIterator adjEdgesEnd(const NodeIterator &nodeItr) {
- return getNodeEntry(nodeItr).adjEdgesEnd();
- }
-
- ConstAdjEdgeIterator adjEdgesEnd(const ConstNodeIterator &nodeItr) const {
- getNodeEntry(nodeItr).adjEdgesEnd();
- }
-
- EdgeIterator findEdge(const NodeIterator &node1Itr,
- const NodeIterator &node2Itr) {
-
- for (AdjEdgeIterator adjEdgeItr = adjEdgesBegin(node1Itr),
- adjEdgeEnd = adjEdgesEnd(node1Itr);
- adjEdgeItr != adjEdgeEnd; ++adjEdgeItr) {
- if ((getEdgeNode1Itr(*adjEdgeItr) == node2Itr) ||
- (getEdgeNode2Itr(*adjEdgeItr) == node2Itr)) {
- return *adjEdgeItr;
- }
- }
-
- return edgeList.end();
- }
-
- ConstEdgeIterator findEdge(const ConstNodeIterator &node1Itr,
- const ConstNodeIterator &node2Itr) const {
-
- for (ConstAdjEdgeIterator adjEdgeItr = adjEdgesBegin(node1Itr),
- adjEdgeEnd = adjEdgesEnd(node1Itr);
- adjEdgeItr != adjEdgeEnd; ++adjEdgeItr) {
- if ((getEdgeNode1Itr(*adjEdgeItr) == node2Itr) ||
- (getEdgeNode2Itr(*adjEdgeItr) == node2Itr)) {
- return *adjEdgeItr;
- }
- }
-
- return edgeList.end();
- }
-
- Matrix& getEdgeCosts(const EdgeIterator &edgeItr) {
- return getEdgeEntry(edgeItr).getCosts();
- }
-
- const Matrix& getEdgeCosts(const ConstEdgeIterator &edgeItr) const {
- return getEdgeEntry(edgeItr).getCosts();
- }
-
- NodeIterator getEdgeNode1Itr(const EdgeIterator &edgeItr) {
- return getEdgeEntry(edgeItr).getNode1Itr();
- }
-
- ConstNodeIterator getEdgeNode1Itr(const ConstEdgeIterator &edgeItr) const {
- return getEdgeEntry(edgeItr).getNode1Itr();
- }
-
- NodeIterator getEdgeNode2Itr(const EdgeIterator &edgeItr) {
- return getEdgeEntry(edgeItr).getNode2Itr();
- }
-
- ConstNodeIterator getEdgeNode2Itr(const ConstEdgeIterator &edgeItr) const {
- return getEdgeEntry(edgeItr).getNode2Itr();
- }
-
- NodeIterator getEdgeOtherNode(const EdgeIterator &edgeItr,
- const NodeIterator &nodeItr) {
-
- EdgeEntry &edgeEntry = getEdgeEntry(edgeItr);
- if (nodeItr == edgeEntry.getNode1Itr()) {
- return edgeEntry.getNode2Itr();
- }
- //else
- return edgeEntry.getNode1Itr();
- }
-
- ConstNodeIterator getEdgeOtherNode(const ConstEdgeIterator &edgeItr,
- const ConstNodeIterator &nodeItr) const {
-
- const EdgeEntry &edgeEntry = getEdgeEntry(edgeItr);
- if (nodeItr == edgeEntry.getNode1Itr()) {
- return edgeEntry.getNode2Itr();
- }
- //else
- return edgeEntry.getNode1Itr();
- }
-
- void removeEdge(const EdgeIterator &edgeItr) {
- assert(iteratorInRange(edgeItr, edgeList.begin(), edgeList.end()) &&
- "Iterator does not belong to this graph!");
-
- --edgeListSize;
-
- // Get the edge entry.
- EdgeEntry &edgeEntry = getEdgeEntry(edgeItr);
-
- // Get the nodes entry.
- NodeEntry &node1Entry(getNodeEntry(edgeEntry.getNode1Itr())),
- &node2Entry(getNodeEntry(edgeEntry.getNode2Itr()));
-
- // Disconnect the edge from the nodes.
- node1Entry.removeAdjEdge(edgeEntry.getNode1ThisEdgeItr());
- node2Entry.removeAdjEdge(edgeEntry.getNode2ThisEdgeItr());
-
- // Remove the edge from the graph.
- edgeList.erase(edgeItr);
- }
-
- EdgeIterator edgesBegin() { return edgeList.begin(); }
- ConstEdgeIterator edgesBegin() const { return edgeList.begin(); }
- EdgeIterator edgesEnd() { return edgeList.end(); }
- ConstEdgeIterator edgesEnd() const { return edgeList.end(); }
-
- void clear() {
- nodeList.clear();
- nodeListSize = 0;
- edgeList.clear();
- edgeListSize = 0;
- idToNodeMap.clear();
- }
-
- template <typename OStream>
- void printDot(OStream &os) const {
-
- assert(areNodeIDsValid() &&
- "Cannot print a .dot of a graph unless IDs have been assigned.");
-
- os << "graph {\n";
-
- for (ConstNodeIterator nodeItr = nodesBegin(), nodeEnd = nodesEnd();
- nodeItr != nodeEnd; ++nodeItr) {
-
- os << " node" << getNodeID(nodeItr) << " [ label=\""
- << getNodeID(nodeItr) << ": " << getNodeCosts(nodeItr) << "\" ]\n";
- }
-
- os << " edge [ len=" << getNumNodes() << " ]\n";
-
- for (ConstEdgeIterator edgeItr = edgesBegin(), edgeEnd = edgesEnd();
- edgeItr != edgeEnd; ++edgeItr) {
-
- os << " node" << getNodeID(getEdgeNode1Itr(edgeItr))
- << " -- node" << getNodeID(getEdgeNode2Itr(edgeItr))
- << " [ label=\"";
-
- const Matrix &edgeCosts = getEdgeCosts(edgeItr);
-
- for (unsigned i = 0; i < edgeCosts.getRows(); ++i) {
- os << edgeCosts.getRowAsVector(i) << "\\n";
- }
-
- os << "\" ]\n";
- }
-
- os << "}\n";
- }
-
- template <typename OStream>
- void printDot(OStream &os) {
- if (!areNodeIDsValid()) {
- assignNodeIDs();
- }
-
- const_cast<const ThisGraphT*>(this)->printDot(os);
- }
-
- template <typename OStream>
- void dumpTo(OStream &os) const {
- typedef ConstNodeIterator ConstNodeID;
-
- assert(areNodeIDsValid() &&
- "Cannot dump a graph unless IDs have been assigned.");
-
- for (ConstNodeIterator nItr = nodesBegin(), nEnd = nodesEnd();
- nItr != nEnd; ++nItr) {
- os << getNodeID(nItr) << "\n";
- }
-
- unsigned edgeNumber = 1;
- for (ConstEdgeIterator eItr = edgesBegin(), eEnd = edgesEnd();
- eItr != eEnd; ++eItr) {
-
- os << edgeNumber++ << ": { "
- << getNodeID(getEdgeNode1Itr(eItr)) << ", "
- << getNodeID(getEdgeNode2Itr(eItr)) << " }\n";
- }
-
- }
-
- template <typename OStream>
- void dumpTo(OStream &os) {
- if (!areNodeIDsValid()) {
- assignNodeIDs();
- }
-
- const_cast<const ThisGraphT*>(this)->dumpTo(os);
- }
-
-};
-
-/// \brief Provides a base from which to derive nodes for GraphBase.
-template <typename NodeImpl, typename EdgeImpl>
-class NodeBase {
-private:
-
- typedef GraphBase<NodeImpl, EdgeImpl> GraphBaseT;
- typedef NodeBaseTraits<GraphBaseT> ThisNodeBaseTraits;
-
-public:
- typedef typename GraphBaseT::EdgeIterator EdgeIterator;
-
-private:
- typedef typename ThisNodeBaseTraits::AdjEdgeList AdjEdgeList;
-
- unsigned degree, id;
- Vector costs;
- AdjEdgeList adjEdges;
-
- void operator=(const NodeBase& other) {
- assert(false && "Can't assign NodeEntrys.");
- }
-
-public:
-
- typedef typename ThisNodeBaseTraits::AdjEdgeIterator AdjEdgeIterator;
- typedef typename ThisNodeBaseTraits::ConstAdjEdgeIterator
- ConstAdjEdgeIterator;
-
- NodeBase(const Vector &costs) : degree(0), costs(costs) {
- assert((costs.getLength() > 0) && "Can't have zero-length cost vector.");
- }
-
- Vector& getCosts() { return costs; }
- const Vector& getCosts() const { return costs; }
-
- unsigned getDegree() const { return degree; }
-
- void setID(unsigned id) { this->id = id; }
- unsigned getID() const { return id; }
-
- AdjEdgeIterator addAdjEdge(const EdgeIterator &edgeItr) {
- ++degree;
- return adjEdges.insert(adjEdges.end(), edgeItr);
- }
-
- void removeAdjEdge(const AdjEdgeIterator &adjEdgeItr) {
- --degree;
- adjEdges.erase(adjEdgeItr);
- }
-
- AdjEdgeIterator adjEdgesBegin() { return adjEdges.begin(); }
- ConstAdjEdgeIterator adjEdgesBegin() const { return adjEdges.begin(); }
- AdjEdgeIterator adjEdgesEnd() { return adjEdges.end(); }
- ConstAdjEdgeIterator adjEdgesEnd() const { return adjEdges.end(); }
-
-};
-
-template <typename NodeImpl, typename EdgeImpl>
-class EdgeBase {
-public:
- typedef typename GraphBase<NodeImpl, EdgeImpl>::NodeIterator NodeIterator;
- typedef typename GraphBase<NodeImpl, EdgeImpl>::EdgeIterator EdgeIterator;
-
- typedef typename NodeImpl::AdjEdgeIterator NodeAdjEdgeIterator;
-
-private:
-
- NodeIterator node1Itr, node2Itr;
- NodeAdjEdgeIterator node1ThisEdgeItr, node2ThisEdgeItr;
- Matrix costs;
-
- void operator=(const EdgeBase &other) {
- assert(false && "Can't assign EdgeEntrys.");
- }
-
-public:
-
- EdgeBase(const NodeIterator &node1Itr, const NodeIterator &node2Itr,
- const Matrix &costs) :
- node1Itr(node1Itr), node2Itr(node2Itr), costs(costs) {
-
- assert((costs.getRows() > 0) && (costs.getCols() > 0) &&
- "Can't have zero-dimensioned cost matrices");
- }
-
- Matrix& getCosts() { return costs; }
- const Matrix& getCosts() const { return costs; }
-
- const NodeIterator& getNode1Itr() const { return node1Itr; }
- const NodeIterator& getNode2Itr() const { return node2Itr; }
-
- void setNode1ThisEdgeItr(const NodeAdjEdgeIterator &node1ThisEdgeItr) {
- this->node1ThisEdgeItr = node1ThisEdgeItr;
- }
-
- const NodeAdjEdgeIterator& getNode1ThisEdgeItr() const {
- return node1ThisEdgeItr;
- }
-
- void setNode2ThisEdgeItr(const NodeAdjEdgeIterator &node2ThisEdgeItr) {
- this->node2ThisEdgeItr = node2ThisEdgeItr;
- }
-
- const NodeAdjEdgeIterator& getNode2ThisEdgeItr() const {
- return node2ThisEdgeItr;
- }
-
-};
-
-
-}
-
-#endif // LLVM_CODEGEN_PBQP_GRAPHBASE_HPP
diff --git a/lib/CodeGen/PBQP/HeuristicBase.h b/lib/CodeGen/PBQP/HeuristicBase.h
new file mode 100644
index 0000000..3bb24e1
--- /dev/null
+++ b/lib/CodeGen/PBQP/HeuristicBase.h
@@ -0,0 +1,242 @@
+//===-- HeuristcBase.h --- Heuristic base class for PBQP --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PBQP_HEURISTICBASE_H
+#define LLVM_CODEGEN_PBQP_HEURISTICBASE_H
+
+#include "HeuristicSolver.h"
+
+namespace PBQP {
+
+ /// \brief Abstract base class for heuristic implementations.
+ ///
+ /// This class provides a handy base for heuristic implementations with common
+ /// solver behaviour implemented for a number of methods.
+ ///
+ /// To implement your own heuristic using this class as a base you'll have to
+ /// implement, as a minimum, the following methods:
+ /// <ul>
+ /// <li> void addToHeuristicList(Graph::NodeItr) : Add a node to the
+ /// heuristic reduction list.
+ /// <li> void heuristicReduce() : Perform a single heuristic reduction.
+ /// <li> void preUpdateEdgeCosts(Graph::EdgeItr) : Handle the (imminent)
+ /// change to the cost matrix on the given edge (by R2).
+ /// <li> void postUpdateEdgeCostts(Graph::EdgeItr) : Handle the new
+ /// costs on the given edge.
+ /// <li> void handleAddEdge(Graph::EdgeItr) : Handle the addition of a new
+ /// edge into the PBQP graph (by R2).
+ /// <li> void handleRemoveEdge(Graph::EdgeItr, Graph::NodeItr) : Handle the
+ /// disconnection of the given edge from the given node.
+ /// <li> A constructor for your derived class : to pass back a reference to
+ /// the solver which is using this heuristic.
+ /// </ul>
+ ///
+ /// These methods are implemented in this class for documentation purposes,
+ /// but will assert if called.
+ ///
+ /// Note that this class uses the curiously recursive template idiom to
+ /// forward calls to the derived class. These methods need not be made
+ /// virtual, and indeed probably shouldn't for performance reasons.
+ ///
+ /// You'll also need to provide NodeData and EdgeData structs in your class.
+ /// These can be used to attach data relevant to your heuristic to each
+ /// node/edge in the PBQP graph.
+
+ template <typename HImpl>
+ class HeuristicBase {
+ private:
+
+ typedef std::list<Graph::NodeItr> OptimalList;
+
+ HeuristicSolverImpl<HImpl> &s;
+ Graph &g;
+ OptimalList optimalList;
+
+ // Return a reference to the derived heuristic.
+ HImpl& impl() { return static_cast<HImpl&>(*this); }
+
+ // Add the given node to the optimal reductions list. Keep an iterator to
+ // its location for fast removal.
+ void addToOptimalReductionList(Graph::NodeItr nItr) {
+ optimalList.insert(optimalList.end(), nItr);
+ }
+
+ public:
+
+ /// \brief Construct an instance with a reference to the given solver.
+ /// @param solver The solver which is using this heuristic instance.
+ HeuristicBase(HeuristicSolverImpl<HImpl> &solver)
+ : s(solver), g(s.getGraph()) { }
+
+ /// \brief Get the solver which is using this heuristic instance.
+ /// @return The solver which is using this heuristic instance.
+ ///
+ /// You can use this method to get access to the solver in your derived
+ /// heuristic implementation.
+ HeuristicSolverImpl<HImpl>& getSolver() { return s; }
+
+ /// \brief Get the graph representing the problem to be solved.
+ /// @return The graph representing the problem to be solved.
+ Graph& getGraph() { return g; }
+
+ /// \brief Tell the solver to simplify the graph before the reduction phase.
+ /// @return Whether or not the solver should run a simplification phase
+ /// prior to the main setup and reduction.
+ ///
+ /// HeuristicBase returns true from this method as it's a sensible default,
+ /// however you can over-ride it in your derived class if you want different
+ /// behaviour.
+ bool solverRunSimplify() const { return true; }
+
+ /// \brief Decide whether a node should be optimally or heuristically
+ /// reduced.
+ /// @return Whether or not the given node should be listed for optimal
+ /// reduction (via R0, R1 or R2).
+ ///
+ /// HeuristicBase returns true for any node with degree less than 3. This is
+ /// sane and sensible for many situations, but not all. You can over-ride
+ /// this method in your derived class if you want a different selection
+ /// criteria. Note however that your criteria for selecting optimal nodes
+ /// should be <i>at least</i> as strong as this. I.e. Nodes of degree 3 or
+ /// higher should not be selected under any circumstances.
+ bool shouldOptimallyReduce(Graph::NodeItr nItr) {
+ if (g.getNodeDegree(nItr) < 3)
+ return true;
+ // else
+ return false;
+ }
+
+ /// \brief Add the given node to the list of nodes to be optimally reduced.
+ /// @return nItr Node iterator to be added.
+ ///
+ /// You probably don't want to over-ride this, except perhaps to record
+ /// statistics before calling this implementation. HeuristicBase relies on
+ /// its behaviour.
+ void addToOptimalReduceList(Graph::NodeItr nItr) {
+ optimalList.push_back(nItr);
+ }
+
+ /// \brief Initialise the heuristic.
+ ///
+ /// HeuristicBase iterates over all nodes in the problem and adds them to
+ /// the appropriate list using addToOptimalReduceList or
+ /// addToHeuristicReduceList based on the result of shouldOptimallyReduce.
+ ///
+ /// This behaviour should be fine for most situations.
+ void setup() {
+ for (Graph::NodeItr nItr = g.nodesBegin(), nEnd = g.nodesEnd();
+ nItr != nEnd; ++nItr) {
+ if (impl().shouldOptimallyReduce(nItr)) {
+ addToOptimalReduceList(nItr);
+ } else {
+ impl().addToHeuristicReduceList(nItr);
+ }
+ }
+ }
+
+ /// \brief Optimally reduce one of the nodes in the optimal reduce list.
+ /// @return True if a reduction takes place, false if the optimal reduce
+ /// list is empty.
+ ///
+ /// Selects a node from the optimal reduce list and removes it, applying
+ /// R0, R1 or R2 as appropriate based on the selected node's degree.
+ bool optimalReduce() {
+ if (optimalList.empty())
+ return false;
+
+ Graph::NodeItr nItr = optimalList.front();
+ optimalList.pop_front();
+
+ switch (s.getSolverDegree(nItr)) {
+ case 0: s.applyR0(nItr); break;
+ case 1: s.applyR1(nItr); break;
+ case 2: s.applyR2(nItr); break;
+ default: assert(false &&
+ "Optimal reductions of degree > 2 nodes is invalid.");
+ }
+
+ return true;
+ }
+
+ /// \brief Perform the PBQP reduction process.
+ ///
+ /// Reduces the problem to the empty graph by repeated application of the
+ /// reduction rules R0, R1, R2 and RN.
+ /// R0, R1 or R2 are always applied if possible before RN is used.
+ void reduce() {
+ bool finished = false;
+
+ while (!finished) {
+ if (!optimalReduce())
+ if (!impl().heuristicReduce())
+ finished = true;
+ }
+ }
+
+ /// \brief Add a node to the heuristic reduce list.
+ /// @param nItr Node iterator to add to the heuristic reduce list.
+ void addToHeuristicList(Graph::NodeItr nItr) {
+ assert(false && "Must be implemented in derived class.");
+ }
+
+ /// \brief Heuristically reduce one of the nodes in the heuristic
+ /// reduce list.
+ /// @return True if a reduction takes place, false if the heuristic reduce
+ /// list is empty.
+ void heuristicReduce() {
+ assert(false && "Must be implemented in derived class.");
+ }
+
+ /// \brief Prepare a change in the costs on the given edge.
+ /// @param eItr Edge iterator.
+ void preUpdateEdgeCosts(Graph::EdgeItr eItr) {
+ assert(false && "Must be implemented in derived class.");
+ }
+
+ /// \brief Handle the change in the costs on the given edge.
+ /// @param eItr Edge iterator.
+ void postUpdateEdgeCostts(Graph::EdgeItr eItr) {
+ assert(false && "Must be implemented in derived class.");
+ }
+
+ /// \brief Handle the addition of a new edge into the PBQP graph.
+ /// @param eItr Edge iterator for the added edge.
+ void handleAddEdge(Graph::EdgeItr eItr) {
+ assert(false && "Must be implemented in derived class.");
+ }
+
+ /// \brief Handle disconnection of an edge from a node.
+ /// @param eItr Edge iterator for edge being disconnected.
+ /// @param nItr Node iterator for the node being disconnected from.
+ ///
+ /// Edges are frequently removed due to the removal of a node. This
+ /// method allows for the effect to be computed only for the remaining
+ /// node in the graph.
+ void handleRemoveEdge(Graph::EdgeItr eItr, Graph::NodeItr nItr) {
+ assert(false && "Must be implemented in derived class.");
+ }
+
+ /// \brief Clean up any structures used by HeuristicBase.
+ ///
+ /// At present this just performs a sanity check: that the optimal reduce
+ /// list is empty now that reduction has completed.
+ ///
+ /// If your derived class has more complex structures which need tearing
+ /// down you should over-ride this method but include a call back to this
+ /// implementation.
+ void cleanup() {
+ assert(optimalList.empty() && "Nodes left over in optimal reduce list?");
+ }
+
+ };
+
+}
+
+
+#endif // LLVM_CODEGEN_PBQP_HEURISTICBASE_H
diff --git a/lib/CodeGen/PBQP/HeuristicSolver.h b/lib/CodeGen/PBQP/HeuristicSolver.h
index f78a58a..c156264 100644
--- a/lib/CodeGen/PBQP/HeuristicSolver.h
+++ b/lib/CodeGen/PBQP/HeuristicSolver.h
@@ -1,4 +1,4 @@
-//===-- HeuristicSolver.h - Heuristic PBQP Solver ---------------*- C++ -*-===//
+//===-- HeuristicSolver.h - Heuristic PBQP Solver --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,780 +9,598 @@
//
// Heuristic PBQP solver. This solver is able to perform optimal reductions for
// nodes of degree 0, 1 or 2. For nodes of degree >2 a plugable heuristic is
-// used to to select a node for reduction.
+// used to select a node for reduction.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H
#define LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H
-#include "Solver.h"
-#include "AnnotatedGraph.h"
-#include "llvm/Support/raw_ostream.h"
+#include "Graph.h"
+#include "Solution.h"
+#include <vector>
#include <limits>
namespace PBQP {
-/// \brief Important types for the HeuristicSolverImpl.
-///
-/// Declared seperately to allow access to heuristic classes before the solver
-/// is fully constructed.
-template <typename HeuristicNodeData, typename HeuristicEdgeData>
-class HSITypes {
-public:
-
- class NodeData;
- class EdgeData;
-
- typedef AnnotatedGraph<NodeData, EdgeData> SolverGraph;
- typedef typename SolverGraph::NodeIterator GraphNodeIterator;
- typedef typename SolverGraph::EdgeIterator GraphEdgeIterator;
- typedef typename SolverGraph::AdjEdgeIterator GraphAdjEdgeIterator;
-
- typedef std::list<GraphNodeIterator> NodeList;
- typedef typename NodeList::iterator NodeListIterator;
-
- typedef std::vector<GraphNodeIterator> NodeStack;
- typedef typename NodeStack::iterator NodeStackIterator;
-
- class NodeData {
- friend class EdgeData;
-
+ /// \brief Heuristic PBQP solver implementation.
+ ///
+ /// This class should usually be created (and destroyed) indirectly via a call
+ /// to HeuristicSolver<HImpl>::solve(Graph&).
+ /// See the comments for HeuristicSolver.
+ ///
+ /// HeuristicSolverImpl provides the R0, R1 and R2 reduction rules,
+ /// backpropagation phase, and maintains the internal copy of the graph on
+ /// which the reduction is carried out (the original being kept to facilitate
+ /// backpropagation).
+ template <typename HImpl>
+ class HeuristicSolverImpl {
private:
- typedef std::list<GraphEdgeIterator> LinksList;
+ typedef typename HImpl::NodeData HeuristicNodeData;
+ typedef typename HImpl::EdgeData HeuristicEdgeData;
- unsigned numLinks;
- LinksList links, solvedLinks;
- NodeListIterator bucketItr;
- HeuristicNodeData heuristicData;
+ typedef std::list<Graph::EdgeItr> SolverEdges;
public:
-
- typedef typename LinksList::iterator AdjLinkIterator;
+
+ /// \brief Iterator type for edges in the solver graph.
+ typedef SolverEdges::iterator SolverEdgeItr;
private:
- AdjLinkIterator addLink(const GraphEdgeIterator &edgeItr) {
- ++numLinks;
- return links.insert(links.end(), edgeItr);
- }
+ class NodeData {
+ public:
+ NodeData() : solverDegree(0) {}
- void delLink(const AdjLinkIterator &adjLinkItr) {
- --numLinks;
- links.erase(adjLinkItr);
- }
+ HeuristicNodeData& getHeuristicData() { return hData; }
- public:
-
- NodeData() : numLinks(0) {}
-
- unsigned getLinkDegree() const { return numLinks; }
-
- HeuristicNodeData& getHeuristicData() { return heuristicData; }
- const HeuristicNodeData& getHeuristicData() const {
- return heuristicData;
- }
+ SolverEdgeItr addSolverEdge(Graph::EdgeItr eItr) {
+ ++solverDegree;
+ return solverEdges.insert(solverEdges.end(), eItr);
+ }
- void setBucketItr(const NodeListIterator &bucketItr) {
- this->bucketItr = bucketItr;
- }
+ void removeSolverEdge(SolverEdgeItr seItr) {
+ --solverDegree;
+ solverEdges.erase(seItr);
+ }
- const NodeListIterator& getBucketItr() const {
- return bucketItr;
- }
+ SolverEdgeItr solverEdgesBegin() { return solverEdges.begin(); }
+ SolverEdgeItr solverEdgesEnd() { return solverEdges.end(); }
+ unsigned getSolverDegree() const { return solverDegree; }
+ void clearSolverEdges() {
+ solverDegree = 0;
+ solverEdges.clear();
+ }
+
+ private:
+ HeuristicNodeData hData;
+ unsigned solverDegree;
+ SolverEdges solverEdges;
+ };
+
+ class EdgeData {
+ public:
+ HeuristicEdgeData& getHeuristicData() { return hData; }
+
+ void setN1SolverEdgeItr(SolverEdgeItr n1SolverEdgeItr) {
+ this->n1SolverEdgeItr = n1SolverEdgeItr;
+ }
- AdjLinkIterator adjLinksBegin() {
- return links.begin();
- }
+ SolverEdgeItr getN1SolverEdgeItr() { return n1SolverEdgeItr; }
- AdjLinkIterator adjLinksEnd() {
- return links.end();
- }
+ void setN2SolverEdgeItr(SolverEdgeItr n2SolverEdgeItr){
+ this->n2SolverEdgeItr = n2SolverEdgeItr;
+ }
- void addSolvedLink(const GraphEdgeIterator &solvedLinkItr) {
- solvedLinks.push_back(solvedLinkItr);
- }
+ SolverEdgeItr getN2SolverEdgeItr() { return n2SolverEdgeItr; }
- AdjLinkIterator solvedLinksBegin() {
- return solvedLinks.begin();
- }
+ private:
- AdjLinkIterator solvedLinksEnd() {
- return solvedLinks.end();
- }
+ HeuristicEdgeData hData;
+ SolverEdgeItr n1SolverEdgeItr, n2SolverEdgeItr;
+ };
- };
+ Graph &g;
+ HImpl h;
+ Solution s;
+ std::vector<Graph::NodeItr> stack;
- class EdgeData {
- private:
+ typedef std::list<NodeData> NodeDataList;
+ NodeDataList nodeDataList;
- SolverGraph &g;
- GraphNodeIterator node1Itr, node2Itr;
- HeuristicEdgeData heuristicData;
- typename NodeData::AdjLinkIterator node1ThisEdgeItr, node2ThisEdgeItr;
+ typedef std::list<EdgeData> EdgeDataList;
+ EdgeDataList edgeDataList;
public:
- EdgeData(SolverGraph &g) : g(g) {}
-
- HeuristicEdgeData& getHeuristicData() { return heuristicData; }
- const HeuristicEdgeData& getHeuristicData() const {
- return heuristicData;
- }
-
- void setup(const GraphEdgeIterator &thisEdgeItr) {
- node1Itr = g.getEdgeNode1Itr(thisEdgeItr);
- node2Itr = g.getEdgeNode2Itr(thisEdgeItr);
-
- node1ThisEdgeItr = g.getNodeData(node1Itr).addLink(thisEdgeItr);
- node2ThisEdgeItr = g.getNodeData(node2Itr).addLink(thisEdgeItr);
- }
-
- void unlink() {
- g.getNodeData(node1Itr).delLink(node1ThisEdgeItr);
- g.getNodeData(node2Itr).delLink(node2ThisEdgeItr);
- }
-
- };
-
-};
-
-template <typename Heuristic>
-class HeuristicSolverImpl {
-public:
- // Typedefs to make life easier:
- typedef HSITypes<typename Heuristic::NodeData,
- typename Heuristic::EdgeData> HSIT;
- typedef typename HSIT::SolverGraph SolverGraph;
- typedef typename HSIT::NodeData NodeData;
- typedef typename HSIT::EdgeData EdgeData;
- typedef typename HSIT::GraphNodeIterator GraphNodeIterator;
- typedef typename HSIT::GraphEdgeIterator GraphEdgeIterator;
- typedef typename HSIT::GraphAdjEdgeIterator GraphAdjEdgeIterator;
-
- typedef typename HSIT::NodeList NodeList;
- typedef typename HSIT::NodeListIterator NodeListIterator;
-
- typedef std::vector<GraphNodeIterator> NodeStack;
- typedef typename NodeStack::iterator NodeStackIterator;
-
- /// \brief Constructor, which performs all the actual solver work.
- HeuristicSolverImpl(const SimpleGraph &orig) :
- solution(orig.getNumNodes(), true)
- {
- copyGraph(orig);
- simplify();
- setup();
- computeSolution();
- computeSolutionCost(orig);
- }
-
- /// \brief Returns the graph for this solver.
- SolverGraph& getGraph() { return g; }
-
- /// \brief Return the solution found by this solver.
- const Solution& getSolution() const { return solution; }
-
-private:
-
- /// \brief Add the given node to the appropriate bucket for its link
- /// degree.
- void addToBucket(const GraphNodeIterator &nodeItr) {
- NodeData &nodeData = g.getNodeData(nodeItr);
-
- switch (nodeData.getLinkDegree()) {
- case 0: nodeData.setBucketItr(
- r0Bucket.insert(r0Bucket.end(), nodeItr));
- break;
- case 1: nodeData.setBucketItr(
- r1Bucket.insert(r1Bucket.end(), nodeItr));
- break;
- case 2: nodeData.setBucketItr(
- r2Bucket.insert(r2Bucket.end(), nodeItr));
- break;
- default: heuristic.addToRNBucket(nodeItr);
- break;
- }
- }
-
- /// \brief Remove the given node from the appropriate bucket for its link
- /// degree.
- void removeFromBucket(const GraphNodeIterator &nodeItr) {
- NodeData &nodeData = g.getNodeData(nodeItr);
-
- switch (nodeData.getLinkDegree()) {
- case 0: r0Bucket.erase(nodeData.getBucketItr()); break;
- case 1: r1Bucket.erase(nodeData.getBucketItr()); break;
- case 2: r2Bucket.erase(nodeData.getBucketItr()); break;
- default: heuristic.removeFromRNBucket(nodeItr); break;
- }
- }
-
-public:
-
- /// \brief Add a link.
- void addLink(const GraphEdgeIterator &edgeItr) {
- g.getEdgeData(edgeItr).setup(edgeItr);
-
- if ((g.getNodeData(g.getEdgeNode1Itr(edgeItr)).getLinkDegree() > 2) ||
- (g.getNodeData(g.getEdgeNode2Itr(edgeItr)).getLinkDegree() > 2)) {
- heuristic.handleAddLink(edgeItr);
- }
- }
-
- /// \brief Remove link, update info for node.
- ///
- /// Only updates information for the given node, since usually the other
- /// is about to be removed.
- void removeLink(const GraphEdgeIterator &edgeItr,
- const GraphNodeIterator &nodeItr) {
-
- if (g.getNodeData(nodeItr).getLinkDegree() > 2) {
- heuristic.handleRemoveLink(edgeItr, nodeItr);
- }
- g.getEdgeData(edgeItr).unlink();
- }
-
- /// \brief Remove link, update info for both nodes. Useful for R2 only.
- void removeLinkR2(const GraphEdgeIterator &edgeItr) {
- GraphNodeIterator node1Itr = g.getEdgeNode1Itr(edgeItr);
-
- if (g.getNodeData(node1Itr).getLinkDegree() > 2) {
- heuristic.handleRemoveLink(edgeItr, node1Itr);
+ /// \brief Construct a heuristic solver implementation to solve the given
+ /// graph.
+ /// @param g The graph representing the problem instance to be solved.
+ HeuristicSolverImpl(Graph &g) : g(g), h(*this) {}
+
+ /// \brief Get the graph being solved by this solver.
+ /// @return The graph representing the problem instance being solved by this
+ /// solver.
+ Graph& getGraph() { return g; }
+
+ /// \brief Get the heuristic data attached to the given node.
+ /// @param nItr Node iterator.
+ /// @return The heuristic data attached to the given node.
+ HeuristicNodeData& getHeuristicNodeData(Graph::NodeItr nItr) {
+ return getSolverNodeData(nItr).getHeuristicData();
+ }
+
+ /// \brief Get the heuristic data attached to the given edge.
+ /// @param eItr Edge iterator.
+ /// @return The heuristic data attached to the given node.
+ HeuristicEdgeData& getHeuristicEdgeData(Graph::EdgeItr eItr) {
+ return getSolverEdgeData(eItr).getHeuristicData();
+ }
+
+ /// \brief Begin iterator for the set of edges adjacent to the given node in
+ /// the solver graph.
+ /// @param nItr Node iterator.
+ /// @return Begin iterator for the set of edges adjacent to the given node
+ /// in the solver graph.
+ SolverEdgeItr solverEdgesBegin(Graph::NodeItr nItr) {
+ return getSolverNodeData(nItr).solverEdgesBegin();
+ }
+
+ /// \brief End iterator for the set of edges adjacent to the given node in
+ /// the solver graph.
+ /// @param nItr Node iterator.
+ /// @return End iterator for the set of edges adjacent to the given node in
+ /// the solver graph.
+ SolverEdgeItr solverEdgesEnd(Graph::NodeItr nItr) {
+ return getSolverNodeData(nItr).solverEdgesEnd();
+ }
+
+ /// \brief Remove a node from the solver graph.
+ /// @param eItr Edge iterator for edge to be removed.
+ ///
+ /// Does <i>not</i> notify the heuristic of the removal. That should be
+ /// done manually if necessary.
+ void removeSolverEdge(Graph::EdgeItr eItr) {
+ EdgeData &eData = getSolverEdgeData(eItr);
+ NodeData &n1Data = getSolverNodeData(g.getEdgeNode1(eItr)),
+ &n2Data = getSolverNodeData(g.getEdgeNode2(eItr));
+
+ n1Data.removeSolverEdge(eData.getN1SolverEdgeItr());
+ n2Data.removeSolverEdge(eData.getN2SolverEdgeItr());
+ }
+
+ /// \brief Compute a solution to the PBQP problem instance with which this
+ /// heuristic solver was constructed.
+ /// @return A solution to the PBQP problem.
+ ///
+ /// Performs the full PBQP heuristic solver algorithm, including setup,
+ /// calls to the heuristic (which will call back to the reduction rules in
+ /// this class), and cleanup.
+ Solution computeSolution() {
+ setup();
+ h.setup();
+ h.reduce();
+ backpropagate();
+ h.cleanup();
+ cleanup();
+ return s;
+ }
+
+ /// \brief Add to the end of the stack.
+ /// @param nItr Node iterator to add to the reduction stack.
+ void pushToStack(Graph::NodeItr nItr) {
+ getSolverNodeData(nItr).clearSolverEdges();
+ stack.push_back(nItr);
+ }
+
+ /// \brief Returns the solver degree of the given node.
+ /// @param nItr Node iterator for which degree is requested.
+ /// @return Node degree in the <i>solver</i> graph (not the original graph).
+ unsigned getSolverDegree(Graph::NodeItr nItr) {
+ return getSolverNodeData(nItr).getSolverDegree();
+ }
+
+ /// \brief Set the solution of the given node.
+ /// @param nItr Node iterator to set solution for.
+ /// @param selection Selection for node.
+ void setSolution(const Graph::NodeItr &nItr, unsigned selection) {
+ s.setSelection(nItr, selection);
+
+ for (Graph::AdjEdgeItr aeItr = g.adjEdgesBegin(nItr),
+ aeEnd = g.adjEdgesEnd(nItr);
+ aeItr != aeEnd; ++aeItr) {
+ Graph::EdgeItr eItr(*aeItr);
+ Graph::NodeItr anItr(g.getEdgeOtherNode(eItr, nItr));
+ getSolverNodeData(anItr).addSolverEdge(eItr);
+ }
}
- removeLink(edgeItr, g.getEdgeNode2Itr(edgeItr));
- }
-
- /// \brief Removes all links connected to the given node.
- void unlinkNode(const GraphNodeIterator &nodeItr) {
- NodeData &nodeData = g.getNodeData(nodeItr);
-
- typedef std::vector<GraphEdgeIterator> TempEdgeList;
- TempEdgeList edgesToUnlink;
- edgesToUnlink.reserve(nodeData.getLinkDegree());
+ /// \brief Apply rule R0.
+ /// @param nItr Node iterator for node to apply R0 to.
+ ///
+ /// Node will be automatically pushed to the solver stack.
+ void applyR0(Graph::NodeItr nItr) {
+ assert(getSolverNodeData(nItr).getSolverDegree() == 0 &&
+ "R0 applied to node with degree != 0.");
- // Copy adj edges into a temp vector. We want to destroy them during
- // the unlink, and we can't do that while we're iterating over them.
- std::copy(nodeData.adjLinksBegin(), nodeData.adjLinksEnd(),
- std::back_inserter(edgesToUnlink));
-
- for (typename TempEdgeList::iterator
- edgeItr = edgesToUnlink.begin(), edgeEnd = edgesToUnlink.end();
- edgeItr != edgeEnd; ++edgeItr) {
-
- GraphNodeIterator otherNode = g.getEdgeOtherNode(*edgeItr, nodeItr);
-
- removeFromBucket(otherNode);
- removeLink(*edgeItr, otherNode);
- addToBucket(otherNode);
+ // Nothing to do. Just push the node onto the reduction stack.
+ pushToStack(nItr);
}
- }
-
- /// \brief Push the given node onto the stack to be solved with
- /// backpropagation.
- void pushStack(const GraphNodeIterator &nodeItr) {
- stack.push_back(nodeItr);
- }
-
- /// \brief Set the solution of the given node.
- void setSolution(const GraphNodeIterator &nodeItr, unsigned solIndex) {
- solution.setSelection(g.getNodeID(nodeItr), solIndex);
-
- for (GraphAdjEdgeIterator adjEdgeItr = g.adjEdgesBegin(nodeItr),
- adjEdgeEnd = g.adjEdgesEnd(nodeItr);
- adjEdgeItr != adjEdgeEnd; ++adjEdgeItr) {
- GraphEdgeIterator edgeItr(*adjEdgeItr);
- GraphNodeIterator adjNodeItr(g.getEdgeOtherNode(edgeItr, nodeItr));
- g.getNodeData(adjNodeItr).addSolvedLink(edgeItr);
- }
- }
-
-private:
- SolverGraph g;
- Heuristic heuristic;
- Solution solution;
+ /// \brief Apply rule R1.
+ /// @param nItr Node iterator for node to apply R1 to.
+ ///
+ /// Node will be automatically pushed to the solver stack.
+ void applyR1(Graph::NodeItr xnItr) {
+ NodeData &nd = getSolverNodeData(xnItr);
+ assert(nd.getSolverDegree() == 1 &&
+ "R1 applied to node with degree != 1.");
- NodeList r0Bucket,
- r1Bucket,
- r2Bucket;
+ Graph::EdgeItr eItr = *nd.solverEdgesBegin();
- NodeStack stack;
-
- // Copy the SimpleGraph into an annotated graph which we can use for reduction.
- void copyGraph(const SimpleGraph &orig) {
-
- assert((g.getNumEdges() == 0) && (g.getNumNodes() == 0) &&
- "Graph should be empty prior to solver setup.");
-
- assert(orig.areNodeIDsValid() &&
- "Cannot copy from a graph with invalid node IDs.");
-
- std::vector<GraphNodeIterator> newNodeItrs;
-
- for (unsigned nodeID = 0; nodeID < orig.getNumNodes(); ++nodeID) {
- newNodeItrs.push_back(
- g.addNode(orig.getNodeCosts(orig.getNodeItr(nodeID)), NodeData()));
+ const Matrix &eCosts = g.getEdgeCosts(eItr);
+ const Vector &xCosts = g.getNodeCosts(xnItr);
+
+ // Duplicate a little to avoid transposing matrices.
+ if (xnItr == g.getEdgeNode1(eItr)) {
+ Graph::NodeItr ynItr = g.getEdgeNode2(eItr);
+ Vector &yCosts = g.getNodeCosts(ynItr);
+ for (unsigned j = 0; j < yCosts.getLength(); ++j) {
+ PBQPNum min = eCosts[0][j] + xCosts[0];
+ for (unsigned i = 1; i < xCosts.getLength(); ++i) {
+ PBQPNum c = eCosts[i][j] + xCosts[i];
+ if (c < min)
+ min = c;
+ }
+ yCosts[j] += min;
+ }
+ h.handleRemoveEdge(eItr, ynItr);
+ } else {
+ Graph::NodeItr ynItr = g.getEdgeNode1(eItr);
+ Vector &yCosts = g.getNodeCosts(ynItr);
+ for (unsigned i = 0; i < yCosts.getLength(); ++i) {
+ PBQPNum min = eCosts[i][0] + xCosts[0];
+ for (unsigned j = 1; j < xCosts.getLength(); ++j) {
+ PBQPNum c = eCosts[i][j] + xCosts[j];
+ if (c < min)
+ min = c;
+ }
+ yCosts[i] += min;
+ }
+ h.handleRemoveEdge(eItr, ynItr);
+ }
+ removeSolverEdge(eItr);
+ assert(nd.getSolverDegree() == 0 &&
+ "Degree 1 with edge removed should be 0.");
+ pushToStack(xnItr);
}
- for (SimpleGraph::ConstEdgeIterator
- origEdgeItr = orig.edgesBegin(), origEdgeEnd = orig.edgesEnd();
- origEdgeItr != origEdgeEnd; ++origEdgeItr) {
-
- unsigned id1 = orig.getNodeID(orig.getEdgeNode1Itr(origEdgeItr)),
- id2 = orig.getNodeID(orig.getEdgeNode2Itr(origEdgeItr));
+ /// \brief Apply rule R2.
+ /// @param nItr Node iterator for node to apply R2 to.
+ ///
+ /// Node will be automatically pushed to the solver stack.
+ void applyR2(Graph::NodeItr xnItr) {
+ assert(getSolverNodeData(xnItr).getSolverDegree() == 2 &&
+ "R2 applied to node with degree != 2.");
- g.addEdge(newNodeItrs[id1], newNodeItrs[id2],
- orig.getEdgeCosts(origEdgeItr), EdgeData(g));
- }
+ NodeData &nd = getSolverNodeData(xnItr);
+ const Vector &xCosts = g.getNodeCosts(xnItr);
- // Assign IDs to the new nodes using the ordering from the old graph,
- // this will lead to nodes in the new graph getting the same ID as the
- // corresponding node in the old graph.
- g.assignNodeIDs(newNodeItrs);
- }
+ SolverEdgeItr aeItr = nd.solverEdgesBegin();
+ Graph::EdgeItr yxeItr = *aeItr,
+ zxeItr = *(++aeItr);
- // Simplify the annotated graph by eliminating independent edges and trivial
- // nodes.
- void simplify() {
- disconnectTrivialNodes();
- eliminateIndependentEdges();
- }
+ Graph::NodeItr ynItr = g.getEdgeOtherNode(yxeItr, xnItr),
+ znItr = g.getEdgeOtherNode(zxeItr, xnItr);
- // Eliminate trivial nodes.
- void disconnectTrivialNodes() {
- for (GraphNodeIterator nodeItr = g.nodesBegin(), nodeEnd = g.nodesEnd();
- nodeItr != nodeEnd; ++nodeItr) {
+ bool flipEdge1 = (g.getEdgeNode1(yxeItr) == xnItr),
+ flipEdge2 = (g.getEdgeNode1(zxeItr) == xnItr);
- if (g.getNodeCosts(nodeItr).getLength() == 1) {
+ const Matrix *yxeCosts = flipEdge1 ?
+ new Matrix(g.getEdgeCosts(yxeItr).transpose()) :
+ &g.getEdgeCosts(yxeItr);
- std::vector<GraphEdgeIterator> edgesToRemove;
+ const Matrix *zxeCosts = flipEdge2 ?
+ new Matrix(g.getEdgeCosts(zxeItr).transpose()) :
+ &g.getEdgeCosts(zxeItr);
- for (GraphAdjEdgeIterator adjEdgeItr = g.adjEdgesBegin(nodeItr),
- adjEdgeEnd = g.adjEdgesEnd(nodeItr);
- adjEdgeItr != adjEdgeEnd; ++adjEdgeItr) {
+ unsigned xLen = xCosts.getLength(),
+ yLen = yxeCosts->getRows(),
+ zLen = zxeCosts->getRows();
+
+ Matrix delta(yLen, zLen);
- GraphEdgeIterator edgeItr = *adjEdgeItr;
-
- if (g.getEdgeNode1Itr(edgeItr) == nodeItr) {
- GraphNodeIterator otherNodeItr = g.getEdgeNode2Itr(edgeItr);
- g.getNodeCosts(otherNodeItr) +=
- g.getEdgeCosts(edgeItr).getRowAsVector(0);
- }
- else {
- GraphNodeIterator otherNodeItr = g.getEdgeNode1Itr(edgeItr);
- g.getNodeCosts(otherNodeItr) +=
- g.getEdgeCosts(edgeItr).getColAsVector(0);
+ for (unsigned i = 0; i < yLen; ++i) {
+ for (unsigned j = 0; j < zLen; ++j) {
+ PBQPNum min = (*yxeCosts)[i][0] + (*zxeCosts)[j][0] + xCosts[0];
+ for (unsigned k = 1; k < xLen; ++k) {
+ PBQPNum c = (*yxeCosts)[i][k] + (*zxeCosts)[j][k] + xCosts[k];
+ if (c < min) {
+ min = c;
+ }
}
-
- edgesToRemove.push_back(edgeItr);
+ delta[i][j] = min;
}
+ }
- while (!edgesToRemove.empty()) {
- g.removeEdge(edgesToRemove.back());
- edgesToRemove.pop_back();
+ if (flipEdge1)
+ delete yxeCosts;
+
+ if (flipEdge2)
+ delete zxeCosts;
+
+ Graph::EdgeItr yzeItr = g.findEdge(ynItr, znItr);
+ bool addedEdge = false;
+
+ if (yzeItr == g.edgesEnd()) {
+ yzeItr = g.addEdge(ynItr, znItr, delta);
+ addedEdge = true;
+ } else {
+ Matrix &yzeCosts = g.getEdgeCosts(yzeItr);
+ h.preUpdateEdgeCosts(yzeItr);
+ if (ynItr == g.getEdgeNode1(yzeItr)) {
+ yzeCosts += delta;
+ } else {
+ yzeCosts += delta.transpose();
}
}
- }
- }
- void eliminateIndependentEdges() {
- std::vector<GraphEdgeIterator> edgesToProcess;
+ bool nullCostEdge = tryNormaliseEdgeMatrix(yzeItr);
- for (GraphEdgeIterator edgeItr = g.edgesBegin(), edgeEnd = g.edgesEnd();
- edgeItr != edgeEnd; ++edgeItr) {
- edgesToProcess.push_back(edgeItr);
- }
-
- while (!edgesToProcess.empty()) {
- tryToEliminateEdge(edgesToProcess.back());
- edgesToProcess.pop_back();
- }
- }
-
- void tryToEliminateEdge(const GraphEdgeIterator &edgeItr) {
- if (tryNormaliseEdgeMatrix(edgeItr)) {
- g.removeEdge(edgeItr);
- }
- }
-
- bool tryNormaliseEdgeMatrix(const GraphEdgeIterator &edgeItr) {
-
- Matrix &edgeCosts = g.getEdgeCosts(edgeItr);
- Vector &uCosts = g.getNodeCosts(g.getEdgeNode1Itr(edgeItr)),
- &vCosts = g.getNodeCosts(g.getEdgeNode2Itr(edgeItr));
-
- for (unsigned r = 0; r < edgeCosts.getRows(); ++r) {
- PBQPNum rowMin = edgeCosts.getRowMin(r);
- uCosts[r] += rowMin;
- if (rowMin != std::numeric_limits<PBQPNum>::infinity()) {
- edgeCosts.subFromRow(r, rowMin);
+ if (!addedEdge) {
+ // If we modified the edge costs let the heuristic know.
+ h.postUpdateEdgeCosts(yzeItr);
}
- else {
- edgeCosts.setRow(r, 0);
+
+ if (nullCostEdge) {
+ // If this edge ended up null remove it.
+ if (!addedEdge) {
+ // We didn't just add it, so we need to notify the heuristic
+ // and remove it from the solver.
+ h.handleRemoveEdge(yzeItr, ynItr);
+ h.handleRemoveEdge(yzeItr, znItr);
+ removeSolverEdge(yzeItr);
+ }
+ g.removeEdge(yzeItr);
+ } else if (addedEdge) {
+ // If the edge was added, and non-null, finish setting it up, add it to
+ // the solver & notify heuristic.
+ edgeDataList.push_back(EdgeData());
+ g.setEdgeData(yzeItr, &edgeDataList.back());
+ addSolverEdge(yzeItr);
+ h.handleAddEdge(yzeItr);
}
- }
- for (unsigned c = 0; c < edgeCosts.getCols(); ++c) {
- PBQPNum colMin = edgeCosts.getColMin(c);
- vCosts[c] += colMin;
- if (colMin != std::numeric_limits<PBQPNum>::infinity()) {
- edgeCosts.subFromCol(c, colMin);
- }
- else {
- edgeCosts.setCol(c, 0);
- }
- }
+ h.handleRemoveEdge(yxeItr, ynItr);
+ removeSolverEdge(yxeItr);
+ h.handleRemoveEdge(zxeItr, znItr);
+ removeSolverEdge(zxeItr);
- return edgeCosts.isZero();
- }
+ pushToStack(xnItr);
+ }
- void setup() {
- setupLinks();
- heuristic.initialise(*this);
- setupBuckets();
- }
+ private:
- void setupLinks() {
- for (GraphEdgeIterator edgeItr = g.edgesBegin(), edgeEnd = g.edgesEnd();
- edgeItr != edgeEnd; ++edgeItr) {
- g.getEdgeData(edgeItr).setup(edgeItr);
+ NodeData& getSolverNodeData(Graph::NodeItr nItr) {
+ return *static_cast<NodeData*>(g.getNodeData(nItr));
}
- }
- void setupBuckets() {
- for (GraphNodeIterator nodeItr = g.nodesBegin(), nodeEnd = g.nodesEnd();
- nodeItr != nodeEnd; ++nodeItr) {
- addToBucket(nodeItr);
- }
- }
-
- void computeSolution() {
- assert(g.areNodeIDsValid() &&
- "Nodes cannot be added/removed during reduction.");
-
- reduce();
- computeTrivialSolutions();
- backpropagate();
- }
-
- void printNode(const GraphNodeIterator &nodeItr) {
- llvm::errs() << "Node " << g.getNodeID(nodeItr) << " (" << &*nodeItr << "):\n"
- << " costs = " << g.getNodeCosts(nodeItr) << "\n"
- << " link degree = " << g.getNodeData(nodeItr).getLinkDegree() << "\n"
- << " links = [ ";
-
- for (typename HSIT::NodeData::AdjLinkIterator
- aeItr = g.getNodeData(nodeItr).adjLinksBegin(),
- aeEnd = g.getNodeData(nodeItr).adjLinksEnd();
- aeItr != aeEnd; ++aeItr) {
- llvm::errs() << "(" << g.getNodeID(g.getEdgeNode1Itr(*aeItr))
- << ", " << g.getNodeID(g.getEdgeNode2Itr(*aeItr))
- << ") ";
+ EdgeData& getSolverEdgeData(Graph::EdgeItr eItr) {
+ return *static_cast<EdgeData*>(g.getEdgeData(eItr));
}
- llvm::errs() << "]\n";
- }
- void dumpState() {
- llvm::errs() << "\n";
+ void addSolverEdge(Graph::EdgeItr eItr) {
+ EdgeData &eData = getSolverEdgeData(eItr);
+ NodeData &n1Data = getSolverNodeData(g.getEdgeNode1(eItr)),
+ &n2Data = getSolverNodeData(g.getEdgeNode2(eItr));
- for (GraphNodeIterator nodeItr = g.nodesBegin(), nodeEnd = g.nodesEnd();
- nodeItr != nodeEnd; ++nodeItr) {
- printNode(nodeItr);
+ eData.setN1SolverEdgeItr(n1Data.addSolverEdge(eItr));
+ eData.setN2SolverEdgeItr(n2Data.addSolverEdge(eItr));
}
- NodeList* buckets[] = { &r0Bucket, &r1Bucket, &r2Bucket };
-
- for (unsigned b = 0; b < 3; ++b) {
- NodeList &bucket = *buckets[b];
-
- llvm::errs() << "Bucket " << b << ": [ ";
-
- for (NodeListIterator nItr = bucket.begin(), nEnd = bucket.end();
- nItr != nEnd; ++nItr) {
- llvm::errs() << g.getNodeID(*nItr) << " ";
+ void setup() {
+ if (h.solverRunSimplify()) {
+ simplify();
}
- llvm::errs() << "]\n";
- }
+ // Create node data objects.
+ for (Graph::NodeItr nItr = g.nodesBegin(), nEnd = g.nodesEnd();
+ nItr != nEnd; ++nItr) {
+ nodeDataList.push_back(NodeData());
+ g.setNodeData(nItr, &nodeDataList.back());
+ }
- llvm::errs() << "Stack: [ ";
- for (NodeStackIterator nsItr = stack.begin(), nsEnd = stack.end();
- nsItr != nsEnd; ++nsItr) {
- llvm::errs() << g.getNodeID(*nsItr) << " ";
+ // Create edge data objects.
+ for (Graph::EdgeItr eItr = g.edgesBegin(), eEnd = g.edgesEnd();
+ eItr != eEnd; ++eItr) {
+ edgeDataList.push_back(EdgeData());
+ g.setEdgeData(eItr, &edgeDataList.back());
+ addSolverEdge(eItr);
+ }
}
- llvm::errs() << "]\n";
- }
-
- void reduce() {
- bool reductionFinished = r1Bucket.empty() && r2Bucket.empty() &&
- heuristic.rNBucketEmpty();
- while (!reductionFinished) {
-
- if (!r1Bucket.empty()) {
- processR1();
- }
- else if (!r2Bucket.empty()) {
- processR2();
- }
- else if (!heuristic.rNBucketEmpty()) {
- solution.setProvedOptimal(false);
- solution.incRNReductions();
- heuristic.processRN();
- }
- else reductionFinished = true;
+ void simplify() {
+ disconnectTrivialNodes();
+ eliminateIndependentEdges();
}
-
- }
- void processR1() {
+ // Eliminate trivial nodes.
+ void disconnectTrivialNodes() {
+ unsigned numDisconnected = 0;
- // Remove the first node in the R0 bucket:
- GraphNodeIterator xNodeItr = r1Bucket.front();
- r1Bucket.pop_front();
+ for (Graph::NodeItr nItr = g.nodesBegin(), nEnd = g.nodesEnd();
+ nItr != nEnd; ++nItr) {
- solution.incR1Reductions();
+ if (g.getNodeCosts(nItr).getLength() == 1) {
- //llvm::errs() << "Applying R1 to " << g.getNodeID(xNodeItr) << "\n";
+ std::vector<Graph::EdgeItr> edgesToRemove;
- assert((g.getNodeData(xNodeItr).getLinkDegree() == 1) &&
- "Node in R1 bucket has degree != 1");
+ for (Graph::AdjEdgeItr aeItr = g.adjEdgesBegin(nItr),
+ aeEnd = g.adjEdgesEnd(nItr);
+ aeItr != aeEnd; ++aeItr) {
- GraphEdgeIterator edgeItr = *g.getNodeData(xNodeItr).adjLinksBegin();
+ Graph::EdgeItr eItr = *aeItr;
- const Matrix &edgeCosts = g.getEdgeCosts(edgeItr);
+ if (g.getEdgeNode1(eItr) == nItr) {
+ Graph::NodeItr otherNodeItr = g.getEdgeNode2(eItr);
+ g.getNodeCosts(otherNodeItr) +=
+ g.getEdgeCosts(eItr).getRowAsVector(0);
+ }
+ else {
+ Graph::NodeItr otherNodeItr = g.getEdgeNode1(eItr);
+ g.getNodeCosts(otherNodeItr) +=
+ g.getEdgeCosts(eItr).getColAsVector(0);
+ }
- const Vector &xCosts = g.getNodeCosts(xNodeItr);
- unsigned xLen = xCosts.getLength();
+ edgesToRemove.push_back(eItr);
+ }
- // Duplicate a little code to avoid transposing matrices:
- if (xNodeItr == g.getEdgeNode1Itr(edgeItr)) {
- GraphNodeIterator yNodeItr = g.getEdgeNode2Itr(edgeItr);
- Vector &yCosts = g.getNodeCosts(yNodeItr);
- unsigned yLen = yCosts.getLength();
+ if (!edgesToRemove.empty())
+ ++numDisconnected;
- for (unsigned j = 0; j < yLen; ++j) {
- PBQPNum min = edgeCosts[0][j] + xCosts[0];
- for (unsigned i = 1; i < xLen; ++i) {
- PBQPNum c = edgeCosts[i][j] + xCosts[i];
- if (c < min)
- min = c;
+ while (!edgesToRemove.empty()) {
+ g.removeEdge(edgesToRemove.back());
+ edgesToRemove.pop_back();
+ }
}
- yCosts[j] += min;
}
}
- else {
- GraphNodeIterator yNodeItr = g.getEdgeNode1Itr(edgeItr);
- Vector &yCosts = g.getNodeCosts(yNodeItr);
- unsigned yLen = yCosts.getLength();
- for (unsigned i = 0; i < yLen; ++i) {
- PBQPNum min = edgeCosts[i][0] + xCosts[0];
+ void eliminateIndependentEdges() {
+ std::vector<Graph::EdgeItr> edgesToProcess;
+ unsigned numEliminated = 0;
- for (unsigned j = 1; j < xLen; ++j) {
- PBQPNum c = edgeCosts[i][j] + xCosts[j];
- if (c < min)
- min = c;
- }
- yCosts[i] += min;
+ for (Graph::EdgeItr eItr = g.edgesBegin(), eEnd = g.edgesEnd();
+ eItr != eEnd; ++eItr) {
+ edgesToProcess.push_back(eItr);
}
- }
-
- unlinkNode(xNodeItr);
- pushStack(xNodeItr);
- }
-
- void processR2() {
-
- GraphNodeIterator xNodeItr = r2Bucket.front();
- r2Bucket.pop_front();
-
- solution.incR2Reductions();
-
- // Unlink is unsafe here. At some point it may optimistically more a node
- // to a lower-degree list when its degree will later rise, or vice versa,
- // violating the assumption that node degrees monotonically decrease
- // during the reduction phase. Instead we'll bucket shuffle manually.
- pushStack(xNodeItr);
-
- assert((g.getNodeData(xNodeItr).getLinkDegree() == 2) &&
- "Node in R2 bucket has degree != 2");
-
- const Vector &xCosts = g.getNodeCosts(xNodeItr);
- typename NodeData::AdjLinkIterator tempItr =
- g.getNodeData(xNodeItr).adjLinksBegin();
-
- GraphEdgeIterator yxEdgeItr = *tempItr,
- zxEdgeItr = *(++tempItr);
+ while (!edgesToProcess.empty()) {
+ if (tryToEliminateEdge(edgesToProcess.back()))
+ ++numEliminated;
+ edgesToProcess.pop_back();
+ }
+ }
- GraphNodeIterator yNodeItr = g.getEdgeOtherNode(yxEdgeItr, xNodeItr),
- zNodeItr = g.getEdgeOtherNode(zxEdgeItr, xNodeItr);
+ bool tryToEliminateEdge(Graph::EdgeItr eItr) {
+ if (tryNormaliseEdgeMatrix(eItr)) {
+ g.removeEdge(eItr);
+ return true;
+ }
+ return false;
+ }
- removeFromBucket(yNodeItr);
- removeFromBucket(zNodeItr);
+ bool tryNormaliseEdgeMatrix(Graph::EdgeItr &eItr) {
- removeLink(yxEdgeItr, yNodeItr);
- removeLink(zxEdgeItr, zNodeItr);
+ const PBQPNum infinity = std::numeric_limits<PBQPNum>::infinity();
- // Graph some of the costs:
- bool flipEdge1 = (g.getEdgeNode1Itr(yxEdgeItr) == xNodeItr),
- flipEdge2 = (g.getEdgeNode1Itr(zxEdgeItr) == xNodeItr);
+ Matrix &edgeCosts = g.getEdgeCosts(eItr);
+ Vector &uCosts = g.getNodeCosts(g.getEdgeNode1(eItr)),
+ &vCosts = g.getNodeCosts(g.getEdgeNode2(eItr));
- const Matrix *yxCosts = flipEdge1 ?
- new Matrix(g.getEdgeCosts(yxEdgeItr).transpose()) :
- &g.getEdgeCosts(yxEdgeItr),
- *zxCosts = flipEdge2 ?
- new Matrix(g.getEdgeCosts(zxEdgeItr).transpose()) :
- &g.getEdgeCosts(zxEdgeItr);
+ for (unsigned r = 0; r < edgeCosts.getRows(); ++r) {
+ PBQPNum rowMin = infinity;
- unsigned xLen = xCosts.getLength(),
- yLen = yxCosts->getRows(),
- zLen = zxCosts->getRows();
+ for (unsigned c = 0; c < edgeCosts.getCols(); ++c) {
+ if (vCosts[c] != infinity && edgeCosts[r][c] < rowMin)
+ rowMin = edgeCosts[r][c];
+ }
- // Compute delta:
- Matrix delta(yLen, zLen);
+ uCosts[r] += rowMin;
- for (unsigned i = 0; i < yLen; ++i) {
- for (unsigned j = 0; j < zLen; ++j) {
- PBQPNum min = (*yxCosts)[i][0] + (*zxCosts)[j][0] + xCosts[0];
- for (unsigned k = 1; k < xLen; ++k) {
- PBQPNum c = (*yxCosts)[i][k] + (*zxCosts)[j][k] + xCosts[k];
- if (c < min) {
- min = c;
- }
+ if (rowMin != infinity) {
+ edgeCosts.subFromRow(r, rowMin);
+ }
+ else {
+ edgeCosts.setRow(r, 0);
}
- delta[i][j] = min;
}
- }
-
- if (flipEdge1)
- delete yxCosts;
- if (flipEdge2)
- delete zxCosts;
+ for (unsigned c = 0; c < edgeCosts.getCols(); ++c) {
+ PBQPNum colMin = infinity;
- // Deal with the potentially induced yz edge.
- GraphEdgeIterator yzEdgeItr = g.findEdge(yNodeItr, zNodeItr);
- if (yzEdgeItr == g.edgesEnd()) {
- yzEdgeItr = g.addEdge(yNodeItr, zNodeItr, delta, EdgeData(g));
- }
- else {
- // There was an edge, but we're going to screw with it. Delete the old
- // link, update the costs. We'll re-link it later.
- removeLinkR2(yzEdgeItr);
- g.getEdgeCosts(yzEdgeItr) +=
- (yNodeItr == g.getEdgeNode1Itr(yzEdgeItr)) ?
- delta : delta.transpose();
- }
+ for (unsigned r = 0; r < edgeCosts.getRows(); ++r) {
+ if (uCosts[r] != infinity && edgeCosts[r][c] < colMin)
+ colMin = edgeCosts[r][c];
+ }
- bool nullCostEdge = tryNormaliseEdgeMatrix(yzEdgeItr);
+ vCosts[c] += colMin;
- // Nulled the edge, remove it entirely.
- if (nullCostEdge) {
- g.removeEdge(yzEdgeItr);
- }
- else {
- // Edge remains - re-link it.
- addLink(yzEdgeItr);
- }
+ if (colMin != infinity) {
+ edgeCosts.subFromCol(c, colMin);
+ }
+ else {
+ edgeCosts.setCol(c, 0);
+ }
+ }
- addToBucket(yNodeItr);
- addToBucket(zNodeItr);
+ return edgeCosts.isZero();
}
- void computeTrivialSolutions() {
-
- for (NodeListIterator r0Itr = r0Bucket.begin(), r0End = r0Bucket.end();
- r0Itr != r0End; ++r0Itr) {
- GraphNodeIterator nodeItr = *r0Itr;
-
- solution.incR0Reductions();
- setSolution(nodeItr, g.getNodeCosts(nodeItr).minIndex());
+ void backpropagate() {
+ while (!stack.empty()) {
+ computeSolution(stack.back());
+ stack.pop_back();
+ }
}
- }
-
- void backpropagate() {
- while (!stack.empty()) {
- computeSolution(stack.back());
- stack.pop_back();
- }
- }
+ void computeSolution(Graph::NodeItr nItr) {
- void computeSolution(const GraphNodeIterator &nodeItr) {
+ NodeData &nodeData = getSolverNodeData(nItr);
- NodeData &nodeData = g.getNodeData(nodeItr);
+ Vector v(g.getNodeCosts(nItr));
- Vector v(g.getNodeCosts(nodeItr));
+ // Solve based on existing solved edges.
+ for (SolverEdgeItr solvedEdgeItr = nodeData.solverEdgesBegin(),
+ solvedEdgeEnd = nodeData.solverEdgesEnd();
+ solvedEdgeItr != solvedEdgeEnd; ++solvedEdgeItr) {
- // Solve based on existing links.
- for (typename NodeData::AdjLinkIterator
- solvedLinkItr = nodeData.solvedLinksBegin(),
- solvedLinkEnd = nodeData.solvedLinksEnd();
- solvedLinkItr != solvedLinkEnd; ++solvedLinkItr) {
+ Graph::EdgeItr eItr(*solvedEdgeItr);
+ Matrix &edgeCosts = g.getEdgeCosts(eItr);
- GraphEdgeIterator solvedEdgeItr(*solvedLinkItr);
- Matrix &edgeCosts = g.getEdgeCosts(solvedEdgeItr);
+ if (nItr == g.getEdgeNode1(eItr)) {
+ Graph::NodeItr adjNode(g.getEdgeNode2(eItr));
+ unsigned adjSolution = s.getSelection(adjNode);
+ v += edgeCosts.getColAsVector(adjSolution);
+ }
+ else {
+ Graph::NodeItr adjNode(g.getEdgeNode1(eItr));
+ unsigned adjSolution = s.getSelection(adjNode);
+ v += edgeCosts.getRowAsVector(adjSolution);
+ }
- if (nodeItr == g.getEdgeNode1Itr(solvedEdgeItr)) {
- GraphNodeIterator adjNode(g.getEdgeNode2Itr(solvedEdgeItr));
- unsigned adjSolution =
- solution.getSelection(g.getNodeID(adjNode));
- v += edgeCosts.getColAsVector(adjSolution);
- }
- else {
- GraphNodeIterator adjNode(g.getEdgeNode1Itr(solvedEdgeItr));
- unsigned adjSolution =
- solution.getSelection(g.getNodeID(adjNode));
- v += edgeCosts.getRowAsVector(adjSolution);
}
+ setSolution(nItr, v.minIndex());
}
- setSolution(nodeItr, v.minIndex());
- }
-
- void computeSolutionCost(const SimpleGraph &orig) {
- PBQPNum cost = 0.0;
-
- for (SimpleGraph::ConstNodeIterator
- nodeItr = orig.nodesBegin(), nodeEnd = orig.nodesEnd();
- nodeItr != nodeEnd; ++nodeItr) {
-
- unsigned nodeId = orig.getNodeID(nodeItr);
-
- cost += orig.getNodeCosts(nodeItr)[solution.getSelection(nodeId)];
+ void cleanup() {
+ h.cleanup();
+ nodeDataList.clear();
+ edgeDataList.clear();
}
+ };
- for (SimpleGraph::ConstEdgeIterator
- edgeItr = orig.edgesBegin(), edgeEnd = orig.edgesEnd();
- edgeItr != edgeEnd; ++edgeItr) {
-
- SimpleGraph::ConstNodeIterator n1 = orig.getEdgeNode1Itr(edgeItr),
- n2 = orig.getEdgeNode2Itr(edgeItr);
- unsigned sol1 = solution.getSelection(orig.getNodeID(n1)),
- sol2 = solution.getSelection(orig.getNodeID(n2));
-
- cost += orig.getEdgeCosts(edgeItr)[sol1][sol2];
+ /// \brief PBQP heuristic solver class.
+ ///
+ /// Given a PBQP Graph g representing a PBQP problem, you can find a solution
+ /// by calling
+ /// <tt>Solution s = HeuristicSolver<H>::solve(g);</tt>
+ ///
+ /// The choice of heuristic for the H parameter will affect both the solver
+ /// speed and solution quality. The heuristic should be chosen based on the
+ /// nature of the problem being solved.
+ /// Currently the only solver included with LLVM is the Briggs heuristic for
+ /// register allocation.
+ template <typename HImpl>
+ class HeuristicSolver {
+ public:
+ static Solution solve(Graph &g) {
+ HeuristicSolverImpl<HImpl> hs(g);
+ return hs.computeSolution();
}
-
- solution.setSolutionCost(cost);
- }
-
-};
-
-template <typename Heuristic>
-class HeuristicSolver : public Solver {
-public:
- Solution solve(const SimpleGraph &g) const {
- HeuristicSolverImpl<Heuristic> solverImpl(g);
- return solverImpl.getSolution();
- }
-};
+ };
}
diff --git a/lib/CodeGen/PBQP/Heuristics/Briggs.h b/lib/CodeGen/PBQP/Heuristics/Briggs.h
index 1228f65..30d34d9 100644
--- a/lib/CodeGen/PBQP/Heuristics/Briggs.h
+++ b/lib/CodeGen/PBQP/Heuristics/Briggs.h
@@ -18,365 +18,447 @@
#ifndef LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H
#define LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H
+#include "llvm/Support/Compiler.h"
#include "../HeuristicSolver.h"
+#include "../HeuristicBase.h"
#include <set>
+#include <limits>
namespace PBQP {
-namespace Heuristics {
-
-class Briggs {
- public:
-
- class NodeData;
- class EdgeData;
-
- private:
-
- typedef HeuristicSolverImpl<Briggs> Solver;
- typedef HSITypes<NodeData, EdgeData> HSIT;
- typedef HSIT::SolverGraph SolverGraph;
- typedef HSIT::GraphNodeIterator GraphNodeIterator;
- typedef HSIT::GraphEdgeIterator GraphEdgeIterator;
-
- class LinkDegreeComparator {
+ namespace Heuristics {
+
+ /// \brief PBQP Heuristic which applies an allocability test based on
+ /// Briggs.
+ ///
+ /// This heuristic assumes that the elements of cost vectors in the PBQP
+ /// problem represent storage options, with the first being the spill
+ /// option and subsequent elements representing legal registers for the
+ /// corresponding node. Edge cost matrices are likewise assumed to represent
+ /// register constraints.
+ /// If one or more nodes can be proven allocable by this heuristic (by
+ /// inspection of their constraint matrices) then the allocable node of
+ /// highest degree is selected for the next reduction and pushed to the
+ /// solver stack. If no nodes can be proven allocable then the node with
+ /// the lowest estimated spill cost is selected and push to the solver stack
+ /// instead.
+ ///
+ /// This implementation is built on top of HeuristicBase.
+ class Briggs : public HeuristicBase<Briggs> {
+ private:
+
+ class LinkDegreeComparator {
public:
- LinkDegreeComparator() : g(0) {}
- LinkDegreeComparator(SolverGraph *g) : g(g) {}
-
- bool operator()(const GraphNodeIterator &node1Itr,
- const GraphNodeIterator &node2Itr) const {
- assert((g != 0) && "Graph object not set, cannot access node data.");
- unsigned n1Degree = g->getNodeData(node1Itr).getLinkDegree(),
- n2Degree = g->getNodeData(node2Itr).getLinkDegree();
- if (n1Degree > n2Degree) {
+ LinkDegreeComparator(HeuristicSolverImpl<Briggs> &s) : s(&s) {}
+ bool operator()(Graph::NodeItr n1Itr, Graph::NodeItr n2Itr) const {
+ if (s->getSolverDegree(n1Itr) > s->getSolverDegree(n2Itr))
return true;
- }
- else if (n1Degree < n2Degree) {
+ if (s->getSolverDegree(n1Itr) < s->getSolverDegree(n2Itr))
return false;
- }
- // else they're "equal" by degree, differentiate based on ID.
- return g->getNodeID(node1Itr) < g->getNodeID(node2Itr);
+ return (&*n1Itr < &*n2Itr);
}
-
private:
- SolverGraph *g;
- };
+ HeuristicSolverImpl<Briggs> *s;
+ };
- class SpillPriorityComparator {
+ class SpillCostComparator {
public:
- SpillPriorityComparator() : g(0) {}
- SpillPriorityComparator(SolverGraph *g) : g(g) {}
-
- bool operator()(const GraphNodeIterator &node1Itr,
- const GraphNodeIterator &node2Itr) const {
- assert((g != 0) && "Graph object not set, cannot access node data.");
- PBQPNum cost1 =
- g->getNodeCosts(node1Itr)[0] /
- g->getNodeData(node1Itr).getLinkDegree(),
- cost2 =
- g->getNodeCosts(node2Itr)[0] /
- g->getNodeData(node2Itr).getLinkDegree();
-
- if (cost1 < cost2) {
+ SpillCostComparator(HeuristicSolverImpl<Briggs> &s)
+ : s(&s), g(&s.getGraph()) {}
+ bool operator()(Graph::NodeItr n1Itr, Graph::NodeItr n2Itr) const {
+ PBQPNum cost1 = g->getNodeCosts(n1Itr)[0] / s->getSolverDegree(n1Itr),
+ cost2 = g->getNodeCosts(n2Itr)[0] / s->getSolverDegree(n2Itr);
+ if (cost1 < cost2)
return true;
- }
- else if (cost1 > cost2) {
+ if (cost1 > cost2)
return false;
- }
- // else they'er "equal" again, differentiate based on address again.
- return g->getNodeID(node1Itr) < g->getNodeID(node2Itr);
+ return (&*n1Itr < &*n2Itr);
}
private:
- SolverGraph *g;
- };
-
- typedef std::set<GraphNodeIterator, LinkDegreeComparator>
- RNAllocableNodeList;
- typedef RNAllocableNodeList::iterator RNAllocableNodeListIterator;
-
- typedef std::set<GraphNodeIterator, SpillPriorityComparator>
- RNUnallocableNodeList;
- typedef RNUnallocableNodeList::iterator RNUnallocableNodeListIterator;
-
- public:
-
- class NodeData {
- private:
- RNAllocableNodeListIterator rNAllocableNodeListItr;
- RNUnallocableNodeListIterator rNUnallocableNodeListItr;
- unsigned numRegOptions, numDenied, numSafe;
- std::vector<unsigned> unsafeDegrees;
- bool allocable;
-
- void addRemoveLink(SolverGraph &g, const GraphNodeIterator &nodeItr,
- const GraphEdgeIterator &edgeItr, bool add) {
+ HeuristicSolverImpl<Briggs> *s;
+ Graph *g;
+ };
- //assume we're adding...
- unsigned udTarget = 0, dir = 1;
+ typedef std::list<Graph::NodeItr> RNAllocableList;
+ typedef RNAllocableList::iterator RNAllocableListItr;
- if (!add) {
- udTarget = 1;
- dir = ~0;
- }
+ typedef std::list<Graph::NodeItr> RNUnallocableList;
+ typedef RNUnallocableList::iterator RNUnallocableListItr;
- EdgeData &linkEdgeData = g.getEdgeData(edgeItr).getHeuristicData();
+ public:
- EdgeData::ConstUnsafeIterator edgeUnsafeBegin, edgeUnsafeEnd;
+ struct NodeData {
+ typedef std::vector<unsigned> UnsafeDegreesArray;
+ bool isHeuristic, isAllocable, isInitialized;
+ unsigned numDenied, numSafe;
+ UnsafeDegreesArray unsafeDegrees;
+ RNAllocableListItr rnaItr;
+ RNUnallocableListItr rnuItr;
- if (nodeItr == g.getEdgeNode1Itr(edgeItr)) {
- numDenied += (dir * linkEdgeData.getWorstDegree());
- edgeUnsafeBegin = linkEdgeData.unsafeBegin();
- edgeUnsafeEnd = linkEdgeData.unsafeEnd();
- }
- else {
- numDenied += (dir * linkEdgeData.getReverseWorstDegree());
- edgeUnsafeBegin = linkEdgeData.reverseUnsafeBegin();
- edgeUnsafeEnd = linkEdgeData.reverseUnsafeEnd();
- }
+ NodeData()
+ : isHeuristic(false), isAllocable(false), isInitialized(false),
+ numDenied(0), numSafe(0) { }
+ };
- assert((unsafeDegrees.size() ==
- static_cast<unsigned>(
- std::distance(edgeUnsafeBegin, edgeUnsafeEnd)))
- && "Unsafe array size mismatch.");
-
- std::vector<unsigned>::iterator unsafeDegreesItr =
- unsafeDegrees.begin();
-
- for (EdgeData::ConstUnsafeIterator edgeUnsafeItr = edgeUnsafeBegin;
- edgeUnsafeItr != edgeUnsafeEnd;
- ++edgeUnsafeItr, ++unsafeDegreesItr) {
-
- if ((*edgeUnsafeItr == 1) && (*unsafeDegreesItr == udTarget)) {
- numSafe -= dir;
- }
- *unsafeDegreesItr += (dir * (*edgeUnsafeItr));
- }
-
- allocable = (numDenied < numRegOptions) || (numSafe > 0);
- }
-
- public:
-
- void setup(SolverGraph &g, const GraphNodeIterator &nodeItr) {
-
- numRegOptions = g.getNodeCosts(nodeItr).getLength() - 1;
-
- numSafe = numRegOptions; // Optimistic, correct below.
- numDenied = 0; // Also optimistic.
- unsafeDegrees.resize(numRegOptions, 0);
-
- HSIT::NodeData &nodeData = g.getNodeData(nodeItr);
-
- for (HSIT::NodeData::AdjLinkIterator
- adjLinkItr = nodeData.adjLinksBegin(),
- adjLinkEnd = nodeData.adjLinksEnd();
- adjLinkItr != adjLinkEnd; ++adjLinkItr) {
-
- addRemoveLink(g, nodeItr, *adjLinkItr, true);
- }
- }
-
- bool isAllocable() const { return allocable; }
-
- void handleAddLink(SolverGraph &g, const GraphNodeIterator &nodeItr,
- const GraphEdgeIterator &adjEdge) {
- addRemoveLink(g, nodeItr, adjEdge, true);
+ struct EdgeData {
+ typedef std::vector<unsigned> UnsafeArray;
+ unsigned worst, reverseWorst;
+ UnsafeArray unsafe, reverseUnsafe;
+ bool isUpToDate;
+
+ EdgeData() : worst(0), reverseWorst(0), isUpToDate(false) {}
+ };
+
+ /// \brief Construct an instance of the Briggs heuristic.
+ /// @param solver A reference to the solver which is using this heuristic.
+ Briggs(HeuristicSolverImpl<Briggs> &solver) :
+ HeuristicBase<Briggs>(solver) {}
+
+ /// \brief Determine whether a node should be reduced using optimal
+ /// reduction.
+ /// @param nItr Node iterator to be considered.
+ /// @return True if the given node should be optimally reduced, false
+ /// otherwise.
+ ///
+ /// Selects nodes of degree 0, 1 or 2 for optimal reduction, with one
+ /// exception. Nodes whose spill cost (element 0 of their cost vector) is
+ /// infinite are checked for allocability first. Allocable nodes may be
+ /// optimally reduced, but nodes whose allocability cannot be proven are
+ /// selected for heuristic reduction instead.
+ bool shouldOptimallyReduce(Graph::NodeItr nItr) {
+ if (getSolver().getSolverDegree(nItr) < 3) {
+ return true;
}
-
- void handleRemoveLink(SolverGraph &g, const GraphNodeIterator &nodeItr,
- const GraphEdgeIterator &adjEdge) {
- addRemoveLink(g, nodeItr, adjEdge, false);
+ // else
+ return false;
+ }
+
+ /// \brief Add a node to the heuristic reduce list.
+ /// @param nItr Node iterator to add to the heuristic reduce list.
+ void addToHeuristicReduceList(Graph::NodeItr nItr) {
+ NodeData &nd = getHeuristicNodeData(nItr);
+ initializeNode(nItr);
+ nd.isHeuristic = true;
+ if (nd.isAllocable) {
+ nd.rnaItr = rnAllocableList.insert(rnAllocableList.end(), nItr);
+ } else {
+ nd.rnuItr = rnUnallocableList.insert(rnUnallocableList.end(), nItr);
}
-
- void setRNAllocableNodeListItr(
- const RNAllocableNodeListIterator &rNAllocableNodeListItr) {
-
- this->rNAllocableNodeListItr = rNAllocableNodeListItr;
+ }
+
+ /// \brief Heuristically reduce one of the nodes in the heuristic
+ /// reduce list.
+ /// @return True if a reduction takes place, false if the heuristic reduce
+ /// list is empty.
+ ///
+ /// If the list of allocable nodes is non-empty a node is selected
+ /// from it and pushed to the stack. Otherwise if the non-allocable list
+ /// is non-empty a node is selected from it and pushed to the stack.
+ /// If both lists are empty the method simply returns false with no action
+ /// taken.
+ bool heuristicReduce() {
+ if (!rnAllocableList.empty()) {
+ RNAllocableListItr rnaItr =
+ min_element(rnAllocableList.begin(), rnAllocableList.end(),
+ LinkDegreeComparator(getSolver()));
+ Graph::NodeItr nItr = *rnaItr;
+ rnAllocableList.erase(rnaItr);
+ handleRemoveNode(nItr);
+ getSolver().pushToStack(nItr);
+ return true;
+ } else if (!rnUnallocableList.empty()) {
+ RNUnallocableListItr rnuItr =
+ min_element(rnUnallocableList.begin(), rnUnallocableList.end(),
+ SpillCostComparator(getSolver()));
+ Graph::NodeItr nItr = *rnuItr;
+ rnUnallocableList.erase(rnuItr);
+ handleRemoveNode(nItr);
+ getSolver().pushToStack(nItr);
+ return true;
}
-
- RNAllocableNodeListIterator getRNAllocableNodeListItr() const {
- return rNAllocableNodeListItr;
+ // else
+ return false;
+ }
+
+ /// \brief Prepare a change in the costs on the given edge.
+ /// @param eItr Edge iterator.
+ void preUpdateEdgeCosts(Graph::EdgeItr eItr) {
+ Graph &g = getGraph();
+ Graph::NodeItr n1Itr = g.getEdgeNode1(eItr),
+ n2Itr = g.getEdgeNode2(eItr);
+ NodeData &n1 = getHeuristicNodeData(n1Itr),
+ &n2 = getHeuristicNodeData(n2Itr);
+
+ if (n1.isHeuristic)
+ subtractEdgeContributions(eItr, getGraph().getEdgeNode1(eItr));
+ if (n2.isHeuristic)
+ subtractEdgeContributions(eItr, getGraph().getEdgeNode2(eItr));
+
+ EdgeData &ed = getHeuristicEdgeData(eItr);
+ ed.isUpToDate = false;
+ }
+
+ /// \brief Handle the change in the costs on the given edge.
+ /// @param eItr Edge iterator.
+ void postUpdateEdgeCosts(Graph::EdgeItr eItr) {
+ // This is effectively the same as adding a new edge now, since
+ // we've factored out the costs of the old one.
+ handleAddEdge(eItr);
+ }
+
+ /// \brief Handle the addition of a new edge into the PBQP graph.
+ /// @param eItr Edge iterator for the added edge.
+ ///
+ /// Updates allocability of any nodes connected by this edge which are
+ /// being managed by the heuristic. If allocability changes they are
+ /// moved to the appropriate list.
+ void handleAddEdge(Graph::EdgeItr eItr) {
+ Graph &g = getGraph();
+ Graph::NodeItr n1Itr = g.getEdgeNode1(eItr),
+ n2Itr = g.getEdgeNode2(eItr);
+ NodeData &n1 = getHeuristicNodeData(n1Itr),
+ &n2 = getHeuristicNodeData(n2Itr);
+
+ // If neither node is managed by the heuristic there's nothing to be
+ // done.
+ if (!n1.isHeuristic && !n2.isHeuristic)
+ return;
+
+ // Ok - we need to update at least one node.
+ computeEdgeContributions(eItr);
+
+ // Update node 1 if it's managed by the heuristic.
+ if (n1.isHeuristic) {
+ bool n1WasAllocable = n1.isAllocable;
+ addEdgeContributions(eItr, n1Itr);
+ updateAllocability(n1Itr);
+ if (n1WasAllocable && !n1.isAllocable) {
+ rnAllocableList.erase(n1.rnaItr);
+ n1.rnuItr =
+ rnUnallocableList.insert(rnUnallocableList.end(), n1Itr);
+ }
}
- void setRNUnallocableNodeListItr(
- const RNUnallocableNodeListIterator &rNUnallocableNodeListItr) {
-
- this->rNUnallocableNodeListItr = rNUnallocableNodeListItr;
+ // Likewise for node 2.
+ if (n2.isHeuristic) {
+ bool n2WasAllocable = n2.isAllocable;
+ addEdgeContributions(eItr, n2Itr);
+ updateAllocability(n2Itr);
+ if (n2WasAllocable && !n2.isAllocable) {
+ rnAllocableList.erase(n2.rnaItr);
+ n2.rnuItr =
+ rnUnallocableList.insert(rnUnallocableList.end(), n2Itr);
+ }
}
-
- RNUnallocableNodeListIterator getRNUnallocableNodeListItr() const {
- return rNUnallocableNodeListItr;
+ }
+
+ /// \brief Handle disconnection of an edge from a node.
+ /// @param eItr Edge iterator for edge being disconnected.
+ /// @param nItr Node iterator for the node being disconnected from.
+ ///
+ /// Updates allocability of the given node and, if appropriate, moves the
+ /// node to a new list.
+ void handleRemoveEdge(Graph::EdgeItr eItr, Graph::NodeItr nItr) {
+ NodeData &nd = getHeuristicNodeData(nItr);
+
+ // If the node is not managed by the heuristic there's nothing to be
+ // done.
+ if (!nd.isHeuristic)
+ return;
+
+ EdgeData &ed ATTRIBUTE_UNUSED = getHeuristicEdgeData(eItr);
+
+ assert(ed.isUpToDate && "Edge data is not up to date.");
+
+ // Update node.
+ bool ndWasAllocable = nd.isAllocable;
+ subtractEdgeContributions(eItr, nItr);
+ updateAllocability(nItr);
+
+ // If the node has gone optimal...
+ if (shouldOptimallyReduce(nItr)) {
+ nd.isHeuristic = false;
+ addToOptimalReduceList(nItr);
+ if (ndWasAllocable) {
+ rnAllocableList.erase(nd.rnaItr);
+ } else {
+ rnUnallocableList.erase(nd.rnuItr);
+ }
+ } else {
+ // Node didn't go optimal, but we might have to move it
+ // from "unallocable" to "allocable".
+ if (!ndWasAllocable && nd.isAllocable) {
+ rnUnallocableList.erase(nd.rnuItr);
+ nd.rnaItr = rnAllocableList.insert(rnAllocableList.end(), nItr);
+ }
}
+ }
+ private:
- };
+ NodeData& getHeuristicNodeData(Graph::NodeItr nItr) {
+ return getSolver().getHeuristicNodeData(nItr);
+ }
- class EdgeData {
- private:
+ EdgeData& getHeuristicEdgeData(Graph::EdgeItr eItr) {
+ return getSolver().getHeuristicEdgeData(eItr);
+ }
- typedef std::vector<unsigned> UnsafeArray;
+ // Work out what this edge will contribute to the allocability of the
+ // nodes connected to it.
+ void computeEdgeContributions(Graph::EdgeItr eItr) {
+ EdgeData &ed = getHeuristicEdgeData(eItr);
- unsigned worstDegree,
- reverseWorstDegree;
- UnsafeArray unsafe, reverseUnsafe;
+ if (ed.isUpToDate)
+ return; // Edge data is already up to date.
- public:
+ Matrix &eCosts = getGraph().getEdgeCosts(eItr);
- EdgeData() : worstDegree(0), reverseWorstDegree(0) {}
+ unsigned numRegs = eCosts.getRows() - 1,
+ numReverseRegs = eCosts.getCols() - 1;
- typedef UnsafeArray::const_iterator ConstUnsafeIterator;
+ std::vector<unsigned> rowInfCounts(numRegs, 0),
+ colInfCounts(numReverseRegs, 0);
- void setup(SolverGraph &g, const GraphEdgeIterator &edgeItr) {
- const Matrix &edgeCosts = g.getEdgeCosts(edgeItr);
- unsigned numRegs = edgeCosts.getRows() - 1,
- numReverseRegs = edgeCosts.getCols() - 1;
+ ed.worst = 0;
+ ed.reverseWorst = 0;
+ ed.unsafe.clear();
+ ed.unsafe.resize(numRegs, 0);
+ ed.reverseUnsafe.clear();
+ ed.reverseUnsafe.resize(numReverseRegs, 0);
- unsafe.resize(numRegs, 0);
- reverseUnsafe.resize(numReverseRegs, 0);
+ for (unsigned i = 0; i < numRegs; ++i) {
+ for (unsigned j = 0; j < numReverseRegs; ++j) {
+ if (eCosts[i + 1][j + 1] ==
+ std::numeric_limits<PBQPNum>::infinity()) {
+ ed.unsafe[i] = 1;
+ ed.reverseUnsafe[j] = 1;
+ ++rowInfCounts[i];
+ ++colInfCounts[j];
- std::vector<unsigned> rowInfCounts(numRegs, 0),
- colInfCounts(numReverseRegs, 0);
+ if (colInfCounts[j] > ed.worst) {
+ ed.worst = colInfCounts[j];
+ }
- for (unsigned i = 0; i < numRegs; ++i) {
- for (unsigned j = 0; j < numReverseRegs; ++j) {
- if (edgeCosts[i + 1][j + 1] ==
- std::numeric_limits<PBQPNum>::infinity()) {
- unsafe[i] = 1;
- reverseUnsafe[j] = 1;
- ++rowInfCounts[i];
- ++colInfCounts[j];
-
- if (colInfCounts[j] > worstDegree) {
- worstDegree = colInfCounts[j];
- }
-
- if (rowInfCounts[i] > reverseWorstDegree) {
- reverseWorstDegree = rowInfCounts[i];
- }
+ if (rowInfCounts[i] > ed.reverseWorst) {
+ ed.reverseWorst = rowInfCounts[i];
}
}
}
}
- unsigned getWorstDegree() const { return worstDegree; }
- unsigned getReverseWorstDegree() const { return reverseWorstDegree; }
- ConstUnsafeIterator unsafeBegin() const { return unsafe.begin(); }
- ConstUnsafeIterator unsafeEnd() const { return unsafe.end(); }
- ConstUnsafeIterator reverseUnsafeBegin() const {
- return reverseUnsafe.begin();
+ ed.isUpToDate = true;
+ }
+
+ // Add the contributions of the given edge to the given node's
+ // numDenied and safe members. No action is taken other than to update
+ // these member values. Once updated these numbers can be used by clients
+ // to update the node's allocability.
+ void addEdgeContributions(Graph::EdgeItr eItr, Graph::NodeItr nItr) {
+ EdgeData &ed = getHeuristicEdgeData(eItr);
+
+ assert(ed.isUpToDate && "Using out-of-date edge numbers.");
+
+ NodeData &nd = getHeuristicNodeData(nItr);
+ unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1;
+
+ bool nIsNode1 = nItr == getGraph().getEdgeNode1(eItr);
+ EdgeData::UnsafeArray &unsafe =
+ nIsNode1 ? ed.unsafe : ed.reverseUnsafe;
+ nd.numDenied += nIsNode1 ? ed.worst : ed.reverseWorst;
+
+ for (unsigned r = 0; r < numRegs; ++r) {
+ if (unsafe[r]) {
+ if (nd.unsafeDegrees[r]==0) {
+ --nd.numSafe;
+ }
+ ++nd.unsafeDegrees[r];
+ }
}
- ConstUnsafeIterator reverseUnsafeEnd() const {
- return reverseUnsafe.end();
+ }
+
+ // Subtract the contributions of the given edge to the given node's
+ // numDenied and safe members. No action is taken other than to update
+ // these member values. Once updated these numbers can be used by clients
+ // to update the node's allocability.
+ void subtractEdgeContributions(Graph::EdgeItr eItr, Graph::NodeItr nItr) {
+ EdgeData &ed = getHeuristicEdgeData(eItr);
+
+ assert(ed.isUpToDate && "Using out-of-date edge numbers.");
+
+ NodeData &nd = getHeuristicNodeData(nItr);
+ unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1;
+
+ bool nIsNode1 = nItr == getGraph().getEdgeNode1(eItr);
+ EdgeData::UnsafeArray &unsafe =
+ nIsNode1 ? ed.unsafe : ed.reverseUnsafe;
+ nd.numDenied -= nIsNode1 ? ed.worst : ed.reverseWorst;
+
+ for (unsigned r = 0; r < numRegs; ++r) {
+ if (unsafe[r]) {
+ if (nd.unsafeDegrees[r] == 1) {
+ ++nd.numSafe;
+ }
+ --nd.unsafeDegrees[r];
+ }
}
- };
-
- void initialise(Solver &solver) {
- this->s = &solver;
- g = &s->getGraph();
- rNAllocableBucket = RNAllocableNodeList(LinkDegreeComparator(g));
- rNUnallocableBucket =
- RNUnallocableNodeList(SpillPriorityComparator(g));
-
- for (GraphEdgeIterator
- edgeItr = g->edgesBegin(), edgeEnd = g->edgesEnd();
- edgeItr != edgeEnd; ++edgeItr) {
-
- g->getEdgeData(edgeItr).getHeuristicData().setup(*g, edgeItr);
- }
-
- for (GraphNodeIterator
- nodeItr = g->nodesBegin(), nodeEnd = g->nodesEnd();
- nodeItr != nodeEnd; ++nodeItr) {
-
- g->getNodeData(nodeItr).getHeuristicData().setup(*g, nodeItr);
- }
- }
-
- void addToRNBucket(const GraphNodeIterator &nodeItr) {
- NodeData &nodeData = g->getNodeData(nodeItr).getHeuristicData();
-
- if (nodeData.isAllocable()) {
- nodeData.setRNAllocableNodeListItr(
- rNAllocableBucket.insert(rNAllocableBucket.begin(), nodeItr));
- }
- else {
- nodeData.setRNUnallocableNodeListItr(
- rNUnallocableBucket.insert(rNUnallocableBucket.begin(), nodeItr));
- }
- }
+ }
- void removeFromRNBucket(const GraphNodeIterator &nodeItr) {
- NodeData &nodeData = g->getNodeData(nodeItr).getHeuristicData();
-
- if (nodeData.isAllocable()) {
- rNAllocableBucket.erase(nodeData.getRNAllocableNodeListItr());
- }
- else {
- rNUnallocableBucket.erase(nodeData.getRNUnallocableNodeListItr());
- }
- }
+ void updateAllocability(Graph::NodeItr nItr) {
+ NodeData &nd = getHeuristicNodeData(nItr);
+ unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1;
+ nd.isAllocable = nd.numDenied < numRegs || nd.numSafe > 0;
+ }
- void handleAddLink(const GraphEdgeIterator &edgeItr) {
- // We assume that if we got here this edge is attached to at least
- // one high degree node.
- g->getEdgeData(edgeItr).getHeuristicData().setup(*g, edgeItr);
-
- GraphNodeIterator n1Itr = g->getEdgeNode1Itr(edgeItr),
- n2Itr = g->getEdgeNode2Itr(edgeItr);
-
- HSIT::NodeData &n1Data = g->getNodeData(n1Itr),
- &n2Data = g->getNodeData(n2Itr);
-
- if (n1Data.getLinkDegree() > 2) {
- n1Data.getHeuristicData().handleAddLink(*g, n1Itr, edgeItr);
- }
- if (n2Data.getLinkDegree() > 2) {
- n2Data.getHeuristicData().handleAddLink(*g, n2Itr, edgeItr);
- }
- }
+ void initializeNode(Graph::NodeItr nItr) {
+ NodeData &nd = getHeuristicNodeData(nItr);
- void handleRemoveLink(const GraphEdgeIterator &edgeItr,
- const GraphNodeIterator &nodeItr) {
- NodeData &nodeData = g->getNodeData(nodeItr).getHeuristicData();
- nodeData.handleRemoveLink(*g, nodeItr, edgeItr);
- }
+ if (nd.isInitialized)
+ return; // Node data is already up to date.
- void processRN() {
-
- if (!rNAllocableBucket.empty()) {
- GraphNodeIterator selectedNodeItr = *rNAllocableBucket.begin();
- //std::cerr << "RN safely pushing " << g->getNodeID(selectedNodeItr) << "\n";
- rNAllocableBucket.erase(rNAllocableBucket.begin());
- s->pushStack(selectedNodeItr);
- s->unlinkNode(selectedNodeItr);
- }
- else {
- GraphNodeIterator selectedNodeItr = *rNUnallocableBucket.begin();
- //std::cerr << "RN optimistically pushing " << g->getNodeID(selectedNodeItr) << "\n";
- rNUnallocableBucket.erase(rNUnallocableBucket.begin());
- s->pushStack(selectedNodeItr);
- s->unlinkNode(selectedNodeItr);
- }
-
- }
+ unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1;
- bool rNBucketEmpty() const {
- return (rNAllocableBucket.empty() && rNUnallocableBucket.empty());
- }
+ nd.numDenied = 0;
+ nd.numSafe = numRegs;
+ nd.unsafeDegrees.resize(numRegs, 0);
-private:
+ typedef HeuristicSolverImpl<Briggs>::SolverEdgeItr SolverEdgeItr;
- Solver *s;
- SolverGraph *g;
- RNAllocableNodeList rNAllocableBucket;
- RNUnallocableNodeList rNUnallocableBucket;
-};
+ for (SolverEdgeItr aeItr = getSolver().solverEdgesBegin(nItr),
+ aeEnd = getSolver().solverEdgesEnd(nItr);
+ aeItr != aeEnd; ++aeItr) {
+
+ Graph::EdgeItr eItr = *aeItr;
+ computeEdgeContributions(eItr);
+ addEdgeContributions(eItr, nItr);
+ }
+ updateAllocability(nItr);
+ nd.isInitialized = true;
+ }
+
+ void handleRemoveNode(Graph::NodeItr xnItr) {
+ typedef HeuristicSolverImpl<Briggs>::SolverEdgeItr SolverEdgeItr;
+ std::vector<Graph::EdgeItr> edgesToRemove;
+ for (SolverEdgeItr aeItr = getSolver().solverEdgesBegin(xnItr),
+ aeEnd = getSolver().solverEdgesEnd(xnItr);
+ aeItr != aeEnd; ++aeItr) {
+ Graph::NodeItr ynItr = getGraph().getEdgeOtherNode(*aeItr, xnItr);
+ handleRemoveEdge(*aeItr, ynItr);
+ edgesToRemove.push_back(*aeItr);
+ }
+ while (!edgesToRemove.empty()) {
+ getSolver().removeSolverEdge(edgesToRemove.back());
+ edgesToRemove.pop_back();
+ }
+ }
+ RNAllocableList rnAllocableList;
+ RNUnallocableList rnUnallocableList;
+ };
-}
+ }
}
diff --git a/lib/CodeGen/PBQP/PBQPMath.h b/lib/CodeGen/PBQP/Math.h
index 20737a2..e7598bf 100644
--- a/lib/CodeGen/PBQP/PBQPMath.h
+++ b/lib/CodeGen/PBQP/Math.h
@@ -1,4 +1,4 @@
-//===-- PBQPMath.h - PBQP Vector and Matrix classes -------------*- C++ -*-===//
+//===------ Math.h - PBQP Vector and Matrix classes -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_PBQP_PBQPMATH_H
-#define LLVM_CODEGEN_PBQP_PBQPMATH_H
+#ifndef LLVM_CODEGEN_PBQP_MATH_H
+#define LLVM_CODEGEN_PBQP_MATH_H
#include <cassert>
#include <algorithm>
@@ -16,7 +16,7 @@
namespace PBQP {
-typedef double PBQPNum;
+typedef float PBQPNum;
/// \brief PBQP Vector class.
class Vector {
@@ -285,4 +285,4 @@ OStream& operator<<(OStream &os, const Matrix &m) {
}
-#endif // LLVM_CODEGEN_PBQP_PBQPMATH_HPP
+#endif // LLVM_CODEGEN_PBQP_MATH_H
diff --git a/lib/CodeGen/PBQP/SimpleGraph.h b/lib/CodeGen/PBQP/SimpleGraph.h
deleted file mode 100644
index 13e63ce..0000000
--- a/lib/CodeGen/PBQP/SimpleGraph.h
+++ /dev/null
@@ -1,100 +0,0 @@
-//===-- SimpleGraph.h - Simple PBQP Graph -----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Simple PBQP graph class representing a PBQP problem. Graphs of this type
-// can be passed to a PBQPSolver instance to solve the PBQP problem.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_PBQP_SIMPLEGRAPH_H
-#define LLVM_CODEGEN_PBQP_SIMPLEGRAPH_H
-
-#include "GraphBase.h"
-
-namespace PBQP {
-
-class SimpleEdge;
-
-class SimpleNode : public NodeBase<SimpleNode, SimpleEdge> {
-public:
- SimpleNode(const Vector &costs) :
- NodeBase<SimpleNode, SimpleEdge>(costs) {}
-};
-
-class SimpleEdge : public EdgeBase<SimpleNode, SimpleEdge> {
-public:
- SimpleEdge(const NodeIterator &node1Itr, const NodeIterator &node2Itr,
- const Matrix &costs) :
- EdgeBase<SimpleNode, SimpleEdge>(node1Itr, node2Itr, costs) {}
-};
-
-class SimpleGraph : public GraphBase<SimpleNode, SimpleEdge> {
-private:
-
- typedef GraphBase<SimpleNode, SimpleEdge> PGraph;
-
- void copyFrom(const SimpleGraph &other) {
- assert(other.areNodeIDsValid() &&
- "Cannot copy from another graph unless IDs have been assigned.");
-
- std::vector<NodeIterator> newNodeItrs(other.getNumNodes());
-
- for (ConstNodeIterator nItr = other.nodesBegin(), nEnd = other.nodesEnd();
- nItr != nEnd; ++nItr) {
- newNodeItrs[other.getNodeID(nItr)] = addNode(other.getNodeCosts(nItr));
- }
-
- for (ConstEdgeIterator eItr = other.edgesBegin(), eEnd = other.edgesEnd();
- eItr != eEnd; ++eItr) {
-
- unsigned node1ID = other.getNodeID(other.getEdgeNode1Itr(eItr)),
- node2ID = other.getNodeID(other.getEdgeNode2Itr(eItr));
-
- addEdge(newNodeItrs[node1ID], newNodeItrs[node2ID],
- other.getEdgeCosts(eItr));
- }
- }
-
- void copyFrom(SimpleGraph &other) {
- if (!other.areNodeIDsValid()) {
- other.assignNodeIDs();
- }
- copyFrom(const_cast<const SimpleGraph&>(other));
- }
-
-public:
-
- SimpleGraph() {}
-
-
- SimpleGraph(const SimpleGraph &other) : PGraph() {
- copyFrom(other);
- }
-
- SimpleGraph& operator=(const SimpleGraph &other) {
- clear();
- copyFrom(other);
- return *this;
- }
-
- NodeIterator addNode(const Vector &costs) {
- return PGraph::addConstructedNode(SimpleNode(costs));
- }
-
- EdgeIterator addEdge(const NodeIterator &node1Itr,
- const NodeIterator &node2Itr,
- const Matrix &costs) {
- return PGraph::addConstructedEdge(SimpleEdge(node1Itr, node2Itr, costs));
- }
-
-};
-
-}
-
-#endif // LLVM_CODEGEN_PBQP_SIMPLEGRAPH_H
diff --git a/lib/CodeGen/PBQP/Solution.h b/lib/CodeGen/PBQP/Solution.h
index aee684d..294b537 100644
--- a/lib/CodeGen/PBQP/Solution.h
+++ b/lib/CodeGen/PBQP/Solution.h
@@ -7,81 +7,51 @@
//
//===----------------------------------------------------------------------===//
//
-// Annotated PBQP Graph class. This class is used internally by the PBQP solver
-// to cache information to speed up reduction.
+// PBQP Solution class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_PBQP_SOLUTION_H
#define LLVM_CODEGEN_PBQP_SOLUTION_H
-#include "PBQPMath.h"
+#include "Math.h"
+#include "Graph.h"
-namespace PBQP {
-
-class Solution {
-
- friend class SolverImplementation;
-
-private:
-
- std::vector<unsigned> selections;
- PBQPNum solutionCost;
- bool provedOptimal;
- unsigned r0Reductions, r1Reductions,
- r2Reductions, rNReductions;
-
-public:
-
- Solution() :
- solutionCost(0.0), provedOptimal(false),
- r0Reductions(0), r1Reductions(0), r2Reductions(0), rNReductions(0) {}
-
- Solution(unsigned length, bool assumeOptimal) :
- selections(length), solutionCost(0.0), provedOptimal(assumeOptimal),
- r0Reductions(0), r1Reductions(0), r2Reductions(0), rNReductions(0) {}
-
- void setProvedOptimal(bool provedOptimal) {
- this->provedOptimal = provedOptimal;
- }
-
- void setSelection(unsigned nodeID, unsigned selection) {
- selections[nodeID] = selection;
- }
+#include <map>
- void setSolutionCost(PBQPNum solutionCost) {
- this->solutionCost = solutionCost;
- }
-
- void incR0Reductions() { ++r0Reductions; }
- void incR1Reductions() { ++r1Reductions; }
- void incR2Reductions() { ++r2Reductions; }
- void incRNReductions() { ++rNReductions; }
-
- unsigned numNodes() const { return selections.size(); }
-
- unsigned getSelection(unsigned nodeID) const {
- return selections[nodeID];
- }
-
- PBQPNum getCost() const { return solutionCost; }
-
- bool isProvedOptimal() const { return provedOptimal; }
-
- unsigned getR0Reductions() const { return r0Reductions; }
- unsigned getR1Reductions() const { return r1Reductions; }
- unsigned getR2Reductions() const { return r2Reductions; }
- unsigned getRNReductions() const { return rNReductions; }
-
- bool operator==(const Solution &other) const {
- return (selections == other.selections);
- }
-
- bool operator!=(const Solution &other) const {
- return !(*this == other);
- }
+namespace PBQP {
-};
+ /// \brief Represents a solution to a PBQP problem.
+ ///
+ /// To get the selection for each node in the problem use the getSelection method.
+ class Solution {
+ private:
+ typedef std::map<Graph::NodeItr, unsigned, NodeItrComparator> SelectionsMap;
+ SelectionsMap selections;
+
+ public:
+
+ /// \brief Number of nodes for which selections have been made.
+ /// @return Number of nodes for which selections have been made.
+ unsigned numNodes() const { return selections.size(); }
+
+ /// \brief Set the selection for a given node.
+ /// @param nItr Node iterator.
+ /// @param selection Selection for nItr.
+ void setSelection(Graph::NodeItr nItr, unsigned selection) {
+ selections[nItr] = selection;
+ }
+
+ /// \brief Get a node's selection.
+ /// @param nItr Node iterator.
+ /// @return The selection for nItr;
+ unsigned getSelection(Graph::NodeItr nItr) const {
+ SelectionsMap::const_iterator sItr = selections.find(nItr);
+ assert(sItr != selections.end() && "No selection for node.");
+ return sItr->second;
+ }
+
+ };
}
diff --git a/lib/CodeGen/PBQP/Solver.h b/lib/CodeGen/PBQP/Solver.h
deleted file mode 100644
index a445de8..0000000
--- a/lib/CodeGen/PBQP/Solver.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//===-- Solver.h ------- PBQP solver interface ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CODEGEN_PBQP_SOLVER_H
-#define LLVM_CODEGEN_PBQP_SOLVER_H
-
-#include "SimpleGraph.h"
-#include "Solution.h"
-
-namespace PBQP {
-
-/// \brief Interface for solver classes.
-class Solver {
-public:
-
- virtual ~Solver() = 0;
- virtual Solution solve(const SimpleGraph &orig) const = 0;
-};
-
-Solver::~Solver() {}
-
-}
-
-#endif // LLVM_CODEGEN_PBQP_SOLVER_H
diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp
index 365df30..b740c68 100644
--- a/lib/CodeGen/PHIElimination.cpp
+++ b/lib/CodeGen/PHIElimination.cpp
@@ -21,6 +21,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Function.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -95,14 +96,14 @@ bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &Fn) {
///
bool llvm::PHIElimination::EliminatePHINodes(MachineFunction &MF,
MachineBasicBlock &MBB) {
- if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI)
+ if (MBB.empty() || !MBB.front().isPHI())
return false; // Quick exit for basic blocks without PHIs.
// Get an iterator to the first instruction after the last PHI node (this may
// also be the end of the basic block).
MachineBasicBlock::iterator AfterPHIsIt = SkipPHIsAndLabels(MBB, MBB.begin());
- while (MBB.front().getOpcode() == TargetInstrInfo::PHI)
+ while (MBB.front().isPHI())
LowerAtomicPHINode(MBB, AfterPHIsIt);
return true;
@@ -115,7 +116,7 @@ static bool isSourceDefinedByImplicitDef(const MachineInstr *MPhi,
for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2) {
unsigned SrcReg = MPhi->getOperand(i).getReg();
const MachineInstr *DefMI = MRI->getVRegDef(SrcReg);
- if (!DefMI || DefMI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF)
+ if (!DefMI || !DefMI->isImplicitDef())
return false;
}
return true;
@@ -197,7 +198,7 @@ void llvm::PHIElimination::LowerAtomicPHINode(
// If all sources of a PHI node are implicit_def, just emit an
// implicit_def instead of a copy.
BuildMI(MBB, AfterPHIsIt, MPhi->getDebugLoc(),
- TII->get(TargetInstrInfo::IMPLICIT_DEF), DestReg);
+ TII->get(TargetOpcode::IMPLICIT_DEF), DestReg);
else {
// Can we reuse an earlier PHI node? This only happens for critical edges,
// typically those created by tail duplication.
@@ -281,7 +282,7 @@ void llvm::PHIElimination::LowerAtomicPHINode(
// If source is defined by an implicit def, there is no need to insert a
// copy.
MachineInstr *DefMI = MRI->getVRegDef(SrcReg);
- if (DefMI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
+ if (DefMI->isImplicitDef()) {
ImpDefs.insert(DefMI);
continue;
}
@@ -375,7 +376,7 @@ void llvm::PHIElimination::analyzePHINodes(const MachineFunction& Fn) {
for (MachineFunction::const_iterator I = Fn.begin(), E = Fn.end();
I != E; ++I)
for (MachineBasicBlock::const_iterator BBI = I->begin(), BBE = I->end();
- BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI)
+ BBI != BBE && BBI->isPHI(); ++BBI)
for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
++VRegPHIUseCount[BBVRegPair(BBI->getOperand(i+1).getMBB()->getNumber(),
BBI->getOperand(i).getReg())];
@@ -384,12 +385,11 @@ void llvm::PHIElimination::analyzePHINodes(const MachineFunction& Fn) {
bool llvm::PHIElimination::SplitPHIEdges(MachineFunction &MF,
MachineBasicBlock &MBB,
LiveVariables &LV) {
- if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI ||
- MBB.isLandingPad())
+ if (MBB.empty() || !MBB.front().isPHI() || MBB.isLandingPad())
return false; // Quick exit for basic blocks without PHIs.
for (MachineBasicBlock::const_iterator BBI = MBB.begin(), BBE = MBB.end();
- BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) {
+ BBI != BBE && BBI->isPHI(); ++BBI) {
for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) {
unsigned Reg = BBI->getOperand(i).getReg();
MachineBasicBlock *PreMBB = BBI->getOperand(i+1).getMBB();
@@ -438,7 +438,7 @@ MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
// Fix PHI nodes in B so they refer to NMBB instead of A
for (MachineBasicBlock::iterator i = B->begin(), e = B->end();
- i != e && i->getOpcode() == TargetInstrInfo::PHI; ++i)
+ i != e && i->isPHI(); ++i)
for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2)
if (i->getOperand(ni+1).getMBB() == A)
i->getOperand(ni+1).setMBB(NMBB);
diff --git a/lib/CodeGen/PHIElimination.h b/lib/CodeGen/PHIElimination.h
index 1bcc9dc..f3ab9e2 100644
--- a/lib/CodeGen/PHIElimination.h
+++ b/lib/CodeGen/PHIElimination.h
@@ -14,10 +14,11 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
namespace llvm {
-
+ class LiveVariables;
+
/// Lower PHI instructions to copies.
class PHIElimination : public MachineFunctionPass {
MachineRegisterInfo *MRI; // Machine register information
@@ -108,13 +109,29 @@ namespace llvm {
// SkipPHIsAndLabels - Copies need to be inserted after phi nodes and
// also after any exception handling labels: in landing pads execution
// starts at the label, so any copies placed before it won't be executed!
+ // We also deal with DBG_VALUEs, which are a bit tricky:
+ // PHI
+ // DBG_VALUE
+ // LABEL
+ // Here the DBG_VALUE needs to be skipped, and if it refers to a PHI it
+ // needs to be annulled or, better, moved to follow the label, as well.
+ // PHI
+ // DBG_VALUE
+ // no label
+ // Here it is not a good idea to skip the DBG_VALUE.
+ // FIXME: For now we skip and annul all DBG_VALUEs, maximally simple and
+ // maximally stupid.
MachineBasicBlock::iterator SkipPHIsAndLabels(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) {
// Rather than assuming that EH labels come before other kinds of labels,
// just skip all labels.
- while (I != MBB.end() &&
- (I->getOpcode() == TargetInstrInfo::PHI || I->isLabel()))
+ while (I != MBB.end() &&
+ (I->isPHI() || I->isLabel() || I->isDebugValue())) {
+ if (I->isDebugValue() && I->getNumOperands()==3 &&
+ I->getOperand(0).isReg())
+ I->getOperand(0).setReg(0U);
++I;
+ }
return I;
}
diff --git a/lib/CodeGen/PreAllocSplitting.cpp b/lib/CodeGen/PreAllocSplitting.cpp
index 8cbc8c2..70e91aa 100644
--- a/lib/CodeGen/PreAllocSplitting.cpp
+++ b/lib/CodeGen/PreAllocSplitting.cpp
@@ -686,8 +686,7 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) {
SlotIndex DefIdx = LIs->getInstructionIndex(&*DI);
DefIdx = DefIdx.getDefIndex();
- assert(DI->getOpcode() != TargetInstrInfo::PHI &&
- "PHI instr in code during pre-alloc splitting.");
+ assert(!DI->isPHI() && "PHI instr in code during pre-alloc splitting.");
VNInfo* NewVN = LI->getNextValue(DefIdx, 0, true, Alloc);
// If the def is a move, set the copy field.
diff --git a/lib/CodeGen/ProcessImplicitDefs.cpp b/lib/CodeGen/ProcessImplicitDefs.cpp
index a00f450..d7179b3 100644
--- a/lib/CodeGen/ProcessImplicitDefs.cpp
+++ b/lib/CodeGen/ProcessImplicitDefs.cpp
@@ -49,9 +49,9 @@ bool ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI,
Reg == SrcReg)
return true;
- if (OpIdx == 2 && MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG)
+ if (OpIdx == 2 && MI->isSubregToReg())
return true;
- if (OpIdx == 1 && MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)
+ if (OpIdx == 1 && MI->isExtractSubreg())
return true;
return false;
}
@@ -88,7 +88,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
I != E; ) {
MachineInstr *MI = &*I;
++I;
- if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
+ if (MI->isImplicitDef()) {
unsigned Reg = MI->getOperand(0).getReg();
ImpDefRegs.insert(Reg);
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
@@ -99,7 +99,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
continue;
}
- if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
+ if (MI->isInsertSubreg()) {
MachineOperand &MO = MI->getOperand(2);
if (ImpDefRegs.count(MO.getReg())) {
// %reg1032<def> = INSERT_SUBREG %reg1032, undef, 2
@@ -127,7 +127,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
// Use is a copy, just turn it into an implicit_def.
if (CanTurnIntoImplicitDef(MI, Reg, i, tii_)) {
bool isKill = MO.isKill();
- MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
+ MI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF));
for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j)
MI->RemoveOperand(j);
if (isKill) {
@@ -187,7 +187,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg),
DE = mri_->def_end(); DI != DE; ++DI) {
MachineInstr *DeadImpDef = &*DI;
- if (DeadImpDef->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) {
+ if (!DeadImpDef->isImplicitDef()) {
Skip = true;
break;
}
@@ -205,10 +205,9 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
// Process each use instruction once.
for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
UE = mri_->use_end(); UI != UE; ++UI) {
- MachineInstr *RMI = &*UI;
- MachineBasicBlock *RMBB = RMI->getParent();
- if (RMBB == MBB)
+ if (UI.getOperand().isUndef())
continue;
+ MachineInstr *RMI = &*UI;
if (ModInsts.insert(RMI))
RUses.push_back(RMI);
}
@@ -220,7 +219,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
Reg == SrcReg) {
- RMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
+ RMI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF));
bool isKill = false;
SmallVector<unsigned, 4> Ops;
@@ -264,8 +263,8 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
}
}
RUses.clear();
+ ModInsts.clear();
}
- ModInsts.clear();
ImpDefRegs.clear();
ImpDefMIs.clear();
}
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 709d46a..040259e 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -161,7 +161,7 @@ void PEI::calculateCallsInformation(MachineFunction &Fn) {
if (Size > MaxCallFrameSize) MaxCallFrameSize = Size;
HasCalls = true;
FrameSDOps.push_back(I);
- } else if (I->getOpcode() == TargetInstrInfo::INLINEASM) {
+ } else if (I->isInlineAsm()) {
// An InlineAsm might be a call; assume it is to get the stack frame
// aligned correctly for calls.
HasCalls = true;
@@ -476,8 +476,6 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
// Loop over all of the stack objects, assigning sequential addresses...
MachineFrameInfo *FFI = Fn.getFrameInfo();
- unsigned MaxAlign = 1;
-
// Start at the beginning of the local area.
// The Offset is the distance from the stack top in the direction
// of stack growth -- so it's always nonnegative.
@@ -517,9 +515,6 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
Offset += FFI->getObjectSize(i);
unsigned Align = FFI->getObjectAlignment(i);
- // If the alignment of this object is greater than that of the stack,
- // then increase the stack alignment to match.
- MaxAlign = std::max(MaxAlign, Align);
// Adjust to alignment boundary
Offset = (Offset+Align-1)/Align*Align;
@@ -529,9 +524,6 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex;
for (int i = MaxCSFI; i >= MinCSFI ; --i) {
unsigned Align = FFI->getObjectAlignment(i);
- // If the alignment of this object is greater than that of the stack,
- // then increase the stack alignment to match.
- MaxAlign = std::max(MaxAlign, Align);
// Adjust to alignment boundary
Offset = (Offset+Align-1)/Align*Align;
@@ -540,6 +532,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
}
}
+ unsigned MaxAlign = FFI->getMaxAlignment();
+
// Make sure the special register scavenging spill slot is closest to the
// frame pointer if a frame pointer is required.
const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
@@ -605,11 +599,6 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
// Update frame info to pretend that this is part of the stack...
FFI->setStackSize(Offset - LocalAreaOffset);
-
- // Remember the required stack alignment in case targets need it to perform
- // dynamic stack alignment.
- if (MaxAlign > FFI->getMaxAlignment())
- FFI->setMaxAlignment(MaxAlign);
}
diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp
index cbb5826..04303cf 100644
--- a/lib/CodeGen/RegAllocLocal.cpp
+++ b/lib/CodeGen/RegAllocLocal.cpp
@@ -490,9 +490,12 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
// If the virtual register is already available, just update the instruction
// and return.
if (unsigned PR = getVirt2PhysRegMapSlot(VirtReg)) {
- MarkPhysRegRecentlyUsed(PR); // Already have this value available!
MI->getOperand(OpNum).setReg(PR); // Assign the input register
- getVirtRegLastUse(VirtReg) = std::make_pair(MI, OpNum);
+ if (!MI->isDebugValue()) {
+ // Do not do these for DBG_VALUE as they can affect codegen.
+ MarkPhysRegRecentlyUsed(PR); // Already have this value available!
+ getVirtRegLastUse(VirtReg) = std::make_pair(MI, OpNum);
+ }
return MI;
}
@@ -531,7 +534,7 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
std::string msg;
raw_string_ostream Msg(msg);
Msg << "Ran out of registers during register allocation!";
- if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
+ if (MI->isInlineAsm()) {
Msg << "\nPlease check your inline asm statement for invalid "
<< "constraints:\n";
MI->print(Msg, TM);
@@ -544,7 +547,7 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
std::string msg;
raw_string_ostream Msg(msg);
Msg << "Ran out of registers during register allocation!";
- if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
+ if (MI->isInlineAsm()) {
Msg << "\nPlease check your inline asm statement for invalid "
<< "constraints:\n";
MI->print(Msg, TM);
@@ -609,6 +612,8 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
DenseMap<unsigned, std::pair<MachineInstr*, unsigned> > LastUseDef;
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
I != E; ++I) {
+ if (I->isDebugValue())
+ continue;
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
MachineOperand& MO = I->getOperand(i);
// Uses don't trigger any flags, but we need to save
@@ -691,7 +696,13 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
bool usedOutsideBlock = isPhysReg ? false :
UsedInMultipleBlocks.test(MO.getReg() -
TargetRegisterInfo::FirstVirtualRegister);
- if (!isPhysReg && !usedOutsideBlock)
+ if (!isPhysReg && !usedOutsideBlock) {
+ // DBG_VALUE complicates this: if the only refs of a register outside
+ // this block are DBG_VALUE, we can't keep the reg live just for that,
+ // as it will cause the reg to be spilled at the end of this block when
+ // it wouldn't have been otherwise. Nullify the DBG_VALUEs when that
+ // happens.
+ bool UsedByDebugValueOnly = false;
for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()),
UE = MRI.reg_end(); UI != UE; ++UI)
// Two cases:
@@ -699,12 +710,26 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
// - used in the same block before it is defined (loop)
if (UI->getParent() != &MBB ||
(MO.isDef() && UI.getOperand().isUse() && precedes(&*UI, MI))) {
+ if (UI->isDebugValue()) {
+ UsedByDebugValueOnly = true;
+ continue;
+ }
+ // A non-DBG_VALUE use means we can leave DBG_VALUE uses alone.
UsedInMultipleBlocks.set(MO.getReg() -
TargetRegisterInfo::FirstVirtualRegister);
usedOutsideBlock = true;
+ UsedByDebugValueOnly = false;
break;
}
-
+ if (UsedByDebugValueOnly)
+ for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()),
+ UE = MRI.reg_end(); UI != UE; ++UI)
+ if (UI->isDebugValue() &&
+ (UI->getParent() != &MBB ||
+ (MO.isDef() && precedes(&*UI, MI))))
+ UI.getOperand().setReg(0U);
+ }
+
// Physical registers and those that are not live-out of the block
// are killed/dead at their last use/def within this block.
if (isPhysReg || !usedOutsideBlock) {
@@ -764,8 +789,11 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
// Determine whether this is a copy instruction. The cases where the
// source or destination are phys regs are handled specially.
unsigned SrcCopyReg, DstCopyReg, SrcCopySubReg, DstCopySubReg;
+ unsigned SrcCopyPhysReg = 0U;
bool isCopy = TII->isMoveInstr(*MI, SrcCopyReg, DstCopyReg,
SrcCopySubReg, DstCopySubReg);
+ if (isCopy && TargetRegisterInfo::isVirtualRegister(SrcCopyReg))
+ SrcCopyPhysReg = getVirt2PhysRegMapSlot(SrcCopyReg);
// Loop over the implicit uses, making sure that they are at the head of the
// use order list, so they don't get reallocated.
@@ -793,7 +821,7 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
// have in them, then mark them unallocatable.
// If any virtual regs are earlyclobber, allocate them now (before
// freeing inputs that are killed).
- if (MI->getOpcode()==TargetInstrInfo::INLINEASM) {
+ if (MI->isInlineAsm()) {
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
MachineOperand& MO = MI->getOperand(i);
if (MO.isReg() && MO.isDef() && MO.isEarlyClobber() &&
@@ -838,6 +866,18 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
}
}
+ // If a DBG_VALUE says something is located in a spilled register,
+ // change the DBG_VALUE to be undef, which prevents the register
+ // from being reloaded here. Doing that would change the generated
+ // code, unless another use immediately follows this instruction.
+ if (MI->isDebugValue() &&
+ MI->getNumOperands()==3 && MI->getOperand(0).isReg()) {
+ unsigned VirtReg = MI->getOperand(0).getReg();
+ if (VirtReg && TargetRegisterInfo::isVirtualRegister(VirtReg) &&
+ !getVirt2PhysRegMapSlot(VirtReg))
+ MI->getOperand(0).setReg(0U);
+ }
+
// Get the used operands into registers. This has the potential to spill
// incoming values if we are out of registers. Note that we completely
// ignore physical register uses here. We assume that if an explicit
@@ -965,13 +1005,26 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
// If DestVirtReg already has a value, use it.
if (!(DestPhysReg = getVirt2PhysRegMapSlot(DestVirtReg))) {
+ // If this is a copy try to reuse the input as the output;
+ // that will make the copy go away.
// If this is a copy, the source reg is a phys reg, and
// that reg is available, use that phys reg for DestPhysReg.
+ // If this is a copy, the source reg is a virtual reg, and
+ // the phys reg that was assigned to that virtual reg is now
+ // available, use that phys reg for DestPhysReg. (If it's now
+ // available that means this was the last use of the source.)
if (isCopy &&
TargetRegisterInfo::isPhysicalRegister(SrcCopyReg) &&
isPhysRegAvailable(SrcCopyReg)) {
DestPhysReg = SrcCopyReg;
assignVirtToPhysReg(DestVirtReg, DestPhysReg);
+ } else if (isCopy &&
+ TargetRegisterInfo::isVirtualRegister(SrcCopyReg) &&
+ SrcCopyPhysReg && isPhysRegAvailable(SrcCopyPhysReg) &&
+ MF->getRegInfo().getRegClass(DestVirtReg)->
+ contains(SrcCopyPhysReg)) {
+ DestPhysReg = SrcCopyPhysReg;
+ assignVirtToPhysReg(DestVirtReg, DestPhysReg);
} else
DestPhysReg = getReg(MBB, MI, DestVirtReg);
}
diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp
index fc59653..2701faf 100644
--- a/lib/CodeGen/RegAllocPBQP.cpp
+++ b/lib/CodeGen/RegAllocPBQP.cpp
@@ -32,7 +32,7 @@
#define DEBUG_TYPE "regalloc"
#include "PBQP/HeuristicSolver.h"
-#include "PBQP/SimpleGraph.h"
+#include "PBQP/Graph.h"
#include "PBQP/Heuristics/Briggs.h"
#include "VirtRegMap.h"
#include "VirtRegRewriter.h"
@@ -58,12 +58,12 @@ using namespace llvm;
static RegisterRegAlloc
registerPBQPRepAlloc("pbqp", "PBQP register allocator.",
- llvm::createPBQPRegisterAllocator);
+ llvm::createPBQPRegisterAllocator);
static cl::opt<bool>
pbqpCoalescing("pbqp-coalescing",
- cl::desc("Attempt coalescing during PBQP register allocation."),
- cl::init(false), cl::Hidden);
+ cl::desc("Attempt coalescing during PBQP register allocation."),
+ cl::init(false), cl::Hidden);
namespace {
@@ -114,6 +114,8 @@ namespace {
typedef std::set<LiveInterval*> LiveIntervalSet;
+ typedef std::vector<PBQP::Graph::NodeItr> NodeVector;
+
MachineFunction *mf;
const TargetMachine *tm;
const TargetRegisterInfo *tri;
@@ -130,6 +132,7 @@ namespace {
AllowedSetMap allowedSets;
LiveIntervalSet vregIntervalsToAlloc,
emptyVRegIntervals;
+ NodeVector problemNodes;
/// Builds a PBQP cost vector.
@@ -174,7 +177,7 @@ namespace {
/// allocation problem for this function.
///
/// @return a PBQP solver object for the register allocation problem.
- PBQP::SimpleGraph constructPBQPProblem();
+ PBQP::Graph constructPBQPProblem();
/// \brief Adds a stack interval if the given live interval has been
/// spilled. Used to support stack slot coloring.
@@ -408,16 +411,16 @@ PBQPRegAlloc::CoalesceMap PBQPRegAlloc::findCoalesces() {
// We also need any physical regs to be allocable, coalescing with
// a non-allocable register is invalid.
if (srcRegIsPhysical) {
- if (std::find(srcRegClass->allocation_order_begin(*mf),
- srcRegClass->allocation_order_end(*mf), srcReg) ==
- srcRegClass->allocation_order_end(*mf))
+ if (std::find(dstRegClass->allocation_order_begin(*mf),
+ dstRegClass->allocation_order_end(*mf), srcReg) ==
+ dstRegClass->allocation_order_end(*mf))
continue;
}
if (dstRegIsPhysical) {
- if (std::find(dstRegClass->allocation_order_begin(*mf),
- dstRegClass->allocation_order_end(*mf), dstReg) ==
- dstRegClass->allocation_order_end(*mf))
+ if (std::find(srcRegClass->allocation_order_begin(*mf),
+ srcRegClass->allocation_order_end(*mf), dstReg) ==
+ srcRegClass->allocation_order_end(*mf))
continue;
}
@@ -439,6 +442,12 @@ PBQPRegAlloc::CoalesceMap PBQPRegAlloc::findCoalesces() {
vniItr = srcLI->vni_begin(), vniEnd = srcLI->vni_end();
vniItr != vniEnd; ++vniItr) {
+ // If we find a poorly defined def we err on the side of caution.
+ if (!(*vniItr)->def.isValid()) {
+ badDef = true;
+ break;
+ }
+
// If we find a def that kills the coalescing opportunity then
// record it and break from the loop.
if (dstLI->liveAt((*vniItr)->def)) {
@@ -460,6 +469,11 @@ PBQPRegAlloc::CoalesceMap PBQPRegAlloc::findCoalesces() {
if ((*vniItr)->getCopy() == instr)
continue;
+ if (!(*vniItr)->def.isValid()) {
+ badDef = true;
+ break;
+ }
+
if (srcLI->liveAt((*vniItr)->def)) {
badDef = true;
break;
@@ -510,11 +524,10 @@ void PBQPRegAlloc::findVRegIntervalsToAlloc() {
}
}
-PBQP::SimpleGraph PBQPRegAlloc::constructPBQPProblem() {
+PBQP::Graph PBQPRegAlloc::constructPBQPProblem() {
typedef std::vector<const LiveInterval*> LIVector;
typedef std::vector<unsigned> RegVector;
- typedef std::vector<PBQP::SimpleGraph::NodeIterator> NodeVector;
// This will store the physical intervals for easy reference.
LIVector physIntervals;
@@ -553,8 +566,8 @@ PBQP::SimpleGraph PBQPRegAlloc::constructPBQPProblem() {
}
// Construct a PBQP solver for this problem
- PBQP::SimpleGraph problem;
- NodeVector problemNodes(vregIntervalsToAlloc.size());
+ PBQP::Graph problem;
+ problemNodes.resize(vregIntervalsToAlloc.size());
// Resize allowedSets container appropriately.
allowedSets.resize(vregIntervalsToAlloc.size());
@@ -657,12 +670,7 @@ PBQP::SimpleGraph PBQPRegAlloc::constructPBQPProblem() {
}
}
- problem.assignNodeIDs();
-
assert(problem.getNumNodes() == allowedSets.size());
- for (unsigned i = 0; i < allowedSets.size(); ++i) {
- assert(problem.getNodeItr(i) == problemNodes[i]);
- }
/*
std::cerr << "Allocating for " << problem.getNumNodes() << " nodes, "
<< problem.getNumEdges() << " edges.\n";
@@ -696,10 +704,6 @@ void PBQPRegAlloc::addStackInterval(const LiveInterval *spilled,
bool PBQPRegAlloc::mapPBQPToRegAlloc(const PBQP::Solution &solution) {
- // Assert that this is a valid solution to the regalloc problem.
- assert(solution.getCost() != std::numeric_limits<PBQP::PBQPNum>::infinity() &&
- "Invalid (infinite cost) solution for PBQP problem.");
-
// Set to true if we have any spills
bool anotherRoundNeeded = false;
@@ -709,7 +713,7 @@ bool PBQPRegAlloc::mapPBQPToRegAlloc(const PBQP::Solution &solution) {
// Iterate over the nodes mapping the PBQP solution to a register assignment.
for (unsigned node = 0; node < node2LI.size(); ++node) {
unsigned virtReg = node2LI[node]->reg,
- allocSelection = solution.getSelection(node);
+ allocSelection = solution.getSelection(problemNodes[node]);
// If the PBQP solution is non-zero it's a physical register...
@@ -849,7 +853,7 @@ bool PBQPRegAlloc::runOnMachineFunction(MachineFunction &MF) {
vrm = &getAnalysis<VirtRegMap>();
- DEBUG(dbgs() << "PBQP2 Register Allocating for " << mf->getFunction()->getName() << "\n");
+ DEBUG(dbgs() << "PBQP Register Allocating for " << mf->getFunction()->getName() << "\n");
// Allocator main loop:
//
@@ -876,10 +880,9 @@ bool PBQPRegAlloc::runOnMachineFunction(MachineFunction &MF) {
while (!pbqpAllocComplete) {
DEBUG(dbgs() << " PBQP Regalloc round " << round << ":\n");
- PBQP::SimpleGraph problem = constructPBQPProblem();
- PBQP::HeuristicSolver<PBQP::Heuristics::Briggs> solver;
- problem.assignNodeIDs();
- PBQP::Solution solution = solver.solve(problem);
+ PBQP::Graph problem = constructPBQPProblem();
+ PBQP::Solution solution =
+ PBQP::HeuristicSolver<PBQP::Heuristics::Briggs>::solve(problem);
pbqpAllocComplete = mapPBQPToRegAlloc(solution);
@@ -895,6 +898,7 @@ bool PBQPRegAlloc::runOnMachineFunction(MachineFunction &MF) {
li2Node.clear();
node2LI.clear();
allowedSets.clear();
+ problemNodes.clear();
DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << *vrm << "\n");
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 8883064..7da7848 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1881,7 +1881,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
LN0->getChain(), LN0->getBasePtr(),
LN0->getSrcValue(),
LN0->getSrcValueOffset(), MemVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
AddToWorkList(N);
CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -1903,7 +1904,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), MemVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
AddToWorkList(N);
CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -1935,7 +1937,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
DAG.getExtLoad(ISD::ZEXTLOAD, LN0->getDebugLoc(), LoadResultTy,
LN0->getChain(), LN0->getBasePtr(),
LN0->getSrcValue(), LN0->getSrcValueOffset(),
- ExtVT, LN0->isVolatile(), LN0->getAlignment());
+ ExtVT, LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
AddToWorkList(N);
CombineTo(LN0, NewLoad, NewLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -1970,7 +1973,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
DAG.getExtLoad(ISD::ZEXTLOAD, LN0->getDebugLoc(), LoadResultTy,
LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset(),
- ExtVT, LN0->isVolatile(), Alignment);
+ ExtVT, LN0->isVolatile(), LN0->isNonTemporal(),
+ Alignment);
AddToWorkList(N);
CombineTo(LN0, Load, Load.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -2640,7 +2644,7 @@ SDValue DAGCombiner::visitSRA(SDNode *N) {
// If the shift is not a no-op (in which case this should be just a sign
// extend already), the truncated to type is legal, sign_extend is legal
- // on that type, and the the truncate to that type is both legal and free,
+ // on that type, and the truncate to that type is both legal and free,
// perform the transform.
if ((ShiftAmt > 0) &&
TLI.isOperationLegalOrCustom(ISD::SIGN_EXTEND, TruncVT) &&
@@ -3143,7 +3147,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
N0.getValueType(), ExtLoad);
@@ -3185,7 +3190,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), MemVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
@@ -3220,6 +3226,14 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
NegOne, DAG.getConstant(0, VT),
cast<CondCodeSDNode>(N0.getOperand(2))->get(), true);
if (SCC.getNode()) return SCC;
+ if (!LegalOperations ||
+ TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultType(VT)))
+ return DAG.getNode(ISD::SELECT, N->getDebugLoc(), VT,
+ DAG.getSetCC(N->getDebugLoc(),
+ TLI.getSetCCResultType(VT),
+ N0.getOperand(0), N0.getOperand(1),
+ cast<CondCodeSDNode>(N0.getOperand(2))->get()),
+ NegOne, DAG.getConstant(0, VT));
}
@@ -3307,7 +3321,8 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
N0.getValueType(), ExtLoad);
@@ -3349,7 +3364,8 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), MemVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), N0.getValueType(),
@@ -3463,7 +3479,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
N0.getValueType(), ExtLoad);
@@ -3505,7 +3522,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
VT, LN0->getChain(), LN0->getBasePtr(),
LN0->getSrcValue(),
LN0->getSrcValueOffset(), MemVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(),
@@ -3628,10 +3646,11 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
SDValue Load = (ExtType == ISD::NON_EXTLOAD)
? DAG.getLoad(VT, N0.getDebugLoc(), LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff,
- LN0->isVolatile(), NewAlign)
+ LN0->isVolatile(), LN0->isNonTemporal(), NewAlign)
: DAG.getExtLoad(ExtType, N0.getDebugLoc(), VT, LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff,
- ExtVT, LN0->isVolatile(), NewAlign);
+ ExtVT, LN0->isVolatile(), LN0->isNonTemporal(),
+ NewAlign);
// Replace the old load's chain with the new load's chain.
WorkListRemover DeadNodes(*this);
@@ -3718,7 +3737,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -3734,7 +3754,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -3818,7 +3839,7 @@ SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *N, EVT VT) {
(!LegalOperations || TLI.isOperationLegal(ISD::LOAD, VT)))
return DAG.getLoad(VT, N->getDebugLoc(), LD1->getChain(),
LD1->getBasePtr(), LD1->getSrcValue(),
- LD1->getSrcValueOffset(), false, Align);
+ LD1->getSrcValueOffset(), false, false, Align);
}
return SDValue();
@@ -3888,7 +3909,8 @@ SDValue DAGCombiner::visitBIT_CONVERT(SDNode *N) {
SDValue Load = DAG.getLoad(VT, N->getDebugLoc(), LN0->getChain(),
LN0->getBasePtr(),
LN0->getSrcValue(), LN0->getSrcValueOffset(),
- LN0->isVolatile(), OrigAlign);
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ OrigAlign);
AddToWorkList(N);
CombineTo(N0.getNode(),
DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(),
@@ -4484,7 +4506,8 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) {
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(),
N0.getValueType(),
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), LN0->isNonTemporal(),
+ LN0->getAlignment());
CombineTo(N, ExtLoad);
CombineTo(N0.getNode(),
DAG.getNode(ISD::FP_ROUND, N0.getDebugLoc(),
@@ -4952,7 +4975,7 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
LD->getValueType(0),
Chain, Ptr, LD->getSrcValue(),
LD->getSrcValueOffset(), LD->getMemoryVT(),
- LD->isVolatile(), Align);
+ LD->isVolatile(), LD->isNonTemporal(), Align);
}
}
@@ -5034,7 +5057,8 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
ReplLoad = DAG.getLoad(N->getValueType(0), LD->getDebugLoc(),
BetterChain, Ptr,
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(),
+ LD->getAlignment());
} else {
ReplLoad = DAG.getExtLoad(LD->getExtensionType(), LD->getDebugLoc(),
LD->getValueType(0),
@@ -5042,6 +5066,7 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
LD->getSrcValueOffset(),
LD->getMemoryVT(),
LD->isVolatile(),
+ LD->isNonTemporal(),
LD->getAlignment());
}
@@ -5141,13 +5166,14 @@ SDValue DAGCombiner::ReduceLoadOpStoreWidth(SDNode *N) {
SDValue NewLD = DAG.getLoad(NewVT, N0.getDebugLoc(),
LD->getChain(), NewPtr,
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile(), NewAlign);
+ LD->isVolatile(), LD->isNonTemporal(),
+ NewAlign);
SDValue NewVal = DAG.getNode(Opc, Value.getDebugLoc(), NewVT, NewLD,
DAG.getConstant(NewImm, NewVT));
SDValue NewST = DAG.getStore(Chain, N->getDebugLoc(),
NewVal, NewPtr,
ST->getSrcValue(), ST->getSrcValueOffset(),
- false, NewAlign);
+ false, false, NewAlign);
AddToWorkList(NewPtr.getNode());
AddToWorkList(NewLD.getNode());
@@ -5176,7 +5202,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return DAG.getTruncStore(Chain, N->getDebugLoc(), Value,
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->getMemoryVT(),
- ST->isVolatile(), Align);
+ ST->isVolatile(), ST->isNonTemporal(), Align);
}
}
@@ -5193,7 +5219,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
TLI.isOperationLegalOrCustom(ISD::STORE, SVT)))
return DAG.getStore(Chain, N->getDebugLoc(), Value.getOperand(0),
Ptr, ST->getSrcValue(),
- ST->getSrcValueOffset(), ST->isVolatile(), OrigAlign);
+ ST->getSrcValueOffset(), ST->isVolatile(),
+ ST->isNonTemporal(), OrigAlign);
}
// Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr'
@@ -5219,7 +5246,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return DAG.getStore(Chain, N->getDebugLoc(), Tmp,
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->isVolatile(),
- ST->getAlignment());
+ ST->isNonTemporal(), ST->getAlignment());
}
break;
case MVT::f64:
@@ -5231,7 +5258,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return DAG.getStore(Chain, N->getDebugLoc(), Tmp,
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->isVolatile(),
- ST->getAlignment());
+ ST->isNonTemporal(), ST->getAlignment());
} else if (!ST->isVolatile() &&
TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i32)) {
// Many FP stores are not made apparent until after legalize, e.g. for
@@ -5245,18 +5272,21 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
int SVOffset = ST->getSrcValueOffset();
unsigned Alignment = ST->getAlignment();
bool isVolatile = ST->isVolatile();
+ bool isNonTemporal = ST->isNonTemporal();
SDValue St0 = DAG.getStore(Chain, ST->getDebugLoc(), Lo,
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(),
- isVolatile, ST->getAlignment());
+ isVolatile, isNonTemporal,
+ ST->getAlignment());
Ptr = DAG.getNode(ISD::ADD, N->getDebugLoc(), Ptr.getValueType(), Ptr,
DAG.getConstant(4, Ptr.getValueType()));
SVOffset += 4;
Alignment = MinAlign(Alignment, 4U);
SDValue St1 = DAG.getStore(Chain, ST->getDebugLoc(), Hi,
Ptr, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
+ SVOffset, isVolatile, isNonTemporal,
+ Alignment);
return DAG.getNode(ISD::TokenFactor, N->getDebugLoc(), MVT::Other,
St0, St1);
}
@@ -5278,12 +5308,13 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
if (ST->isTruncatingStore()) {
ReplStore = DAG.getTruncStore(BetterChain, N->getDebugLoc(), Value, Ptr,
ST->getSrcValue(),ST->getSrcValueOffset(),
- ST->getMemoryVT(),
- ST->isVolatile(), ST->getAlignment());
+ ST->getMemoryVT(), ST->isVolatile(),
+ ST->isNonTemporal(), ST->getAlignment());
} else {
ReplStore = DAG.getStore(BetterChain, N->getDebugLoc(), Value, Ptr,
ST->getSrcValue(), ST->getSrcValueOffset(),
- ST->isVolatile(), ST->getAlignment());
+ ST->isVolatile(), ST->isNonTemporal(),
+ ST->getAlignment());
}
// Create token to keep both nodes around.
@@ -5317,7 +5348,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return DAG.getTruncStore(Chain, N->getDebugLoc(), Shorter,
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->getMemoryVT(),
- ST->isVolatile(), ST->getAlignment());
+ ST->isVolatile(), ST->isNonTemporal(),
+ ST->getAlignment());
// Otherwise, see if we can simplify the operation with
// SimplifyDemandedBits, which only works if the value has a single use.
@@ -5350,7 +5382,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return DAG.getTruncStore(Chain, N->getDebugLoc(), Value.getOperand(0),
Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->getMemoryVT(),
- ST->isVolatile(), ST->getAlignment());
+ ST->isVolatile(), ST->isNonTemporal(),
+ ST->getAlignment());
}
return ReduceLoadOpStoreWidth(N);
@@ -5395,12 +5428,16 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
SDValue InVec = N->getOperand(0);
if (InVec.getOpcode() == ISD::SCALAR_TO_VECTOR) {
- // If the operand is wider than the vector element type then it is implicitly
- // truncated. Make that explicit here.
+ // Check if the result type doesn't match the inserted element type. A
+ // SCALAR_TO_VECTOR may truncate the inserted element and the
+ // EXTRACT_VECTOR_ELT may widen the extracted vector.
EVT EltVT = InVec.getValueType().getVectorElementType();
SDValue InOp = InVec.getOperand(0);
- if (InOp.getValueType() != EltVT)
- return DAG.getNode(ISD::TRUNCATE, InVec.getDebugLoc(), EltVT, InOp);
+ EVT NVT = N->getValueType(0);
+ if (InOp.getValueType() != NVT) {
+ assert(InOp.getValueType().isInteger() && NVT.isInteger());
+ return DAG.getSExtOrTrunc(InOp, InVec.getDebugLoc(), NVT);
+ }
return InOp;
}
@@ -5491,7 +5528,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
return DAG.getLoad(LVT, N->getDebugLoc(), LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset(),
- LN0->isVolatile(), Align);
+ LN0->isVolatile(), LN0->isNonTemporal(), Align);
}
return SDValue();
@@ -5871,6 +5908,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
LLD->getChain(),
Addr, 0, 0,
LLD->isVolatile(),
+ LLD->isNonTemporal(),
LLD->getAlignment());
} else {
Load = DAG.getExtLoad(LLD->getExtensionType(),
@@ -5879,6 +5917,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
LLD->getChain(), Addr, 0, 0,
LLD->getMemoryVT(),
LLD->isVolatile(),
+ LLD->isNonTemporal(),
LLD->getAlignment());
}
@@ -5986,7 +6025,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
CstOffset);
return DAG.getLoad(TV->getValueType(0), DL, DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0, false,
- Alignment);
+ false, Alignment);
}
}
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index 09fd657..35ef5b7 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -121,7 +121,7 @@ unsigned FastISel::getRegForValue(Value *V) {
Reg = LocalValueMap[CE];
} else if (isa<UndefValue>(V)) {
Reg = createResultReg(TLI.getRegClassFor(VT));
- BuildMI(MBB, DL, TII.get(TargetInstrInfo::IMPLICIT_DEF), Reg);
+ BuildMI(MBB, DL, TII.get(TargetOpcode::IMPLICIT_DEF), Reg);
}
// If target-independent code couldn't handle the value, give target-specific
@@ -332,6 +332,8 @@ bool FastISel::SelectCall(User *I) {
return true;
Value *Address = DI->getAddress();
+ if (!Address)
+ return true;
AllocaInst *AI = dyn_cast<AllocaInst>(Address);
// Don't handle byval struct arguments or VLAs, for example.
if (!AI) break;
@@ -343,6 +345,9 @@ bool FastISel::SelectCall(User *I) {
if (MDNode *Dbg = DI->getMetadata("dbg"))
MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg);
}
+ // Building the map above is target independent. Generating DBG_VALUE
+ // inline is target dependent; do this now.
+ (void)TargetSelectInstruction(cast<Instruction>(I));
return true;
}
case Intrinsic::eh_exception: {
@@ -966,7 +971,7 @@ unsigned FastISel::FastEmitInst_extractsubreg(MVT RetVT,
const TargetRegisterClass* RC = MRI.getRegClass(Op0);
unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
- const TargetInstrDesc &II = TII.get(TargetInstrInfo::EXTRACT_SUBREG);
+ const TargetInstrDesc &II = TII.get(TargetOpcode::EXTRACT_SUBREG);
if (II.getNumDefs() >= 1)
BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addImm(Idx);
diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index dc7d82d..50f4c32 100644
--- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -227,7 +227,7 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf,
unsigned NumRegisters = TLI.getNumRegisters(Fn->getContext(), VT);
const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
for (unsigned i = 0; i != NumRegisters; ++i)
- BuildMI(MBB, DL, TII->get(TargetInstrInfo::PHI), PHIReg + i);
+ BuildMI(MBB, DL, TII->get(TargetOpcode::PHI), PHIReg + i);
PHIReg += NumRegisters;
}
}
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 9c50936..02fe85d 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -178,7 +178,7 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
const TargetInstrDesc &II,
bool IsClone, bool IsCloned,
DenseMap<SDValue, unsigned> &VRBaseMap) {
- assert(Node->getMachineOpcode() != TargetInstrInfo::IMPLICIT_DEF &&
+ assert(Node->getMachineOpcode() != TargetOpcode::IMPLICIT_DEF &&
"IMPLICIT_DEF should have been handled as a special case elsewhere!");
for (unsigned i = 0; i < II.getNumDefs(); ++i) {
@@ -236,7 +236,7 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
unsigned InstrEmitter::getVR(SDValue Op,
DenseMap<SDValue, unsigned> &VRBaseMap) {
if (Op.isMachineOpcode() &&
- Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
+ Op.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) {
// Add an IMPLICIT_DEF instruction before every use.
unsigned VReg = getDstOfOnlyCopyToRegUse(Op.getNode(), Op.getResNo());
// IMPLICIT_DEF can produce any type of result so its TargetInstrDesc
@@ -246,7 +246,7 @@ unsigned InstrEmitter::getVR(SDValue Op,
VReg = MRI->createVirtualRegister(RC);
}
BuildMI(MBB, Op.getDebugLoc(),
- TII->get(TargetInstrInfo::IMPLICIT_DEF), VReg);
+ TII->get(TargetOpcode::IMPLICIT_DEF), VReg);
return VReg;
}
@@ -396,12 +396,12 @@ void InstrEmitter::EmitSubregNode(SDNode *Node,
}
}
- if (Opc == TargetInstrInfo::EXTRACT_SUBREG) {
+ if (Opc == TargetOpcode::EXTRACT_SUBREG) {
unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
// Create the extract_subreg machine instruction.
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
- TII->get(TargetInstrInfo::EXTRACT_SUBREG));
+ TII->get(TargetOpcode::EXTRACT_SUBREG));
// Figure out the register class to create for the destreg.
unsigned VReg = getVR(Node->getOperand(0), VRBaseMap);
@@ -424,8 +424,8 @@ void InstrEmitter::EmitSubregNode(SDNode *Node,
AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
MI->addOperand(MachineOperand::CreateImm(SubIdx));
MBB->insert(InsertPos, MI);
- } else if (Opc == TargetInstrInfo::INSERT_SUBREG ||
- Opc == TargetInstrInfo::SUBREG_TO_REG) {
+ } else if (Opc == TargetOpcode::INSERT_SUBREG ||
+ Opc == TargetOpcode::SUBREG_TO_REG) {
SDValue N0 = Node->getOperand(0);
SDValue N1 = Node->getOperand(1);
SDValue N2 = Node->getOperand(2);
@@ -452,7 +452,7 @@ void InstrEmitter::EmitSubregNode(SDNode *Node,
// If creating a subreg_to_reg, then the first input operand
// is an implicit value immediate, otherwise it's a register
- if (Opc == TargetInstrInfo::SUBREG_TO_REG) {
+ if (Opc == TargetOpcode::SUBREG_TO_REG) {
const ConstantSDNode *SD = cast<ConstantSDNode>(N0);
MI->addOperand(MachineOperand::CreateImm(SD->getZExtValue()));
} else
@@ -507,20 +507,20 @@ void InstrEmitter::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
unsigned Opc = Node->getMachineOpcode();
// Handle subreg insert/extract specially
- if (Opc == TargetInstrInfo::EXTRACT_SUBREG ||
- Opc == TargetInstrInfo::INSERT_SUBREG ||
- Opc == TargetInstrInfo::SUBREG_TO_REG) {
+ if (Opc == TargetOpcode::EXTRACT_SUBREG ||
+ Opc == TargetOpcode::INSERT_SUBREG ||
+ Opc == TargetOpcode::SUBREG_TO_REG) {
EmitSubregNode(Node, VRBaseMap);
return;
}
// Handle COPY_TO_REGCLASS specially.
- if (Opc == TargetInstrInfo::COPY_TO_REGCLASS) {
+ if (Opc == TargetOpcode::COPY_TO_REGCLASS) {
EmitCopyToRegClassNode(Node, VRBaseMap);
return;
}
- if (Opc == TargetInstrInfo::IMPLICIT_DEF)
+ if (Opc == TargetOpcode::IMPLICIT_DEF)
// We want a unique VR for each IMPLICIT_DEF use.
return;
@@ -640,7 +640,7 @@ void InstrEmitter::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
// Create the inline asm machine instruction.
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
- TII->get(TargetInstrInfo::INLINEASM));
+ TII->get(TargetOpcode::INLINEASM));
// Add the asm string as an external symbol operand.
const char *AsmStr =
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 5e3f58a..e9321da 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -377,9 +377,10 @@ static SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP,
return DAG.getExtLoad(ISD::EXTLOAD, dl,
OrigVT, DAG.getEntryNode(),
CPIdx, PseudoSourceValue::getConstantPool(),
- 0, VT, false, Alignment);
+ 0, VT, false, false, Alignment);
return DAG.getLoad(OrigVT, dl, DAG.getEntryNode(), CPIdx,
- PseudoSourceValue::getConstantPool(), 0, false, Alignment);
+ PseudoSourceValue::getConstantPool(), 0, false, false,
+ Alignment);
}
/// ExpandUnalignedStore - Expands an unaligned store to 2 half-size stores.
@@ -402,7 +403,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
// FIXME: Does not handle truncating floating point stores!
SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, intVT, Val);
return DAG.getStore(Chain, dl, Result, Ptr, ST->getSrcValue(),
- SVOffset, ST->isVolatile(), Alignment);
+ SVOffset, ST->isVolatile(), ST->isNonTemporal(),
+ Alignment);
} else {
// Do a (aligned) store to a stack slot, then copy from the stack slot
// to the final destination using (unaligned) integer loads and stores.
@@ -418,7 +420,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
// Perform the original store, only redirected to the stack slot.
SDValue Store = DAG.getTruncStore(Chain, dl,
- Val, StackPtr, NULL, 0, StoredVT);
+ Val, StackPtr, NULL, 0, StoredVT,
+ false, false, 0);
SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy());
SmallVector<SDValue, 8> Stores;
unsigned Offset = 0;
@@ -426,11 +429,12 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
// Do all but one copies using the full register width.
for (unsigned i = 1; i < NumRegs; i++) {
// Load one integer register's worth from the stack slot.
- SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, NULL, 0);
+ SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, NULL, 0,
+ false, false, 0);
// Store it to the final location. Remember the store.
Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr,
ST->getSrcValue(), SVOffset + Offset,
- ST->isVolatile(),
+ ST->isVolatile(), ST->isNonTemporal(),
MinAlign(ST->getAlignment(), Offset)));
// Increment the pointers.
Offset += RegBytes;
@@ -446,11 +450,12 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
// Load from the stack slot.
SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Store, StackPtr,
- NULL, 0, MemVT);
+ NULL, 0, MemVT, false, false, 0);
Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr,
ST->getSrcValue(), SVOffset + Offset,
MemVT, ST->isVolatile(),
+ ST->isNonTemporal(),
MinAlign(ST->getAlignment(), Offset)));
// The order of the stores doesn't matter - say it with a TokenFactor.
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0],
@@ -474,13 +479,14 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
SDValue Store1, Store2;
Store1 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Lo:Hi, Ptr,
ST->getSrcValue(), SVOffset, NewStoredVT,
- ST->isVolatile(), Alignment);
+ ST->isVolatile(), ST->isNonTemporal(), Alignment);
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
Alignment = MinAlign(Alignment, IncrementSize);
Store2 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Hi:Lo, Ptr,
ST->getSrcValue(), SVOffset + IncrementSize,
- NewStoredVT, ST->isVolatile(), Alignment);
+ NewStoredVT, ST->isVolatile(), ST->isNonTemporal(),
+ Alignment);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2);
}
@@ -502,7 +508,7 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
// then bitconvert to floating point or vector.
SDValue newLoad = DAG.getLoad(intVT, dl, Chain, Ptr, LD->getSrcValue(),
SVOffset, LD->isVolatile(),
- LD->getAlignment());
+ LD->isNonTemporal(), LD->getAlignment());
SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, LoadedVT, newLoad);
if (VT.isFloatingPoint() && LoadedVT != VT)
Result = DAG.getNode(ISD::FP_EXTEND, dl, VT, Result);
@@ -530,10 +536,11 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
// Load one integer register's worth from the original location.
SDValue Load = DAG.getLoad(RegVT, dl, Chain, Ptr, LD->getSrcValue(),
SVOffset + Offset, LD->isVolatile(),
+ LD->isNonTemporal(),
MinAlign(LD->getAlignment(), Offset));
// Follow the load with a store to the stack slot. Remember the store.
Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, StackPtr,
- NULL, 0));
+ NULL, 0, false, false, 0));
// Increment the pointers.
Offset += RegBytes;
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment);
@@ -546,12 +553,13 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr,
LD->getSrcValue(), SVOffset + Offset,
MemVT, LD->isVolatile(),
+ LD->isNonTemporal(),
MinAlign(LD->getAlignment(), Offset));
// Follow the load with a store to the stack slot. Remember the store.
// On big-endian machines this requires a truncating store to ensure
// that the bits end up in the right place.
Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, StackPtr,
- NULL, 0, MemVT));
+ NULL, 0, MemVT, false, false, 0));
// The order of the stores doesn't matter - say it with a TokenFactor.
SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0],
@@ -559,7 +567,7 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
// Finally, perform the original load only redirected to the stack slot.
Load = DAG.getExtLoad(LD->getExtensionType(), dl, VT, TF, StackBase,
- NULL, 0, LoadedVT);
+ NULL, 0, LoadedVT, false, false, 0);
// Callers expect a MERGE_VALUES node.
SDValue Ops[] = { Load, TF };
@@ -588,20 +596,22 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
SDValue Lo, Hi;
if (TLI.isLittleEndian()) {
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(),
- SVOffset, NewLoadedVT, LD->isVolatile(), Alignment);
+ SVOffset, NewLoadedVT, LD->isVolatile(),
+ LD->isNonTemporal(), Alignment);
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(),
SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(),
- MinAlign(Alignment, IncrementSize));
+ LD->isNonTemporal(), MinAlign(Alignment, IncrementSize));
} else {
Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(),
- SVOffset, NewLoadedVT, LD->isVolatile(), Alignment);
+ SVOffset, NewLoadedVT, LD->isVolatile(),
+ LD->isNonTemporal(), Alignment);
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(),
SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(),
- MinAlign(Alignment, IncrementSize));
+ LD->isNonTemporal(), MinAlign(Alignment, IncrementSize));
}
// aggregate the two parts
@@ -643,7 +653,8 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx,
// Store the vector.
SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Tmp1, StackPtr,
- PseudoSourceValue::getFixedStack(SPFI), 0);
+ PseudoSourceValue::getFixedStack(SPFI), 0,
+ false, false, 0);
// Truncate or zero extend offset to target pointer type.
unsigned CastOpc = IdxVT.bitsGT(PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
@@ -654,10 +665,12 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx,
SDValue StackPtr2 = DAG.getNode(ISD::ADD, dl, IdxVT, Tmp3, StackPtr);
// Store the scalar value.
Ch = DAG.getTruncStore(Ch, dl, Tmp2, StackPtr2,
- PseudoSourceValue::getFixedStack(SPFI), 0, EltVT);
+ PseudoSourceValue::getFixedStack(SPFI), 0, EltVT,
+ false, false, 0);
// Load the updated vector.
return DAG.getLoad(VT, dl, Ch, StackPtr,
- PseudoSourceValue::getFixedStack(SPFI), 0);
+ PseudoSourceValue::getFixedStack(SPFI), 0,
+ false, false, 0);
}
@@ -702,6 +715,7 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) {
int SVOffset = ST->getSrcValueOffset();
unsigned Alignment = ST->getAlignment();
bool isVolatile = ST->isVolatile();
+ bool isNonTemporal = ST->isNonTemporal();
DebugLoc dl = ST->getDebugLoc();
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) {
if (CFP->getValueType(0) == MVT::f32 &&
@@ -710,14 +724,14 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) {
bitcastToAPInt().zextOrTrunc(32),
MVT::i32);
return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
+ SVOffset, isVolatile, isNonTemporal, Alignment);
} else if (CFP->getValueType(0) == MVT::f64) {
// If this target supports 64-bit registers, do a single 64-bit store.
if (getTypeAction(MVT::i64) == Legal) {
Tmp3 = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt().
zextOrTrunc(64), MVT::i64);
return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
+ SVOffset, isVolatile, isNonTemporal, Alignment);
} else if (getTypeAction(MVT::i32) == Legal && !ST->isVolatile()) {
// Otherwise, if the target supports 32-bit registers, use 2 32-bit
// stores. If the target supports neither 32- nor 64-bits, this
@@ -728,11 +742,11 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) {
if (TLI.isBigEndian()) std::swap(Lo, Hi);
Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
+ SVOffset, isVolatile, isNonTemporal, Alignment);
Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(4));
Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), SVOffset+4,
- isVolatile, MinAlign(Alignment, 4U));
+ isVolatile, isNonTemporal, MinAlign(Alignment, 4U));
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
@@ -1108,7 +1122,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Tmp1 = DAG.getLoad(NVT, dl, Tmp1, Tmp2, LD->getSrcValue(),
LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(),
+ LD->getAlignment());
Tmp3 = LegalizeOp(DAG.getNode(ISD::BIT_CONVERT, dl, VT, Tmp1));
Tmp4 = LegalizeOp(Tmp1.getValue(1));
break;
@@ -1125,6 +1140,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
int SVOffset = LD->getSrcValueOffset();
unsigned Alignment = LD->getAlignment();
bool isVolatile = LD->isVolatile();
+ bool isNonTemporal = LD->isNonTemporal();
if (SrcWidth != SrcVT.getStoreSizeInBits() &&
// Some targets pretend to have an i1 loading operation, and actually
@@ -1150,7 +1166,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Result = DAG.getExtLoad(NewExtType, dl, Node->getValueType(0),
Tmp1, Tmp2, LD->getSrcValue(), SVOffset,
- NVT, isVolatile, Alignment);
+ NVT, isVolatile, isNonTemporal, Alignment);
Ch = Result.getValue(1); // The chain.
@@ -1187,7 +1203,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl,
Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset, RoundVT, isVolatile,
- Alignment);
+ isNonTemporal, Alignment);
// Load the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
@@ -1195,7 +1211,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
DAG.getIntPtrConstant(IncrementSize));
Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset + IncrementSize,
- ExtraVT, isVolatile,
+ ExtraVT, isVolatile, isNonTemporal,
MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
@@ -1215,7 +1231,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Load the top RoundWidth bits.
Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset, RoundVT, isVolatile,
- Alignment);
+ isNonTemporal, Alignment);
// Load the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
@@ -1224,7 +1240,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl,
Node->getValueType(0), Tmp1, Tmp2,
LD->getSrcValue(), SVOffset + IncrementSize,
- ExtraVT, isVolatile,
+ ExtraVT, isVolatile, isNonTemporal,
MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
@@ -1284,7 +1300,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
(SrcVT == MVT::f64 && Node->getValueType(0) == MVT::f128)) {
SDValue Load = DAG.getLoad(SrcVT, dl, Tmp1, Tmp2, LD->getSrcValue(),
LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(),
+ LD->getAlignment());
Result = DAG.getNode(ISD::FP_EXTEND, dl,
Node->getValueType(0), Load);
Tmp1 = LegalizeOp(Result); // Relegalize new nodes.
@@ -1297,7 +1314,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Result = DAG.getExtLoad(ISD::EXTLOAD, dl, Node->getValueType(0),
Tmp1, Tmp2, LD->getSrcValue(),
LD->getSrcValueOffset(), SrcVT,
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(),
+ LD->getAlignment());
SDValue ValRes;
if (ExtType == ISD::SEXTLOAD)
ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl,
@@ -1325,6 +1343,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
int SVOffset = ST->getSrcValueOffset();
unsigned Alignment = ST->getAlignment();
bool isVolatile = ST->isVolatile();
+ bool isNonTemporal = ST->isNonTemporal();
if (!ST->isTruncatingStore()) {
if (SDNode *OptStore = OptimizeFloatStore(ST).getNode()) {
@@ -1361,7 +1380,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
TLI.getTypeToPromoteTo(ISD::STORE, VT), Tmp3);
Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2,
ST->getSrcValue(), SVOffset, isVolatile,
- Alignment);
+ isNonTemporal, Alignment);
break;
}
break;
@@ -1379,7 +1398,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
EVT NVT = EVT::getIntegerVT(*DAG.getContext(), StVT.getStoreSizeInBits());
Tmp3 = DAG.getZeroExtendInReg(Tmp3, dl, StVT);
Result = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, NVT, isVolatile, Alignment);
+ SVOffset, NVT, isVolatile, isNonTemporal,
+ Alignment);
} else if (StWidth & (StWidth - 1)) {
// If not storing a power-of-2 number of bits, expand as two stores.
assert(!StVT.isVector() && "Unsupported truncstore!");
@@ -1399,7 +1419,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// Store the bottom RoundWidth bits.
Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, RoundVT,
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
// Store the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
@@ -1409,6 +1429,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
DAG.getConstant(RoundWidth, TLI.getShiftAmountTy()));
Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(),
SVOffset + IncrementSize, ExtraVT, isVolatile,
+ isNonTemporal,
MinAlign(Alignment, IncrementSize));
} else {
// Big endian - avoid unaligned stores.
@@ -1417,7 +1438,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3,
DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy()));
Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(),
- SVOffset, RoundVT, isVolatile, Alignment);
+ SVOffset, RoundVT, isVolatile, isNonTemporal,
+ Alignment);
// Store the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
@@ -1425,6 +1447,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
DAG.getIntPtrConstant(IncrementSize));
Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset + IncrementSize, ExtraVT, isVolatile,
+ isNonTemporal,
MinAlign(Alignment, IncrementSize));
}
@@ -1457,7 +1480,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
assert(isTypeLegal(StVT) && "Do not know how to expand this store!");
Tmp3 = DAG.getNode(ISD::TRUNCATE, dl, StVT, Tmp3);
Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
+ SVOffset, isVolatile, isNonTemporal,
+ Alignment);
break;
}
}
@@ -1484,7 +1508,8 @@ SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) {
DebugLoc dl = Op.getDebugLoc();
// Store the value to a temporary stack slot, then LOAD the returned part.
SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType());
- SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0);
+ SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0,
+ false, false, 0);
// Add the offset to the index.
unsigned EltSize =
@@ -1500,10 +1525,12 @@ SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) {
StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr);
if (Op.getValueType().isVector())
- return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0);
+ return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0,
+ false, false, 0);
else
return DAG.getExtLoad(ISD::EXTLOAD, dl, Op.getValueType(), Ch, StackPtr,
- NULL, 0, Vec.getValueType().getVectorElementType());
+ NULL, 0, Vec.getValueType().getVectorElementType(),
+ false, false, 0);
}
SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
@@ -1533,12 +1560,14 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
Idx = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr, Idx);
// If EltVT smaller than OpVT, only store the bits necessary.
- if (EltVT.bitsLT(OpVT))
+ if (!OpVT.isVector() && EltVT.bitsLT(OpVT)) {
Stores.push_back(DAG.getTruncStore(DAG.getEntryNode(), dl,
- Node->getOperand(i), Idx, SV, Offset, EltVT));
- else
+ Node->getOperand(i), Idx, SV, Offset,
+ EltVT, false, false, 0));
+ } else
Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl,
- Node->getOperand(i), Idx, SV, Offset));
+ Node->getOperand(i), Idx, SV, Offset,
+ false, false, 0));
}
SDValue StoreChain;
@@ -1549,7 +1578,7 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
StoreChain = DAG.getEntryNode();
// Result is a load from the stack slot.
- return DAG.getLoad(VT, dl, StoreChain, FIPtr, SV, 0);
+ return DAG.getLoad(VT, dl, StoreChain, FIPtr, SV, 0, false, false, 0);
}
SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode* Node) {
@@ -1572,12 +1601,14 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode* Node) {
SDValue StackPtr = DAG.CreateStackTemporary(Tmp2.getValueType());
SDValue StorePtr = StackPtr, LoadPtr = StackPtr;
SDValue Ch =
- DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StorePtr, NULL, 0);
+ DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StorePtr, NULL, 0,
+ false, false, 0);
if (Tmp2.getValueType() == MVT::f64 && TLI.isLittleEndian())
LoadPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(),
LoadPtr, DAG.getIntPtrConstant(4));
SignBit = DAG.getExtLoad(ISD::SEXTLOAD, dl, TLI.getPointerTy(),
- Ch, LoadPtr, NULL, 0, MVT::i32);
+ Ch, LoadPtr, NULL, 0, MVT::i32,
+ false, false, 0);
}
SignBit =
DAG.getSetCC(dl, TLI.getSetCCResultType(SignBit.getValueType()),
@@ -1701,20 +1732,21 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp,
if (SrcSize > SlotSize)
Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr,
- SV, 0, SlotVT, false, SrcAlign);
+ SV, 0, SlotVT, false, false, SrcAlign);
else {
assert(SrcSize == SlotSize && "Invalid store");
Store = DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr,
- SV, 0, false, SrcAlign);
+ SV, 0, false, false, SrcAlign);
}
// Result is a load from the stack slot.
if (SlotSize == DestSize)
- return DAG.getLoad(DestVT, dl, Store, FIPtr, SV, 0, false, DestAlign);
+ return DAG.getLoad(DestVT, dl, Store, FIPtr, SV, 0, false, false,
+ DestAlign);
assert(SlotSize < DestSize && "Unknown extension!");
return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, SV, 0, SlotVT,
- false, DestAlign);
+ false, false, DestAlign);
}
SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
@@ -1729,9 +1761,11 @@ SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), dl, Node->getOperand(0),
StackPtr,
PseudoSourceValue::getFixedStack(SPFI), 0,
- Node->getValueType(0).getVectorElementType());
+ Node->getValueType(0).getVectorElementType(),
+ false, false, 0);
return DAG.getLoad(Node->getValueType(0), dl, Ch, StackPtr,
- PseudoSourceValue::getFixedStack(SPFI), 0);
+ PseudoSourceValue::getFixedStack(SPFI), 0,
+ false, false, 0);
}
@@ -1805,7 +1839,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
return DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0,
- false, Alignment);
+ false, false, Alignment);
}
if (!MoreThanTwoValues) {
@@ -1943,13 +1977,16 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
}
// store the lo of the constructed double - based on integer input
SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl,
- Op0Mapped, Lo, NULL, 0);
+ Op0Mapped, Lo, NULL, 0,
+ false, false, 0);
// initial hi portion of constructed double
SDValue InitialHi = DAG.getConstant(0x43300000u, MVT::i32);
// store the hi of the constructed double - biased exponent
- SDValue Store2=DAG.getStore(Store1, dl, InitialHi, Hi, NULL, 0);
+ SDValue Store2=DAG.getStore(Store1, dl, InitialHi, Hi, NULL, 0,
+ false, false, 0);
// load the constructed double
- SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, NULL, 0);
+ SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, NULL, 0,
+ false, false, 0);
// FP constant to bias correct the final result
SDValue Bias = DAG.getConstantFP(isSigned ?
BitsToDouble(0x4330000080000000ULL) :
@@ -2004,13 +2041,13 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
if (DestVT == MVT::f32)
FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0,
- false, Alignment);
+ false, false, Alignment);
else {
FudgeInReg =
LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT,
DAG.getEntryNode(), CPIdx,
PseudoSourceValue::getConstantPool(), 0,
- MVT::f32, false, Alignment));
+ MVT::f32, false, false, Alignment));
}
return DAG.getNode(ISD::FADD, dl, DestVT, Tmp1, FudgeInReg);
@@ -2350,16 +2387,19 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
EVT VT = Node->getValueType(0);
Tmp1 = Node->getOperand(0);
Tmp2 = Node->getOperand(1);
- SDValue VAList = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, V, 0);
+ SDValue VAList = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, V, 0,
+ false, false, 0);
// Increment the pointer, VAList, to the next vaarg
Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList,
DAG.getConstant(TLI.getTargetData()->
getTypeAllocSize(VT.getTypeForEVT(*DAG.getContext())),
TLI.getPointerTy()));
// Store the incremented VAList to the legalized pointer
- Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0);
+ Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0,
+ false, false, 0);
// Load the actual argument out of the pointer VAList
- Results.push_back(DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0));
+ Results.push_back(DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0,
+ false, false, 0));
Results.push_back(Results[0].getValue(1));
break;
}
@@ -2369,8 +2409,9 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue();
const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue();
Tmp1 = DAG.getLoad(TLI.getPointerTy(), dl, Node->getOperand(0),
- Node->getOperand(2), VS, 0);
- Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), VD, 0);
+ Node->getOperand(2), VS, 0, false, false, 0);
+ Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), VD, 0,
+ false, false, 0);
Results.push_back(Tmp1);
break;
}
@@ -2767,7 +2808,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
DAG.getIntPtrConstant(1));
} else {
// FIXME: We should be able to fall back to a libcall with an illegal
- // type in some cases cases.
+ // type in some cases.
// Also, we can fall back to a division in some cases, but that's a big
// performance hit in the general case.
llvm_unreachable("Don't know how to expand this operation yet!");
@@ -2816,15 +2857,19 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
SDValue Index = Node->getOperand(2);
EVT PTy = TLI.getPointerTy();
- MachineFunction &MF = DAG.getMachineFunction();
- unsigned EntrySize = MF.getJumpTableInfo()->getEntrySize();
- Index= DAG.getNode(ISD::MUL, dl, PTy,
+
+ const TargetData &TD = *TLI.getTargetData();
+ unsigned EntrySize =
+ DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD);
+
+ Index = DAG.getNode(ISD::MUL, dl, PTy,
Index, DAG.getConstant(EntrySize, PTy));
SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table);
EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), EntrySize * 8);
SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, dl, PTy, Chain, Addr,
- PseudoSourceValue::getJumpTable(), 0, MemVT);
+ PseudoSourceValue::getJumpTable(), 0, MemVT,
+ false, false, 0);
Addr = LD;
if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) {
// For PIC, the sequence is:
diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 4f0fce7..35a7c7c 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -444,7 +444,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
NewL = DAG.getLoad(L->getAddressingMode(), dl, L->getExtensionType(),
NVT, L->getChain(), L->getBasePtr(), L->getOffset(),
L->getSrcValue(), L->getSrcValueOffset(), NVT,
- L->isVolatile(), L->getAlignment());
+ L->isVolatile(), L->isNonTemporal(), L->getAlignment());
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
@@ -456,8 +456,8 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
L->getMemoryVT(), L->getChain(),
L->getBasePtr(), L->getOffset(),
L->getSrcValue(), L->getSrcValueOffset(),
- L->getMemoryVT(),
- L->isVolatile(), L->getAlignment());
+ L->getMemoryVT(), L->isVolatile(),
+ L->isNonTemporal(), L->getAlignment());
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
@@ -755,7 +755,8 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) {
return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(),
ST->getSrcValue(), ST->getSrcValueOffset(),
- ST->isVolatile(), ST->getAlignment());
+ ST->isVolatile(), ST->isNonTemporal(),
+ ST->getAlignment());
}
@@ -1073,8 +1074,8 @@ void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr,
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->getMemoryVT(),
- LD->isVolatile(), LD->getAlignment());
+ LD->getMemoryVT(), LD->isVolatile(),
+ LD->isNonTemporal(), LD->getAlignment());
// Remember the chain.
Chain = Hi.getValue(1);
@@ -1382,6 +1383,6 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
return DAG.getTruncStore(Chain, N->getDebugLoc(), Hi, Ptr,
ST->getSrcValue(), ST->getSrcValueOffset(),
- ST->getMemoryVT(),
- ST->isVolatile(), ST->getAlignment());
+ ST->getMemoryVT(), ST->isVolatile(),
+ ST->isNonTemporal(), ST->getAlignment());
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 9932cf4..e4d123f 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -359,7 +359,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(),
N->getSrcValue(), N->getSrcValueOffset(),
N->getMemoryVT(), N->isVolatile(),
- N->getAlignment());
+ N->isNonTemporal(), N->getAlignment());
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
@@ -873,6 +873,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment();
bool isVolatile = N->isVolatile();
+ bool isNonTemporal = N->isNonTemporal();
DebugLoc dl = N->getDebugLoc();
SDValue Val = GetPromotedInteger(N->getValue()); // Get promoted value.
@@ -880,7 +881,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
// Truncate the value and store the result.
return DAG.getTruncStore(Ch, dl, Val, Ptr, N->getSrcValue(),
SVOffset, N->getMemoryVT(),
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
}
SDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
@@ -1500,6 +1501,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment();
bool isVolatile = N->isVolatile();
+ bool isNonTemporal = N->isNonTemporal();
DebugLoc dl = N->getDebugLoc();
assert(NVT.isByteSized() && "Expanded type not byte sized!");
@@ -1508,7 +1510,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
EVT MemVT = N->getMemoryVT();
Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
- MemVT, isVolatile, Alignment);
+ MemVT, isVolatile, isNonTemporal, Alignment);
// Remember the chain.
Ch = Lo.getValue(1);
@@ -1530,7 +1532,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
} else if (TLI.isLittleEndian()) {
// Little-endian - low bits are at low addresses.
Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getSrcValue(), SVOffset,
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
unsigned ExcessBits =
N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
@@ -1542,7 +1544,8 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
DAG.getIntPtrConstant(IncrementSize));
Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(),
SVOffset+IncrementSize, NEVT,
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
@@ -1560,7 +1563,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
EVT::getIntegerVT(*DAG.getContext(),
MemVT.getSizeInBits() - ExcessBits),
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
// Increment the pointer to the other half.
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
@@ -1569,7 +1572,8 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr, N->getSrcValue(),
SVOffset+IncrementSize,
EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
@@ -2212,6 +2216,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment();
bool isVolatile = N->isVolatile();
+ bool isNonTemporal = N->isNonTemporal();
DebugLoc dl = N->getDebugLoc();
SDValue Lo, Hi;
@@ -2220,13 +2225,14 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
if (N->getMemoryVT().bitsLE(NVT)) {
GetExpandedInteger(N->getValue(), Lo, Hi);
return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
- N->getMemoryVT(), isVolatile, Alignment);
+ N->getMemoryVT(), isVolatile, isNonTemporal,
+ Alignment);
} else if (TLI.isLittleEndian()) {
// Little-endian - low bits are at low addresses.
GetExpandedInteger(N->getValue(), Lo, Hi);
Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
unsigned ExcessBits =
N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
@@ -2238,7 +2244,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
DAG.getIntPtrConstant(IncrementSize));
Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(),
SVOffset+IncrementSize, NEVT,
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
} else {
// Big-endian - high bits are at low addresses. Favor aligned stores at
@@ -2264,7 +2271,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
// Store both the high bits and maybe some of the low bits.
Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(),
- SVOffset, HiVT, isVolatile, Alignment);
+ SVOffset, HiVT, isVolatile, isNonTemporal,
+ Alignment);
// Increment the pointer to the other half.
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
@@ -2273,7 +2281,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(),
SVOffset+IncrementSize,
EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
}
@@ -2341,7 +2350,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
// FIXME: Avoid the extend by constructing the right constant pool?
SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(),
FudgePtr, NULL, 0, MVT::f32,
- false, Alignment);
+ false, false, Alignment);
return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge);
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index 37f36a3..0d929f1 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -871,9 +871,10 @@ SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op,
// the source and destination types.
SDValue StackPtr = DAG.CreateStackTemporary(Op.getValueType(), DestVT);
// Emit a store to the stack slot.
- SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Op, StackPtr, NULL, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Op, StackPtr, NULL, 0,
+ false, false, 0);
// Result is a load from the stack slot.
- return DAG.getLoad(DestVT, dl, Store, StackPtr, NULL, 0);
+ return DAG.getLoad(DestVT, dl, Store, StackPtr, NULL, 0, false, false, 0);
}
/// CustomLowerNode - Replace the node's results with custom code provided
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index b5dbd41..b0af357 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -609,6 +609,7 @@ private:
SDValue WidenVecRes_SIGN_EXTEND_INREG(SDNode* N);
SDValue WidenVecRes_SELECT(SDNode* N);
SDValue WidenVecRes_SELECT_CC(SDNode* N);
+ SDValue WidenVecRes_SETCC(SDNode* N);
SDValue WidenVecRes_UNDEF(SDNode *N);
SDValue WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N);
SDValue WidenVecRes_VSETCC(SDNode* N);
@@ -633,43 +634,33 @@ private:
// Vector Widening Utilities Support: LegalizeVectorTypes.cpp
//===--------------------------------------------------------------------===//
- /// Helper genWidenVectorLoads - Helper function to generate a set of
+ /// Helper GenWidenVectorLoads - Helper function to generate a set of
/// loads to load a vector with a resulting wider type. It takes
- /// ExtType: Extension type
- /// LdChain: list of chains for the load we have generated.
- /// Chain: incoming chain for the ld vector.
- /// BasePtr: base pointer to load from.
- /// SV: memory disambiguation source value.
- /// SVOffset: memory disambiugation offset.
- /// Alignment: alignment of the memory.
- /// isVolatile: volatile load.
- /// LdWidth: width of memory that we want to load.
- /// ResType: the wider result result type for the resulting vector.
- /// dl: DebugLoc to be applied to new nodes
- SDValue GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain, SDValue Chain,
- SDValue BasePtr, const Value *SV,
- int SVOffset, unsigned Alignment,
- bool isVolatile, unsigned LdWidth,
- EVT ResType, DebugLoc dl);
+ /// LdChain: list of chains for the load to be generated.
+ /// Ld: load to widen
+ SDValue GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
+ LoadSDNode *LD);
+
+ /// GenWidenVectorExtLoads - Helper function to generate a set of extension
+ /// loads to load a ector with a resulting wider type. It takes
+ /// LdChain: list of chains for the load to be generated.
+ /// Ld: load to widen
+ /// ExtType: extension element type
+ SDValue GenWidenVectorExtLoads(SmallVector<SDValue, 16>& LdChain,
+ LoadSDNode *LD, ISD::LoadExtType ExtType);
/// Helper genWidenVectorStores - Helper function to generate a set of
/// stores to store a widen vector into non widen memory
- /// It takes
/// StChain: list of chains for the stores we have generated
- /// Chain: incoming chain for the ld vector
- /// BasePtr: base pointer to load from
- /// SV: memory disambiguation source value
- /// SVOffset: memory disambiugation offset
- /// Alignment: alignment of the memory
- /// isVolatile: volatile lod
- /// ValOp: value to store
- /// StWidth: width of memory that we want to store
- /// dl: DebugLoc to be applied to new nodes
- void GenWidenVectorStores(SmallVector<SDValue, 16>& StChain, SDValue Chain,
- SDValue BasePtr, const Value *SV,
- int SVOffset, unsigned Alignment,
- bool isVolatile, SDValue ValOp,
- unsigned StWidth, DebugLoc dl);
+ /// ST: store of a widen value
+ void GenWidenVectorStores(SmallVector<SDValue, 16>& StChain, StoreSDNode *ST);
+
+ /// Helper genWidenVectorTruncStores - Helper function to generate a set of
+ /// stores to store a truncate widen vector into non widen memory
+ /// StChain: list of chains for the stores we have generated
+ /// ST: store of a widen value
+ void GenWidenVectorTruncStores(SmallVector<SDValue, 16>& StChain,
+ StoreSDNode *ST);
/// Modifies a vector input (widen or narrows) to a vector of NVT. The
/// input vector must have the same element type as NVT.
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
index a1b6ced..5e83b4b 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
@@ -122,10 +122,11 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
const Value *SV = PseudoSourceValue::getFixedStack(SPFI);
// Emit a store to the stack slot.
- SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, SV, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, SV, 0,
+ false, false, 0);
// Load the first half from the stack slot.
- Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, 0);
+ Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, 0, false, false, 0);
// Increment the pointer to the other half.
unsigned IncrementSize = NOutVT.getSizeInBits() / 8;
@@ -134,7 +135,7 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
// Load the second half from the stack slot.
Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, IncrementSize, false,
- MinAlign(Alignment, IncrementSize));
+ false, MinAlign(Alignment, IncrementSize));
// Handle endianness of the load.
if (TLI.isBigEndian())
@@ -205,11 +206,12 @@ void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
int SVOffset = LD->getSrcValueOffset();
unsigned Alignment = LD->getAlignment();
bool isVolatile = LD->isVolatile();
+ bool isNonTemporal = LD->isNonTemporal();
assert(NVT.isByteSized() && "Expanded type not byte sized!");
Lo = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset,
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
// Increment the pointer to the other half.
unsigned IncrementSize = NVT.getSizeInBits() / 8;
@@ -217,7 +219,8 @@ void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
DAG.getIntPtrConstant(IncrementSize));
Hi = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(),
SVOffset+IncrementSize,
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
// Build a factor node to remember that this load is independent of the
// other one.
@@ -383,6 +386,7 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
int SVOffset = St->getSrcValueOffset();
unsigned Alignment = St->getAlignment();
bool isVolatile = St->isVolatile();
+ bool isNonTemporal = St->isNonTemporal();
assert(NVT.isByteSized() && "Expanded type not byte sized!");
unsigned IncrementSize = NVT.getSizeInBits() / 8;
@@ -394,14 +398,15 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
std::swap(Lo, Hi);
Lo = DAG.getStore(Chain, dl, Lo, Ptr, St->getSrcValue(), SVOffset,
- isVolatile, Alignment);
+ isVolatile, isNonTemporal, Alignment);
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
Hi = DAG.getStore(Chain, dl, Hi, Ptr, St->getSrcValue(),
SVOffset + IncrementSize,
- isVolatile, MinAlign(Alignment, IncrementSize));
+ isVolatile, isNonTemporal,
+ MinAlign(Alignment, IncrementSize));
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 808bac7..8363c3a 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -172,7 +172,8 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
DAG.getUNDEF(N->getBasePtr().getValueType()),
N->getSrcValue(), N->getSrcValueOffset(),
N->getMemoryVT().getVectorElementType(),
- N->isVolatile(), N->getOriginalAlignment());
+ N->isVolatile(), N->isNonTemporal(),
+ N->getOriginalAlignment());
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
@@ -366,11 +367,13 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){
N->getBasePtr(),
N->getSrcValue(), N->getSrcValueOffset(),
N->getMemoryVT().getVectorElementType(),
- N->isVolatile(), N->getAlignment());
+ N->isVolatile(), N->isNonTemporal(),
+ N->getAlignment());
return DAG.getStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)),
N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(),
- N->isVolatile(), N->getOriginalAlignment());
+ N->isVolatile(), N->isNonTemporal(),
+ N->getOriginalAlignment());
}
@@ -696,17 +699,20 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
EVT VecVT = Vec.getValueType();
EVT EltVT = VecVT.getVectorElementType();
SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
- SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0,
+ false, false, 0);
// Store the new element. This may be larger than the vector element type,
// so use a truncating store.
SDValue EltPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
unsigned Alignment =
TLI.getTargetData()->getPrefTypeAlignment(VecVT.getTypeForEVT(*DAG.getContext()));
- Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, NULL, 0, EltVT);
+ Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, NULL, 0, EltVT,
+ false, false, 0);
// Load the Lo part from the stack slot.
- Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, NULL, 0);
+ Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, NULL, 0,
+ false, false, 0);
// Increment the pointer to the other part.
unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8;
@@ -715,7 +721,7 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
// Load the Hi part from the stack slot.
Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, NULL, 0, false,
- MinAlign(Alignment, IncrementSize));
+ false, MinAlign(Alignment, IncrementSize));
}
void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo,
@@ -743,19 +749,20 @@ void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
EVT MemoryVT = LD->getMemoryVT();
unsigned Alignment = LD->getOriginalAlignment();
bool isVolatile = LD->isVolatile();
+ bool isNonTemporal = LD->isNonTemporal();
EVT LoMemVT, HiMemVT;
GetSplitDestVTs(MemoryVT, LoMemVT, HiMemVT);
Lo = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, LoVT, Ch, Ptr, Offset,
- SV, SVOffset, LoMemVT, isVolatile, Alignment);
+ SV, SVOffset, LoMemVT, isVolatile, isNonTemporal, Alignment);
unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getIntPtrConstant(IncrementSize));
SVOffset += IncrementSize;
Hi = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, HiVT, Ch, Ptr, Offset,
- SV, SVOffset, HiMemVT, isVolatile, Alignment);
+ SV, SVOffset, HiMemVT, isVolatile, isNonTemporal, Alignment);
// Build a factor node to remember that this load is independent of the
// other one.
@@ -1086,12 +1093,13 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
const Value *SV = PseudoSourceValue::getFixedStack(SPFI);
- SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, SV, 0);
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, SV, 0,
+ false, false, 0);
// Load back the required element.
StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
return DAG.getExtLoad(ISD::EXTLOAD, dl, N->getValueType(0), Store, StackPtr,
- SV, 0, EltVT);
+ SV, 0, EltVT, false, false, 0);
}
SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
@@ -1106,6 +1114,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
EVT MemoryVT = N->getMemoryVT();
unsigned Alignment = N->getOriginalAlignment();
bool isVol = N->isVolatile();
+ bool isNT = N->isNonTemporal();
SDValue Lo, Hi;
GetSplitVector(N->getOperand(1), Lo, Hi);
@@ -1116,10 +1125,10 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
if (isTruncating)
Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
- LoMemVT, isVol, Alignment);
+ LoMemVT, isVol, isNT, Alignment);
else
Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
- isVol, Alignment);
+ isVol, isNT, Alignment);
// Increment the pointer to the other half.
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
@@ -1128,10 +1137,10 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
if (isTruncating)
Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset,
- HiMemVT, isVol, Alignment);
+ HiMemVT, isVol, isNT, Alignment);
else
Hi = DAG.getStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset,
- isVol, Alignment);
+ isVol, isNT, Alignment);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
}
@@ -1172,6 +1181,7 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
case ISD::SIGN_EXTEND_INREG: Res = WidenVecRes_InregOp(N); break;
case ISD::SELECT: Res = WidenVecRes_SELECT(N); break;
case ISD::SELECT_CC: Res = WidenVecRes_SELECT_CC(N); break;
+ case ISD::SETCC: Res = WidenVecRes_SETCC(N); break;
case ISD::UNDEF: Res = WidenVecRes_UNDEF(N); break;
case ISD::VECTOR_SHUFFLE:
Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N));
@@ -1241,10 +1251,96 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) {
// Binary op widening.
+ unsigned Opcode = N->getOpcode();
+ DebugLoc dl = N->getDebugLoc();
EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
- SDValue InOp1 = GetWidenedVector(N->getOperand(0));
- SDValue InOp2 = GetWidenedVector(N->getOperand(1));
- return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp1, InOp2);
+ EVT WidenEltVT = WidenVT.getVectorElementType();
+ EVT VT = WidenVT;
+ unsigned NumElts = VT.getVectorNumElements();
+ while (!TLI.isTypeLegal(VT) && NumElts != 1) {
+ NumElts = NumElts / 2;
+ VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
+ }
+
+ if (NumElts != 1 && !TLI.canOpTrap(N->getOpcode(), VT)) {
+ // Operation doesn't trap so just widen as normal.
+ SDValue InOp1 = GetWidenedVector(N->getOperand(0));
+ SDValue InOp2 = GetWidenedVector(N->getOperand(1));
+ return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2);
+ } else if (NumElts == 1) {
+ // No legal vector version so unroll the vector operation and then widen.
+ return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements());
+ } else {
+ // Since the operation can trap, apply operation on the original vector.
+ SDValue InOp1 = GetWidenedVector(N->getOperand(0));
+ SDValue InOp2 = GetWidenedVector(N->getOperand(1));
+ unsigned CurNumElts = N->getValueType(0).getVectorNumElements();
+
+ SmallVector<SDValue, 16> ConcatOps(CurNumElts);
+ unsigned ConcatEnd = 0; // Current ConcatOps index.
+ unsigned Idx = 0; // Current Idx into input vectors.
+ while (CurNumElts != 0) {
+ while (CurNumElts >= NumElts) {
+ SDValue EOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp1,
+ DAG.getIntPtrConstant(Idx));
+ SDValue EOp2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp2,
+ DAG.getIntPtrConstant(Idx));
+ ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2);
+ Idx += NumElts;
+ CurNumElts -= NumElts;
+ }
+ EVT PrevVecVT = VT;
+ do {
+ NumElts = NumElts / 2;
+ VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
+ } while (!TLI.isTypeLegal(VT) && NumElts != 1);
+
+ if (NumElts == 1) {
+ // Since we are using concat vector, build a vector from the scalar ops.
+ SDValue VecOp = DAG.getUNDEF(PrevVecVT);
+ for (unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
+ SDValue EOp1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT,
+ InOp1, DAG.getIntPtrConstant(Idx));
+ SDValue EOp2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT,
+ InOp2, DAG.getIntPtrConstant(Idx));
+ VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, PrevVecVT, VecOp,
+ DAG.getNode(Opcode, dl, WidenEltVT, EOp1, EOp2),
+ DAG.getIntPtrConstant(i));
+ }
+ CurNumElts = 0;
+ ConcatOps[ConcatEnd++] = VecOp;
+ }
+ }
+
+ // Check to see if we have a single operation with the widen type.
+ if (ConcatEnd == 1) {
+ VT = ConcatOps[0].getValueType();
+ if (VT == WidenVT)
+ return ConcatOps[0];
+ }
+
+ // Rebuild vector to one with the widen type
+ Idx = ConcatEnd - 1;
+ while (Idx != 0) {
+ VT = ConcatOps[Idx--].getValueType();
+ while (Idx != 0 && ConcatOps[Idx].getValueType() == VT)
+ --Idx;
+ if (Idx != 0) {
+ VT = ConcatOps[Idx].getValueType();
+ ConcatOps[Idx+1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT,
+ &ConcatOps[Idx+1], ConcatEnd - Idx - 1);
+ ConcatEnd = Idx + 2;
+ }
+ }
+
+ unsigned NumOps = WidenVT.getVectorNumElements()/VT.getVectorNumElements();
+ if (NumOps != ConcatEnd ) {
+ SDValue UndefVal = DAG.getUNDEF(VT);
+ for (unsigned j = ConcatEnd; j < NumOps; ++j)
+ ConcatOps[j] = UndefVal;
+ }
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &ConcatOps[0], NumOps);
+ }
}
SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
@@ -1655,68 +1751,24 @@ SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
LoadSDNode *LD = cast<LoadSDNode>(N);
- EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0));
- EVT LdVT = LD->getMemoryVT();
- DebugLoc dl = N->getDebugLoc();
- assert(LdVT.isVector() && WidenVT.isVector());
-
- // Load information
- SDValue Chain = LD->getChain();
- SDValue BasePtr = LD->getBasePtr();
- int SVOffset = LD->getSrcValueOffset();
- unsigned Align = LD->getAlignment();
- bool isVolatile = LD->isVolatile();
- const Value *SV = LD->getSrcValue();
ISD::LoadExtType ExtType = LD->getExtensionType();
SDValue Result;
SmallVector<SDValue, 16> LdChain; // Chain for the series of load
- if (ExtType != ISD::NON_EXTLOAD) {
- // For extension loads, we can not play the tricks of chopping legal
- // vector types and bit cast it to the right type. Instead, we unroll
- // the load and build a vector.
- EVT EltVT = WidenVT.getVectorElementType();
- EVT LdEltVT = LdVT.getVectorElementType();
- unsigned NumElts = LdVT.getVectorNumElements();
-
- // Load each element and widen
- unsigned WidenNumElts = WidenVT.getVectorNumElements();
- SmallVector<SDValue, 16> Ops(WidenNumElts);
- unsigned Increment = LdEltVT.getSizeInBits() / 8;
- Ops[0] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, SV, SVOffset,
- LdEltVT, isVolatile, Align);
- LdChain.push_back(Ops[0].getValue(1));
- unsigned i = 0, Offset = Increment;
- for (i=1; i < NumElts; ++i, Offset += Increment) {
- SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
- BasePtr, DAG.getIntPtrConstant(Offset));
- Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr, SV,
- SVOffset + Offset, LdEltVT, isVolatile, Align);
- LdChain.push_back(Ops[i].getValue(1));
- }
-
- // Fill the rest with undefs
- SDValue UndefVal = DAG.getUNDEF(EltVT);
- for (; i != WidenNumElts; ++i)
- Ops[i] = UndefVal;
-
- Result = DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], Ops.size());
- } else {
- assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType());
- unsigned int LdWidth = LdVT.getSizeInBits();
- Result = GenWidenVectorLoads(LdChain, Chain, BasePtr, SV, SVOffset,
- Align, isVolatile, LdWidth, WidenVT, dl);
- }
-
- // If we generate a single load, we can use that for the chain. Otherwise,
- // build a factor node to remember the multiple loads are independent and
- // chain to that.
- SDValue NewChain;
- if (LdChain.size() == 1)
- NewChain = LdChain[0];
- else
- NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LdChain[0],
- LdChain.size());
+ if (ExtType != ISD::NON_EXTLOAD)
+ Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
+ else
+ Result = GenWidenVectorLoads(LdChain, LD);
+
+ // If we generate a single load, we can use that for the chain. Otherwise,
+ // build a factor node to remember the multiple loads are independent and
+ // chain to that.
+ SDValue NewChain;
+ if (LdChain.size() == 1)
+ NewChain = LdChain[0];
+ else
+ NewChain = DAG.getNode(ISD::TokenFactor, LD->getDebugLoc(), MVT::Other,
+ &LdChain[0], LdChain.size());
// Modified the chain - switch anything that used the old chain to use
// the new one.
@@ -1762,6 +1814,14 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) {
N->getOperand(1), InOp1, InOp2, N->getOperand(4));
}
+SDValue DAGTypeLegalizer::WidenVecRes_SETCC(SDNode *N) {
+ EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
+ SDValue InOp1 = GetWidenedVector(N->getOperand(0));
+ SDValue InOp2 = GetWidenedVector(N->getOperand(1));
+ return DAG.getNode(ISD::SETCC, N->getDebugLoc(), WidenVT,
+ InOp1, InOp2, N->getOperand(2));
+}
+
SDValue DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode *N) {
EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
return DAG.getUNDEF(WidenVT);
@@ -1954,57 +2014,17 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
// We have to widen the value but we want only to store the original
// vector type.
StoreSDNode *ST = cast<StoreSDNode>(N);
- SDValue Chain = ST->getChain();
- SDValue BasePtr = ST->getBasePtr();
- const Value *SV = ST->getSrcValue();
- int SVOffset = ST->getSrcValueOffset();
- unsigned Align = ST->getAlignment();
- bool isVolatile = ST->isVolatile();
- SDValue ValOp = GetWidenedVector(ST->getValue());
- DebugLoc dl = N->getDebugLoc();
-
- EVT StVT = ST->getMemoryVT();
- EVT ValVT = ValOp.getValueType();
- // It must be true that we the widen vector type is bigger than where
- // we need to store.
- assert(StVT.isVector() && ValOp.getValueType().isVector());
- assert(StVT.bitsLT(ValOp.getValueType()));
SmallVector<SDValue, 16> StChain;
- if (ST->isTruncatingStore()) {
- // For truncating stores, we can not play the tricks of chopping legal
- // vector types and bit cast it to the right type. Instead, we unroll
- // the store.
- EVT StEltVT = StVT.getVectorElementType();
- EVT ValEltVT = ValVT.getVectorElementType();
- unsigned Increment = ValEltVT.getSizeInBits() / 8;
- unsigned NumElts = StVT.getVectorNumElements();
- SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp,
- DAG.getIntPtrConstant(0));
- StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr, SV,
- SVOffset, StEltVT,
- isVolatile, Align));
- unsigned Offset = Increment;
- for (unsigned i=1; i < NumElts; ++i, Offset += Increment) {
- SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
- BasePtr, DAG.getIntPtrConstant(Offset));
- SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp,
- DAG.getIntPtrConstant(0));
- StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, NewBasePtr, SV,
- SVOffset + Offset, StEltVT,
- isVolatile, MinAlign(Align, Offset)));
- }
- }
- else {
- assert(StVT.getVectorElementType() == ValVT.getVectorElementType());
- // Store value
- GenWidenVectorStores(StChain, Chain, BasePtr, SV, SVOffset,
- Align, isVolatile, ValOp, StVT.getSizeInBits(), dl);
- }
+ if (ST->isTruncatingStore())
+ GenWidenVectorTruncStores(StChain, ST);
+ else
+ GenWidenVectorStores(StChain, ST);
+
if (StChain.size() == 1)
return StChain[0];
else
- return DAG.getNode(ISD::TokenFactor, dl,
+ return DAG.getNode(ISD::TokenFactor, ST->getDebugLoc(),
MVT::Other,&StChain[0],StChain.size());
}
@@ -2012,179 +2032,390 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
// Vector Widening Utilities
//===----------------------------------------------------------------------===//
+// Utility function to find the type to chop up a widen vector for load/store
+// TLI: Target lowering used to determine legal types.
+// Width: Width left need to load/store.
+// WidenVT: The widen vector type to load to/store from
+// Align: If 0, don't allow use of a wider type
+// WidenEx: If Align is not 0, the amount additional we can load/store from.
+
+static EVT FindMemType(SelectionDAG& DAG, const TargetLowering &TLI,
+ unsigned Width, EVT WidenVT,
+ unsigned Align = 0, unsigned WidenEx = 0) {
+ EVT WidenEltVT = WidenVT.getVectorElementType();
+ unsigned WidenWidth = WidenVT.getSizeInBits();
+ unsigned WidenEltWidth = WidenEltVT.getSizeInBits();
+ unsigned AlignInBits = Align*8;
+
+ // If we have one element to load/store, return it.
+ EVT RetVT = WidenEltVT;
+ if (Width == WidenEltWidth)
+ return RetVT;
+
+ // See if there is larger legal integer than the element type to load/store
+ unsigned VT;
+ for (VT = (unsigned)MVT::LAST_INTEGER_VALUETYPE;
+ VT >= (unsigned)MVT::FIRST_INTEGER_VALUETYPE; --VT) {
+ EVT MemVT((MVT::SimpleValueType) VT);
+ unsigned MemVTWidth = MemVT.getSizeInBits();
+ if (MemVT.getSizeInBits() <= WidenEltWidth)
+ break;
+ if (TLI.isTypeLegal(MemVT) && (WidenWidth % MemVTWidth) == 0 &&
+ (MemVTWidth <= Width ||
+ (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
+ RetVT = MemVT;
+ break;
+ }
+ }
-// Utility function to find a vector type and its associated element
-// type from a preferred width and whose vector type must be the same size
-// as the VecVT.
-// TLI: Target lowering used to determine legal types.
-// Width: Preferred width to store.
-// VecVT: Vector value type whose size we must match.
-// Returns NewVecVT and NewEltVT - the vector type and its associated
-// element type.
-static void FindAssocWidenVecType(SelectionDAG& DAG,
- const TargetLowering &TLI, unsigned Width,
- EVT VecVT,
- EVT& NewEltVT, EVT& NewVecVT) {
- unsigned EltWidth = Width + 1;
- if (TLI.isTypeLegal(VecVT)) {
- // We start with the preferred with, making it a power of 2 and find a
- // legal vector type of that width. If not, we reduce it by another of 2.
- // For incoming type is legal, this process will end as a vector of the
- // smallest loadable type should always be legal.
- do {
- assert(EltWidth > 0);
- EltWidth = 1 << Log2_32(EltWidth - 1);
- NewEltVT = EVT::getIntegerVT(*DAG.getContext(), EltWidth);
- unsigned NumElts = VecVT.getSizeInBits() / EltWidth;
- NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewEltVT, NumElts);
- } while (!TLI.isTypeLegal(NewVecVT) ||
- VecVT.getSizeInBits() != NewVecVT.getSizeInBits());
- } else {
- // The incoming vector type is illegal and is the result of widening
- // a vector to a power of 2. In this case, we will use the preferred
- // with as long as it is a multiple of the incoming vector length.
- // The legalization process will eventually make this into a legal type
- // and remove the illegal bit converts (which would turn to stack converts
- // if they are allow to exist).
- do {
- assert(EltWidth > 0);
- EltWidth = 1 << Log2_32(EltWidth - 1);
- NewEltVT = EVT::getIntegerVT(*DAG.getContext(), EltWidth);
- unsigned NumElts = VecVT.getSizeInBits() / EltWidth;
- NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewEltVT, NumElts);
- } while (!TLI.isTypeLegal(NewEltVT) ||
- VecVT.getSizeInBits() != NewVecVT.getSizeInBits());
+ // See if there is a larger vector type to load/store that has the same vector
+ // element type and is evenly divisible with the WidenVT.
+ for (VT = (unsigned)MVT::LAST_VECTOR_VALUETYPE;
+ VT >= (unsigned)MVT::FIRST_VECTOR_VALUETYPE; --VT) {
+ EVT MemVT = (MVT::SimpleValueType) VT;
+ unsigned MemVTWidth = MemVT.getSizeInBits();
+ if (TLI.isTypeLegal(MemVT) && WidenEltVT == MemVT.getVectorElementType() &&
+ (WidenWidth % MemVTWidth) == 0 &&
+ (MemVTWidth <= Width ||
+ (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
+ if (RetVT.getSizeInBits() < MemVTWidth || MemVT == WidenVT)
+ return MemVT;
+ }
}
+
+ return RetVT;
+}
+
+// Builds a vector type from scalar loads
+// VecTy: Resulting Vector type
+// LDOps: Load operators to build a vector type
+// [Start,End) the list of loads to use.
+static SDValue BuildVectorFromScalar(SelectionDAG& DAG, EVT VecTy,
+ SmallVector<SDValue, 16>& LdOps,
+ unsigned Start, unsigned End) {
+ DebugLoc dl = LdOps[Start].getDebugLoc();
+ EVT LdTy = LdOps[Start].getValueType();
+ unsigned Width = VecTy.getSizeInBits();
+ unsigned NumElts = Width / LdTy.getSizeInBits();
+ EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), LdTy, NumElts);
+
+ unsigned Idx = 1;
+ SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT,LdOps[Start]);
+
+ for (unsigned i = Start + 1; i != End; ++i) {
+ EVT NewLdTy = LdOps[i].getValueType();
+ if (NewLdTy != LdTy) {
+ NumElts = Width / NewLdTy.getSizeInBits();
+ NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewLdTy, NumElts);
+ VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp);
+ // Readjust position and vector position based on new load type
+ Idx = Idx * LdTy.getSizeInBits() / NewLdTy.getSizeInBits();
+ LdTy = NewLdTy;
+ }
+ VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOps[i],
+ DAG.getIntPtrConstant(Idx++));
+ }
+ return DAG.getNode(ISD::BIT_CONVERT, dl, VecTy, VecOp);
}
SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
- SDValue Chain,
- SDValue BasePtr,
- const Value *SV,
- int SVOffset,
- unsigned Alignment,
- bool isVolatile,
- unsigned LdWidth,
- EVT ResType,
- DebugLoc dl) {
+ LoadSDNode * LD) {
// The strategy assumes that we can efficiently load powers of two widths.
- // The routines chops the vector into the largest power of 2 load and
- // can be inserted into a legal vector and then cast the result into the
- // vector type we want. This avoids unnecessary stack converts.
+ // The routines chops the vector into the largest vector loads with the same
+ // element type or scalar loads and then recombines it to the widen vector
+ // type.
+ EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0));
+ unsigned WidenWidth = WidenVT.getSizeInBits();
+ EVT LdVT = LD->getMemoryVT();
+ DebugLoc dl = LD->getDebugLoc();
+ assert(LdVT.isVector() && WidenVT.isVector());
+ assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType());
- // TODO: If the Ldwidth is legal, alignment is the same as the LdWidth, and
- // the load is nonvolatile, we an use a wider load for the value.
+ // Load information
+ SDValue Chain = LD->getChain();
+ SDValue BasePtr = LD->getBasePtr();
+ int SVOffset = LD->getSrcValueOffset();
+ unsigned Align = LD->getAlignment();
+ bool isVolatile = LD->isVolatile();
+ bool isNonTemporal = LD->isNonTemporal();
+ const Value *SV = LD->getSrcValue();
+
+ int LdWidth = LdVT.getSizeInBits();
+ int WidthDiff = WidenWidth - LdWidth; // Difference
+ unsigned LdAlign = (isVolatile) ? 0 : Align; // Allow wider loads
// Find the vector type that can load from.
- EVT NewEltVT, NewVecVT;
- unsigned NewEltVTWidth;
- FindAssocWidenVecType(DAG, TLI, LdWidth, ResType, NewEltVT, NewVecVT);
- NewEltVTWidth = NewEltVT.getSizeInBits();
-
- SDValue LdOp = DAG.getLoad(NewEltVT, dl, Chain, BasePtr, SV, SVOffset,
- isVolatile, Alignment);
- SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
+ EVT NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff);
+ int NewVTWidth = NewVT.getSizeInBits();
+ SDValue LdOp = DAG.getLoad(NewVT, dl, Chain, BasePtr, SV, SVOffset,
+ isVolatile, isNonTemporal, Align);
LdChain.push_back(LdOp.getValue(1));
// Check if we can load the element with one instruction
- if (LdWidth == NewEltVTWidth) {
- return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp);
+ if (LdWidth <= NewVTWidth) {
+ if (NewVT.isVector()) {
+ if (NewVT != WidenVT) {
+ assert(WidenWidth % NewVTWidth == 0);
+ unsigned NumConcat = WidenWidth / NewVTWidth;
+ SmallVector<SDValue, 16> ConcatOps(NumConcat);
+ SDValue UndefVal = DAG.getUNDEF(NewVT);
+ ConcatOps[0] = LdOp;
+ for (unsigned i = 1; i != NumConcat; ++i)
+ ConcatOps[i] = UndefVal;
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &ConcatOps[0],
+ NumConcat);
+ } else
+ return LdOp;
+ } else {
+ unsigned NumElts = WidenWidth / LdWidth;
+ EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts);
+ SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, VecOp);
+ }
}
- unsigned Idx = 1;
- LdWidth -= NewEltVTWidth;
+ // Load vector by using multiple loads from largest vector to scalar
+ SmallVector<SDValue, 16> LdOps;
+ LdOps.push_back(LdOp);
+
+ LdWidth -= NewVTWidth;
unsigned Offset = 0;
while (LdWidth > 0) {
- unsigned Increment = NewEltVTWidth / 8;
+ unsigned Increment = NewVTWidth / 8;
Offset += Increment;
BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
DAG.getIntPtrConstant(Increment));
- if (LdWidth < NewEltVTWidth) {
- // Our current type we are using is too large, use a smaller size by
- // using a smaller power of 2
- unsigned oNewEltVTWidth = NewEltVTWidth;
- FindAssocWidenVecType(DAG, TLI, LdWidth, ResType, NewEltVT, NewVecVT);
- NewEltVTWidth = NewEltVT.getSizeInBits();
- // Readjust position and vector position based on new load type
- Idx = Idx * (oNewEltVTWidth/NewEltVTWidth);
- VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp);
+ if (LdWidth < NewVTWidth) {
+ // Our current type we are using is too large, find a better size
+ NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff);
+ NewVTWidth = NewVT.getSizeInBits();
}
- SDValue LdOp = DAG.getLoad(NewEltVT, dl, Chain, BasePtr, SV,
- SVOffset+Offset, isVolatile,
- MinAlign(Alignment, Offset));
+ SDValue LdOp = DAG.getLoad(NewVT, dl, Chain, BasePtr, SV,
+ SVOffset+Offset, isVolatile,
+ isNonTemporal, MinAlign(Align, Increment));
LdChain.push_back(LdOp.getValue(1));
- VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOp,
- DAG.getIntPtrConstant(Idx++));
+ LdOps.push_back(LdOp);
- LdWidth -= NewEltVTWidth;
+ LdWidth -= NewVTWidth;
}
- return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp);
-}
+ // Build the vector from the loads operations
+ unsigned End = LdOps.size();
+ if (LdOps[0].getValueType().isVector()) {
+ // If the load contains vectors, build the vector using concat vector.
+ // All of the vectors used to loads are power of 2 and the scalars load
+ // can be combined to make a power of 2 vector.
+ SmallVector<SDValue, 16> ConcatOps(End);
+ int i = End - 1;
+ int Idx = End;
+ EVT LdTy = LdOps[i].getValueType();
+ // First combine the scalar loads to a vector
+ if (!LdTy.isVector()) {
+ for (--i; i >= 0; --i) {
+ LdTy = LdOps[i].getValueType();
+ if (LdTy.isVector())
+ break;
+ }
+ ConcatOps[--Idx] = BuildVectorFromScalar(DAG, LdTy, LdOps, i+1, End);
+ }
+ ConcatOps[--Idx] = LdOps[i];
+ for (--i; i >= 0; --i) {
+ EVT NewLdTy = LdOps[i].getValueType();
+ if (NewLdTy != LdTy) {
+ // Create a larger vector
+ ConcatOps[End-1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewLdTy,
+ &ConcatOps[Idx], End - Idx);
+ Idx = End - 1;
+ LdTy = NewLdTy;
+ }
+ ConcatOps[--Idx] = LdOps[i];
+ }
-void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
- SDValue Chain,
- SDValue BasePtr,
- const Value *SV,
- int SVOffset,
- unsigned Alignment,
- bool isVolatile,
- SDValue ValOp,
- unsigned StWidth,
- DebugLoc dl) {
- // Breaks the stores into a series of power of 2 width stores. For any
- // width, we convert the vector to the vector of element size that we
- // want to store. This avoids requiring a stack convert.
-
- // Find a width of the element type we can store with
- EVT WidenVT = ValOp.getValueType();
- EVT NewEltVT, NewVecVT;
-
- FindAssocWidenVecType(DAG, TLI, StWidth, WidenVT, NewEltVT, NewVecVT);
- unsigned NewEltVTWidth = NewEltVT.getSizeInBits();
-
- SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, ValOp);
- SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, VecOp,
- DAG.getIntPtrConstant(0));
- SDValue StOp = DAG.getStore(Chain, dl, EOp, BasePtr, SV, SVOffset,
- isVolatile, Alignment);
- StChain.push_back(StOp);
+ if (WidenWidth != LdTy.getSizeInBits()*(End - Idx)) {
+ // We need to fill the rest with undefs to build the vector
+ unsigned NumOps = WidenWidth / LdTy.getSizeInBits();
+ SmallVector<SDValue, 16> WidenOps(NumOps);
+ SDValue UndefVal = DAG.getUNDEF(LdTy);
+ unsigned i = 0;
+ for (; i != End-Idx; ++i)
+ WidenOps[i] = ConcatOps[Idx+i];
+ for (; i != NumOps; ++i)
+ WidenOps[i] = UndefVal;
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &WidenOps[0],NumOps);
+ } else
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT,
+ &ConcatOps[Idx], End - Idx);
+ } else // All the loads are scalar loads.
+ return BuildVectorFromScalar(DAG, WidenVT, LdOps, 0, End);
+}
+
+SDValue
+DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVector<SDValue, 16>& LdChain,
+ LoadSDNode * LD,
+ ISD::LoadExtType ExtType) {
+ // For extension loads, it may not be more efficient to chop up the vector
+ // and then extended it. Instead, we unroll the load and build a new vector.
+ EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0));
+ EVT LdVT = LD->getMemoryVT();
+ DebugLoc dl = LD->getDebugLoc();
+ assert(LdVT.isVector() && WidenVT.isVector());
- // Check if we are done
- if (StWidth == NewEltVTWidth) {
- return;
+ // Load information
+ SDValue Chain = LD->getChain();
+ SDValue BasePtr = LD->getBasePtr();
+ int SVOffset = LD->getSrcValueOffset();
+ unsigned Align = LD->getAlignment();
+ bool isVolatile = LD->isVolatile();
+ bool isNonTemporal = LD->isNonTemporal();
+ const Value *SV = LD->getSrcValue();
+
+ EVT EltVT = WidenVT.getVectorElementType();
+ EVT LdEltVT = LdVT.getVectorElementType();
+ unsigned NumElts = LdVT.getVectorNumElements();
+
+ // Load each element and widen
+ unsigned WidenNumElts = WidenVT.getVectorNumElements();
+ SmallVector<SDValue, 16> Ops(WidenNumElts);
+ unsigned Increment = LdEltVT.getSizeInBits() / 8;
+ Ops[0] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, SV, SVOffset,
+ LdEltVT, isVolatile, isNonTemporal, Align);
+ LdChain.push_back(Ops[0].getValue(1));
+ unsigned i = 0, Offset = Increment;
+ for (i=1; i < NumElts; ++i, Offset += Increment) {
+ SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
+ BasePtr, DAG.getIntPtrConstant(Offset));
+ Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr, SV,
+ SVOffset + Offset, LdEltVT, isVolatile,
+ isNonTemporal, Align);
+ LdChain.push_back(Ops[i].getValue(1));
}
- unsigned Idx = 1;
- StWidth -= NewEltVTWidth;
- unsigned Offset = 0;
+ // Fill the rest with undefs
+ SDValue UndefVal = DAG.getUNDEF(EltVT);
+ for (; i != WidenNumElts; ++i)
+ Ops[i] = UndefVal;
- while (StWidth > 0) {
- unsigned Increment = NewEltVTWidth / 8;
- Offset += Increment;
- BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
- DAG.getIntPtrConstant(Increment));
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], Ops.size());
+}
- if (StWidth < NewEltVTWidth) {
- // Our current type we are using is too large, use a smaller size by
- // using a smaller power of 2
- unsigned oNewEltVTWidth = NewEltVTWidth;
- FindAssocWidenVecType(DAG, TLI, StWidth, WidenVT, NewEltVT, NewVecVT);
- NewEltVTWidth = NewEltVT.getSizeInBits();
- // Readjust position and vector position based on new load type
- Idx = Idx * (oNewEltVTWidth/NewEltVTWidth);
- VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp);
- }
- EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, VecOp,
+void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
+ StoreSDNode *ST) {
+ // The strategy assumes that we can efficiently store powers of two widths.
+ // The routines chops the vector into the largest vector stores with the same
+ // element type or scalar stores.
+ SDValue Chain = ST->getChain();
+ SDValue BasePtr = ST->getBasePtr();
+ const Value *SV = ST->getSrcValue();
+ int SVOffset = ST->getSrcValueOffset();
+ unsigned Align = ST->getAlignment();
+ bool isVolatile = ST->isVolatile();
+ bool isNonTemporal = ST->isNonTemporal();
+ SDValue ValOp = GetWidenedVector(ST->getValue());
+ DebugLoc dl = ST->getDebugLoc();
+
+ EVT StVT = ST->getMemoryVT();
+ unsigned StWidth = StVT.getSizeInBits();
+ EVT ValVT = ValOp.getValueType();
+ unsigned ValWidth = ValVT.getSizeInBits();
+ EVT ValEltVT = ValVT.getVectorElementType();
+ unsigned ValEltWidth = ValEltVT.getSizeInBits();
+ assert(StVT.getVectorElementType() == ValEltVT);
+
+ int Idx = 0; // current index to store
+ unsigned Offset = 0; // offset from base to store
+ while (StWidth != 0) {
+ // Find the largest vector type we can store with
+ EVT NewVT = FindMemType(DAG, TLI, StWidth, ValVT);
+ unsigned NewVTWidth = NewVT.getSizeInBits();
+ unsigned Increment = NewVTWidth / 8;
+ if (NewVT.isVector()) {
+ unsigned NumVTElts = NewVT.getVectorNumElements();
+ do {
+ SDValue EOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT, ValOp,
+ DAG.getIntPtrConstant(Idx));
+ StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV,
+ SVOffset + Offset, isVolatile,
+ isNonTemporal,
+ MinAlign(Align, Offset)));
+ StWidth -= NewVTWidth;
+ Offset += Increment;
+ Idx += NumVTElts;
+ BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
+ DAG.getIntPtrConstant(Increment));
+ } while (StWidth != 0 && StWidth >= NewVTWidth);
+ } else {
+ // Cast the vector to the scalar type we can store
+ unsigned NumElts = ValWidth / NewVTWidth;
+ EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts);
+ SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, ValOp);
+ // Readjust index position based on new vector type
+ Idx = Idx * ValEltWidth / NewVTWidth;
+ do {
+ SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, VecOp,
DAG.getIntPtrConstant(Idx++));
- StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV,
- SVOffset + Offset, isVolatile,
- MinAlign(Alignment, Offset)));
- StWidth -= NewEltVTWidth;
+ StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV,
+ SVOffset + Offset, isVolatile,
+ isNonTemporal, MinAlign(Align, Offset)));
+ StWidth -= NewVTWidth;
+ Offset += Increment;
+ BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
+ DAG.getIntPtrConstant(Increment));
+ } while (StWidth != 0 && StWidth >= NewVTWidth);
+ // Restore index back to be relative to the original widen element type
+ Idx = Idx * NewVTWidth / ValEltWidth;
+ }
+ }
+}
+
+void
+DAGTypeLegalizer::GenWidenVectorTruncStores(SmallVector<SDValue, 16>& StChain,
+ StoreSDNode *ST) {
+ // For extension loads, it may not be more efficient to truncate the vector
+ // and then store it. Instead, we extract each element and then store it.
+ SDValue Chain = ST->getChain();
+ SDValue BasePtr = ST->getBasePtr();
+ const Value *SV = ST->getSrcValue();
+ int SVOffset = ST->getSrcValueOffset();
+ unsigned Align = ST->getAlignment();
+ bool isVolatile = ST->isVolatile();
+ bool isNonTemporal = ST->isNonTemporal();
+ SDValue ValOp = GetWidenedVector(ST->getValue());
+ DebugLoc dl = ST->getDebugLoc();
+
+ EVT StVT = ST->getMemoryVT();
+ EVT ValVT = ValOp.getValueType();
+
+ // It must be true that we the widen vector type is bigger than where
+ // we need to store.
+ assert(StVT.isVector() && ValOp.getValueType().isVector());
+ assert(StVT.bitsLT(ValOp.getValueType()));
+
+ // For truncating stores, we can not play the tricks of chopping legal
+ // vector types and bit cast it to the right type. Instead, we unroll
+ // the store.
+ EVT StEltVT = StVT.getVectorElementType();
+ EVT ValEltVT = ValVT.getVectorElementType();
+ unsigned Increment = ValEltVT.getSizeInBits() / 8;
+ unsigned NumElts = StVT.getVectorNumElements();
+ SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp,
+ DAG.getIntPtrConstant(0));
+ StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr, SV,
+ SVOffset, StEltVT,
+ isVolatile, isNonTemporal, Align));
+ unsigned Offset = Increment;
+ for (unsigned i=1; i < NumElts; ++i, Offset += Increment) {
+ SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
+ BasePtr, DAG.getIntPtrConstant(Offset));
+ SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp,
+ DAG.getIntPtrConstant(0));
+ StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, NewBasePtr, SV,
+ SVOffset + Offset, StEltVT,
+ isVolatile, isNonTemporal,
+ MinAlign(Align, Offset)));
}
}
diff --git a/lib/CodeGen/SelectionDAG/Makefile b/lib/CodeGen/SelectionDAG/Makefile
index 4706e68..ea716fd 100644
--- a/lib/CodeGen/SelectionDAG/Makefile
+++ b/lib/CodeGen/SelectionDAG/Makefile
@@ -9,6 +9,5 @@
LEVEL = ../../..
LIBRARYNAME = LLVMSelectionDAG
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index dea5993..3f1766d 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -345,6 +345,15 @@ void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle,
++NumBacktracks;
}
+static bool isOperandOf(const SUnit *SU, SDNode *N) {
+ for (const SDNode *SUNode = SU->getNode(); SUNode;
+ SUNode = SUNode->getFlaggedNode()) {
+ if (SUNode->isOperandOf(N))
+ return true;
+ }
+ return false;
+}
+
/// CopyAndMoveSuccessors - Clone the specified node and move its scheduled
/// successors to the newly created node.
SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) {
@@ -427,8 +436,7 @@ SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) {
I != E; ++I) {
if (I->isCtrl())
ChainPreds.push_back(*I);
- else if (I->getSUnit()->getNode() &&
- I->getSUnit()->getNode()->isOperandOf(LoadNode))
+ else if (isOperandOf(I->getSUnit(), LoadNode))
LoadPreds.push_back(*I);
else
NodePreds.push_back(*I);
@@ -1034,9 +1042,9 @@ namespace {
// CopyToReg should be close to its uses to facilitate coalescing and
// avoid spilling.
return 0;
- if (Opc == TargetInstrInfo::EXTRACT_SUBREG ||
- Opc == TargetInstrInfo::SUBREG_TO_REG ||
- Opc == TargetInstrInfo::INSERT_SUBREG)
+ if (Opc == TargetOpcode::EXTRACT_SUBREG ||
+ Opc == TargetOpcode::SUBREG_TO_REG ||
+ Opc == TargetOpcode::INSERT_SUBREG)
// EXTRACT_SUBREG, INSERT_SUBREG, and SUBREG_TO_REG nodes should be
// close to their uses to facilitate coalescing.
return 0;
@@ -1437,7 +1445,7 @@ void RegReductionPriorityQueue<SF>::AddPseudoTwoAddrDeps() {
while (SuccSU->Succs.size() == 1 &&
SuccSU->getNode()->isMachineOpcode() &&
SuccSU->getNode()->getMachineOpcode() ==
- TargetInstrInfo::COPY_TO_REGCLASS)
+ TargetOpcode::COPY_TO_REGCLASS)
SuccSU = SuccSU->Succs.front().getSUnit();
// Don't constrain non-instruction nodes.
if (!SuccSU->getNode() || !SuccSU->getNode()->isMachineOpcode())
@@ -1451,9 +1459,9 @@ void RegReductionPriorityQueue<SF>::AddPseudoTwoAddrDeps() {
// Don't constrain EXTRACT_SUBREG, INSERT_SUBREG, and SUBREG_TO_REG;
// these may be coalesced away. We want them close to their uses.
unsigned SuccOpc = SuccSU->getNode()->getMachineOpcode();
- if (SuccOpc == TargetInstrInfo::EXTRACT_SUBREG ||
- SuccOpc == TargetInstrInfo::INSERT_SUBREG ||
- SuccOpc == TargetInstrInfo::SUBREG_TO_REG)
+ if (SuccOpc == TargetOpcode::EXTRACT_SUBREG ||
+ SuccOpc == TargetOpcode::INSERT_SUBREG ||
+ SuccOpc == TargetOpcode::SUBREG_TO_REG)
continue;
if ((!canClobber(SuccSU, DUSU) ||
(hasCopyToRegUse(SU) && !hasCopyToRegUse(SuccSU)) ||
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index f1b6f1e..43cf37e 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -829,6 +829,7 @@ void SelectionDAG::clear() {
EntryNode.UseList = 0;
AllNodes.push_back(&EntryNode);
Root = getEntryNode();
+ delete Ordering;
Ordering = new SDNodeOrdering();
}
@@ -1925,19 +1926,28 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, const APInt &Mask,
}
case ISD::SREM:
if (ConstantSDNode *Rem = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
- const APInt &RA = Rem->getAPIntValue();
- if (RA.isPowerOf2() || (-RA).isPowerOf2()) {
- APInt LowBits = RA.isStrictlyPositive() ? (RA - 1) : ~RA;
+ const APInt &RA = Rem->getAPIntValue().abs();
+ if (RA.isPowerOf2()) {
+ APInt LowBits = RA - 1;
APInt Mask2 = LowBits | APInt::getSignBit(BitWidth);
ComputeMaskedBits(Op.getOperand(0), Mask2,KnownZero2,KnownOne2,Depth+1);
- // If the sign bit of the first operand is zero, the sign bit of
- // the result is zero. If the first operand has no one bits below
- // the second operand's single 1 bit, its sign will be zero.
+ // The low bits of the first operand are unchanged by the srem.
+ KnownZero = KnownZero2 & LowBits;
+ KnownOne = KnownOne2 & LowBits;
+
+ // If the first operand is non-negative or has all low bits zero, then
+ // the upper bits are all zero.
if (KnownZero2[BitWidth-1] || ((KnownZero2 & LowBits) == LowBits))
- KnownZero2 |= ~LowBits;
+ KnownZero |= ~LowBits;
- KnownZero |= KnownZero2 & Mask;
+ // If the first operand is negative and not all low bits are zero, then
+ // the upper bits are all one.
+ if (KnownOne2[BitWidth-1] && ((KnownOne2 & LowBits) != 0))
+ KnownOne |= ~LowBits;
+
+ KnownZero &= Mask;
+ KnownOne &= Mask;
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
}
@@ -2755,13 +2765,16 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT,
// EXTRACT_VECTOR_ELT of INSERT_VECTOR_ELT is often formed when vector
// operations are lowered to scalars.
if (N1.getOpcode() == ISD::INSERT_VECTOR_ELT) {
- // If the indices are the same, return the inserted element.
- if (N1.getOperand(2) == N2)
- return N1.getOperand(1);
- // If the indices are known different, extract the element from
+ // If the indices are the same, return the inserted element else
+ // if the indices are known different, extract the element from
// the original vector.
- else if (isa<ConstantSDNode>(N1.getOperand(2)) &&
- isa<ConstantSDNode>(N2))
+ if (N1.getOperand(2) == N2) {
+ if (VT == N1.getOperand(1).getValueType())
+ return N1.getOperand(1);
+ else
+ return getSExtOrTrunc(N1.getOperand(1), DL, VT);
+ } else if (isa<ConstantSDNode>(N1.getOperand(2)) &&
+ isa<ConstantSDNode>(N2))
return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, N1.getOperand(0), N2);
}
break;
@@ -3287,7 +3300,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Value = getMemsetStringVal(VT, dl, DAG, TLI, Str, SrcOff);
Store = DAG.getStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, DstAlign);
+ DstSV, DstSVOff + DstOff, false, false, DstAlign);
} else {
// The type might not be legal for the target. This should only happen
// if the type is smaller than a legal type, as on PPC, so the right
@@ -3298,10 +3311,11 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
assert(NVT.bitsGE(VT));
Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain,
getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, VT, false, Align);
+ SrcSV, SrcSVOff + SrcOff, VT, false, false, Align);
Store = DAG.getTruncStore(Chain, dl, Value,
- getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, VT, false, DstAlign);
+ getMemBasePlusOffset(Dst, DstOff, DAG),
+ DstSV, DstSVOff + DstOff, VT, false, false,
+ DstAlign);
}
OutChains.push_back(Store);
SrcOff += VTSize;
@@ -3346,7 +3360,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Value = DAG.getLoad(VT, dl, Chain,
getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, false, Align);
+ SrcSV, SrcSVOff + SrcOff, false, false, Align);
LoadValues.push_back(Value);
LoadChains.push_back(Value.getValue(1));
SrcOff += VTSize;
@@ -3361,7 +3375,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Store = DAG.getStore(Chain, dl, LoadValues[i],
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, DstAlign);
+ DstSV, DstSVOff + DstOff, false, false, DstAlign);
OutChains.push_back(Store);
DstOff += VTSize;
}
@@ -3396,7 +3410,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Value = getMemsetValue(Src, VT, DAG, dl);
SDValue Store = DAG.getStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff);
+ DstSV, DstSVOff + DstOff, false, false, 0);
OutChains.push_back(Store);
DstOff += VTSize;
}
@@ -3776,7 +3790,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl,
ISD::LoadExtType ExtType, EVT VT, SDValue Chain,
SDValue Ptr, SDValue Offset,
const Value *SV, int SVOffset, EVT MemVT,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile, bool isNonTemporal,
+ unsigned Alignment) {
if (Alignment == 0) // Ensure that codegen never sees alignment 0
Alignment = getEVTAlignment(VT);
@@ -3790,6 +3805,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl,
unsigned Flags = MachineMemOperand::MOLoad;
if (isVolatile)
Flags |= MachineMemOperand::MOVolatile;
+ if (isNonTemporal)
+ Flags |= MachineMemOperand::MONonTemporal;
MachineMemOperand *MMO =
MF.getMachineMemOperand(SV, Flags, SVOffset,
MemVT.getStoreSize(), Alignment);
@@ -3844,20 +3861,22 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl,
SDValue SelectionDAG::getLoad(EVT VT, DebugLoc dl,
SDValue Chain, SDValue Ptr,
const Value *SV, int SVOffset,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile, bool isNonTemporal,
+ unsigned Alignment) {
SDValue Undef = getUNDEF(Ptr.getValueType());
return getLoad(ISD::UNINDEXED, dl, ISD::NON_EXTLOAD, VT, Chain, Ptr, Undef,
- SV, SVOffset, VT, isVolatile, Alignment);
+ SV, SVOffset, VT, isVolatile, isNonTemporal, Alignment);
}
SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT,
SDValue Chain, SDValue Ptr,
const Value *SV,
int SVOffset, EVT MemVT,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile, bool isNonTemporal,
+ unsigned Alignment) {
SDValue Undef = getUNDEF(Ptr.getValueType());
return getLoad(ISD::UNINDEXED, dl, ExtType, VT, Chain, Ptr, Undef,
- SV, SVOffset, MemVT, isVolatile, Alignment);
+ SV, SVOffset, MemVT, isVolatile, isNonTemporal, Alignment);
}
SDValue
@@ -3869,12 +3888,13 @@ SelectionDAG::getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
return getLoad(AM, dl, LD->getExtensionType(), OrigLoad.getValueType(),
LD->getChain(), Base, Offset, LD->getSrcValue(),
LD->getSrcValueOffset(), LD->getMemoryVT(),
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(), LD->getAlignment());
}
SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
SDValue Ptr, const Value *SV, int SVOffset,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile, bool isNonTemporal,
+ unsigned Alignment) {
if (Alignment == 0) // Ensure that codegen never sees alignment 0
Alignment = getEVTAlignment(Val.getValueType());
@@ -3888,6 +3908,8 @@ SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
unsigned Flags = MachineMemOperand::MOStore;
if (isVolatile)
Flags |= MachineMemOperand::MOVolatile;
+ if (isNonTemporal)
+ Flags |= MachineMemOperand::MONonTemporal;
MachineMemOperand *MMO =
MF.getMachineMemOperand(SV, Flags, SVOffset,
Val.getValueType().getStoreSize(), Alignment);
@@ -3920,7 +3942,8 @@ SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val,
SDValue Ptr, const Value *SV,
int SVOffset, EVT SVT,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile, bool isNonTemporal,
+ unsigned Alignment) {
if (Alignment == 0) // Ensure that codegen never sees alignment 0
Alignment = getEVTAlignment(SVT);
@@ -3934,6 +3957,8 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val,
unsigned Flags = MachineMemOperand::MOStore;
if (isVolatile)
Flags |= MachineMemOperand::MOVolatile;
+ if (isNonTemporal)
+ Flags |= MachineMemOperand::MONonTemporal;
MachineMemOperand *MMO =
MF.getMachineMemOperand(SV, Flags, SVOffset, SVT.getStoreSize(), Alignment);
@@ -4860,23 +4885,23 @@ SelectionDAG::getMachineNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
}
/// getTargetExtractSubreg - A convenience function for creating
-/// TargetInstrInfo::EXTRACT_SUBREG nodes.
+/// TargetOpcode::EXTRACT_SUBREG nodes.
SDValue
SelectionDAG::getTargetExtractSubreg(int SRIdx, DebugLoc DL, EVT VT,
SDValue Operand) {
SDValue SRIdxVal = getTargetConstant(SRIdx, MVT::i32);
- SDNode *Subreg = getMachineNode(TargetInstrInfo::EXTRACT_SUBREG, DL,
+ SDNode *Subreg = getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL,
VT, Operand, SRIdxVal);
return SDValue(Subreg, 0);
}
/// getTargetInsertSubreg - A convenience function for creating
-/// TargetInstrInfo::INSERT_SUBREG nodes.
+/// TargetOpcode::INSERT_SUBREG nodes.
SDValue
SelectionDAG::getTargetInsertSubreg(int SRIdx, DebugLoc DL, EVT VT,
SDValue Operand, SDValue Subreg) {
SDValue SRIdxVal = getTargetConstant(SRIdx, MVT::i32);
- SDNode *Result = getMachineNode(TargetInstrInfo::INSERT_SUBREG, DL,
+ SDNode *Result = getMachineNode(TargetOpcode::INSERT_SUBREG, DL,
VT, Operand, Subreg, SRIdxVal);
return SDValue(Result, 0);
}
@@ -5212,11 +5237,12 @@ unsigned SelectionDAG::AssignTopologicalOrder() {
}
}
if (I == SortedPos) {
- allnodes_iterator J = I;
- SDNode *S = ++J;
- dbgs() << "Offending node:\n";
+#ifndef NDEBUG
+ SDNode *S = ++I;
+ dbgs() << "Overran sorted position:\n";
S->dumprFull();
- assert(0 && "Overran sorted position");
+#endif
+ llvm_unreachable(0);
}
}
@@ -5237,7 +5263,7 @@ unsigned SelectionDAG::AssignTopologicalOrder() {
}
/// AssignOrdering - Assign an order to the SDNode.
-void SelectionDAG::AssignOrdering(SDNode *SD, unsigned Order) {
+void SelectionDAG::AssignOrdering(const SDNode *SD, unsigned Order) {
assert(SD && "Trying to assign an order to a null node!");
Ordering->add(SD, Order);
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 23c7059..85ecb95 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -131,6 +131,17 @@ namespace {
}
}
+ /// areValueTypesLegal - Return true if types of all the values are legal.
+ bool areValueTypesLegal() {
+ for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) {
+ EVT RegisterVT = RegVTs[Value];
+ if (!TLI->isTypeLegal(RegisterVT))
+ return false;
+ }
+ return true;
+ }
+
+
/// append - Add the specified values to this one.
void append(const RegsForValue &RHS) {
TLI = RHS.TLI;
@@ -176,7 +187,6 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
assert(NumParts > 0 && "No parts to assemble!");
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
SDValue Val = Parts[0];
- DAG.AssignOrdering(Val.getNode(), Order);
if (NumParts > 1) {
// Assemble the value from multiple parts.
@@ -209,10 +219,6 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
Val = DAG.getNode(ISD::BUILD_PAIR, dl, RoundVT, Lo, Hi);
- DAG.AssignOrdering(Lo.getNode(), Order);
- DAG.AssignOrdering(Hi.getNode(), Order);
- DAG.AssignOrdering(Val.getNode(), Order);
-
if (RoundParts < NumParts) {
// Assemble the trailing non-power-of-2 part.
unsigned OddParts = NumParts - RoundParts;
@@ -226,15 +232,11 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
std::swap(Lo, Hi);
EVT TotalVT = EVT::getIntegerVT(*DAG.getContext(), NumParts * PartBits);
Hi = DAG.getNode(ISD::ANY_EXTEND, dl, TotalVT, Hi);
- DAG.AssignOrdering(Hi.getNode(), Order);
Hi = DAG.getNode(ISD::SHL, dl, TotalVT, Hi,
DAG.getConstant(Lo.getValueType().getSizeInBits(),
TLI.getPointerTy()));
- DAG.AssignOrdering(Hi.getNode(), Order);
Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, TotalVT, Lo);
- DAG.AssignOrdering(Lo.getNode(), Order);
Val = DAG.getNode(ISD::OR, dl, TotalVT, Lo, Hi);
- DAG.AssignOrdering(Val.getNode(), Order);
}
} else if (ValueVT.isVector()) {
// Handle a multi-element vector.
@@ -275,7 +277,6 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
Val = DAG.getNode(IntermediateVT.isVector() ?
ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR, dl,
ValueVT, &Ops[0], NumIntermediates);
- DAG.AssignOrdering(Val.getNode(), Order);
} else if (PartVT.isFloatingPoint()) {
// FP split into multiple FP parts (for ppcf128)
assert(ValueVT == EVT(MVT::ppcf128) && PartVT == EVT(MVT::f64) &&
@@ -286,10 +287,6 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
if (TLI.isBigEndian())
std::swap(Lo, Hi);
Val = DAG.getNode(ISD::BUILD_PAIR, dl, ValueVT, Lo, Hi);
-
- DAG.AssignOrdering(Hi.getNode(), Order);
- DAG.AssignOrdering(Lo.getNode(), Order);
- DAG.AssignOrdering(Val.getNode(), Order);
} else {
// FP split into integer parts (soft fp)
assert(ValueVT.isFloatingPoint() && PartVT.isInteger() &&
@@ -307,18 +304,14 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
if (PartVT.isVector()) {
assert(ValueVT.isVector() && "Unknown vector conversion!");
- SDValue Res = DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val);
- DAG.AssignOrdering(Res.getNode(), Order);
- return Res;
+ return DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val);
}
if (ValueVT.isVector()) {
assert(ValueVT.getVectorElementType() == PartVT &&
ValueVT.getVectorNumElements() == 1 &&
"Only trivial scalar-to-vector conversions should get here!");
- SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, dl, ValueVT, Val);
- DAG.AssignOrdering(Res.getNode(), Order);
- return Res;
+ return DAG.getNode(ISD::BUILD_VECTOR, dl, ValueVT, Val);
}
if (PartVT.isInteger() &&
@@ -330,36 +323,24 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
if (AssertOp != ISD::DELETED_NODE)
Val = DAG.getNode(AssertOp, dl, PartVT, Val,
DAG.getValueType(ValueVT));
- DAG.AssignOrdering(Val.getNode(), Order);
- Val = DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val);
- DAG.AssignOrdering(Val.getNode(), Order);
- return Val;
+ return DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val);
} else {
- Val = DAG.getNode(ISD::ANY_EXTEND, dl, ValueVT, Val);
- DAG.AssignOrdering(Val.getNode(), Order);
- return Val;
+ return DAG.getNode(ISD::ANY_EXTEND, dl, ValueVT, Val);
}
}
if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) {
if (ValueVT.bitsLT(Val.getValueType())) {
// FP_ROUND's are always exact here.
- Val = DAG.getNode(ISD::FP_ROUND, dl, ValueVT, Val,
- DAG.getIntPtrConstant(1));
- DAG.AssignOrdering(Val.getNode(), Order);
- return Val;
+ return DAG.getNode(ISD::FP_ROUND, dl, ValueVT, Val,
+ DAG.getIntPtrConstant(1));
}
- Val = DAG.getNode(ISD::FP_EXTEND, dl, ValueVT, Val);
- DAG.AssignOrdering(Val.getNode(), Order);
- return Val;
+ return DAG.getNode(ISD::FP_EXTEND, dl, ValueVT, Val);
}
- if (PartVT.getSizeInBits() == ValueVT.getSizeInBits()) {
- Val = DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val);
- DAG.AssignOrdering(Val.getNode(), Order);
- return Val;
- }
+ if (PartVT.getSizeInBits() == ValueVT.getSizeInBits())
+ return DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val);
llvm_unreachable("Unknown mismatch!");
return SDValue();
@@ -414,8 +395,6 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
}
}
- DAG.AssignOrdering(Val.getNode(), Order);
-
// The value may have changed - recompute ValueVT.
ValueVT = Val.getValueType();
assert(NumParts * PartBits == ValueVT.getSizeInBits() &&
@@ -448,9 +427,6 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
NumParts = RoundParts;
ValueVT = EVT::getIntegerVT(*DAG.getContext(), NumParts * PartBits);
Val = DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val);
-
- DAG.AssignOrdering(OddVal.getNode(), Order);
- DAG.AssignOrdering(Val.getNode(), Order);
}
// The number of parts is a power of 2. Repeatedly bisect the value using
@@ -460,8 +436,6 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
ValueVT.getSizeInBits()),
Val);
- DAG.AssignOrdering(Parts[0].getNode(), Order);
-
for (unsigned StepSize = NumParts; StepSize > 1; StepSize /= 2) {
for (unsigned i = 0; i < NumParts; i += StepSize) {
unsigned ThisBits = StepSize * PartBits / 2;
@@ -476,16 +450,11 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
ThisVT, Part0,
DAG.getConstant(0, PtrVT));
- DAG.AssignOrdering(Part0.getNode(), Order);
- DAG.AssignOrdering(Part1.getNode(), Order);
-
if (ThisBits == PartBits && ThisVT != PartVT) {
Part0 = DAG.getNode(ISD::BIT_CONVERT, dl,
PartVT, Part0);
Part1 = DAG.getNode(ISD::BIT_CONVERT, dl,
PartVT, Part1);
- DAG.AssignOrdering(Part0.getNode(), Order);
- DAG.AssignOrdering(Part1.getNode(), Order);
}
}
}
@@ -511,7 +480,6 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
}
}
- DAG.AssignOrdering(Val.getNode(), Order);
Parts[0] = Val;
return;
}
@@ -539,8 +507,6 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
IntermediateVT, Val,
DAG.getConstant(i, PtrVT));
-
- DAG.AssignOrdering(Ops[i].getNode(), Order);
}
// Split the intermediate operands into legal parts.
@@ -638,23 +604,34 @@ SDValue SelectionDAGBuilder::getControlRoot() {
return Root;
}
+void SelectionDAGBuilder::AssignOrderingToNode(const SDNode *Node) {
+ if (DAG.GetOrdering(Node) != 0) return; // Already has ordering.
+ DAG.AssignOrdering(Node, SDNodeOrder);
+
+ for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I)
+ AssignOrderingToNode(Node->getOperand(I).getNode());
+}
+
void SelectionDAGBuilder::visit(Instruction &I) {
visit(I.getOpcode(), I);
}
void SelectionDAGBuilder::visit(unsigned Opcode, User &I) {
- // We're processing a new instruction.
- ++SDNodeOrder;
-
// Note: this doesn't use InstVisitor, because it has to work with
// ConstantExpr's in addition to instructions.
switch (Opcode) {
default: llvm_unreachable("Unknown instruction type encountered!");
// Build the switch statement using the Instruction.def file.
#define HANDLE_INST(NUM, OPCODE, CLASS) \
- case Instruction::OPCODE: return visit##OPCODE((CLASS&)I);
+ case Instruction::OPCODE: visit##OPCODE((CLASS&)I); break;
#include "llvm/Instruction.def"
}
+
+ // Assign the ordering to the freshly created DAG nodes.
+ if (NodeMap.count(&I)) {
+ ++SDNodeOrder;
+ AssignOrderingToNode(getValue(&I).getNode());
+ }
}
SDValue SelectionDAGBuilder::getValue(const Value *V) {
@@ -699,10 +676,8 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
Constants.push_back(SDValue(Val, i));
}
- SDValue Res = DAG.getMergeValues(&Constants[0], Constants.size(),
- getCurDebugLoc());
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- return Res;
+ return DAG.getMergeValues(&Constants[0], Constants.size(),
+ getCurDebugLoc());
}
if (isa<StructType>(C->getType()) || isa<ArrayType>(C->getType())) {
@@ -725,10 +700,8 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
Constants[i] = DAG.getConstant(0, EltVT);
}
- SDValue Res = DAG.getMergeValues(&Constants[0], NumElts,
- getCurDebugLoc());
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- return Res;
+ return DAG.getMergeValues(&Constants[0], NumElts,
+ getCurDebugLoc());
}
if (BlockAddress *BA = dyn_cast<BlockAddress>(C))
@@ -756,10 +729,8 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
}
// Create a BUILD_VECTOR node.
- SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
- VT, &Ops[0], Ops.size());
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- return NodeMap[V] = Res;
+ return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
+ VT, &Ops[0], Ops.size());
}
// If this is a static alloca, generate it as the frameindex instead of
@@ -873,16 +844,11 @@ void SelectionDAGBuilder::visitRet(ReturnInst &I) {
Chains[i] =
DAG.getStore(Chain, getCurDebugLoc(),
SDValue(RetOp.getNode(), RetOp.getResNo() + i),
- Add, NULL, Offsets[i], false, 0);
-
- DAG.AssignOrdering(Add.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Chains[i].getNode(), SDNodeOrder);
+ Add, NULL, Offsets[i], false, false, 0);
}
Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
MVT::Other, &Chains[0], NumValues);
-
- DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
} else {
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
SmallVector<EVT, 4> ValueVTs;
@@ -948,7 +914,6 @@ void SelectionDAGBuilder::visitRet(ReturnInst &I) {
// Update the DAG with the new chain value resulting from return lowering.
DAG.setRoot(Chain);
- DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
}
/// CopyToExportRegsIfNeeded - If the given value has virtual registers
@@ -1209,13 +1174,10 @@ void SelectionDAGBuilder::visitBr(BranchInst &I) {
CurMBB->addSuccessor(Succ0MBB);
// If this is not a fall-through branch, emit the branch.
- if (Succ0MBB != NextBlock) {
- SDValue V = DAG.getNode(ISD::BR, getCurDebugLoc(),
+ if (Succ0MBB != NextBlock)
+ DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(),
MVT::Other, getControlRoot(),
- DAG.getBasicBlock(Succ0MBB));
- DAG.setRoot(V);
- DAG.AssignOrdering(V.getNode(), SDNodeOrder);
- }
+ DAG.getBasicBlock(Succ0MBB)));
return;
}
@@ -1321,8 +1283,6 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB) {
}
}
- DAG.AssignOrdering(Cond.getNode(), SDNodeOrder);
-
// Update successor info
CurMBB->addSuccessor(CB.TrueBB);
CurMBB->addSuccessor(CB.FalseBB);
@@ -1340,13 +1300,11 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB) {
std::swap(CB.TrueBB, CB.FalseBB);
SDValue True = DAG.getConstant(1, Cond.getValueType());
Cond = DAG.getNode(ISD::XOR, dl, Cond.getValueType(), Cond, True);
- DAG.AssignOrdering(Cond.getNode(), SDNodeOrder);
}
SDValue BrCond = DAG.getNode(ISD::BRCOND, dl,
MVT::Other, getControlRoot(), Cond,
DAG.getBasicBlock(CB.TrueBB));
- DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
// If the branch was constant folded, fix up the CFG.
if (BrCond.getOpcode() == ISD::BR) {
@@ -1356,12 +1314,9 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB) {
if (BrCond == getControlRoot())
CurMBB->removeSuccessor(CB.TrueBB);
- if (CB.FalseBB != NextBlock) {
+ if (CB.FalseBB != NextBlock)
BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, BrCond,
DAG.getBasicBlock(CB.FalseBB));
-
- DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
- }
}
DAG.setRoot(BrCond);
@@ -1379,10 +1334,6 @@ void SelectionDAGBuilder::visitJumpTable(JumpTable &JT) {
MVT::Other, Index.getValue(1),
Table, Index);
DAG.setRoot(BrJumpTable);
-
- DAG.AssignOrdering(Index.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Table.getNode(), SDNodeOrder);
- DAG.AssignOrdering(BrJumpTable.getNode(), SDNodeOrder);
}
/// visitJumpTableHeader - This function emits necessary code to produce index
@@ -1398,7 +1349,7 @@ void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT,
DAG.getConstant(JTH.First, VT));
// The SDNode we just created, which holds the value being switched on minus
- // the the smallest case value, needs to be copied to a virtual register so it
+ // the smallest case value, needs to be copied to a virtual register so it
// can be used as an index into the jump table in a subsequent basic block.
// This value may be smaller or larger than the target's pointer type, and
// therefore require extension or truncating.
@@ -1417,11 +1368,6 @@ void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT,
DAG.getConstant(JTH.Last-JTH.First,VT),
ISD::SETUGT);
- DAG.AssignOrdering(Sub.getNode(), SDNodeOrder);
- DAG.AssignOrdering(SwitchOp.getNode(), SDNodeOrder);
- DAG.AssignOrdering(CopyTo.getNode(), SDNodeOrder);
- DAG.AssignOrdering(CMP.getNode(), SDNodeOrder);
-
// Set NextBlock to be the MBB immediately after the current one, if any.
// This is used to avoid emitting unnecessary branches to the next block.
MachineBasicBlock *NextBlock = 0;
@@ -1434,13 +1380,9 @@ void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT,
MVT::Other, CopyTo, CMP,
DAG.getBasicBlock(JT.Default));
- DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
-
- if (JT.MBB != NextBlock) {
+ if (JT.MBB != NextBlock)
BrCond = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrCond,
DAG.getBasicBlock(JT.MBB));
- DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
- }
DAG.setRoot(BrCond);
}
@@ -1467,11 +1409,6 @@ void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B) {
SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), getCurDebugLoc(),
B.Reg, ShiftOp);
- DAG.AssignOrdering(Sub.getNode(), SDNodeOrder);
- DAG.AssignOrdering(RangeCmp.getNode(), SDNodeOrder);
- DAG.AssignOrdering(ShiftOp.getNode(), SDNodeOrder);
- DAG.AssignOrdering(CopyTo.getNode(), SDNodeOrder);
-
// Set NextBlock to be the MBB immediately after the current one, if any.
// This is used to avoid emitting unnecessary branches to the next block.
MachineBasicBlock *NextBlock = 0;
@@ -1488,13 +1425,9 @@ void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B) {
MVT::Other, CopyTo, RangeCmp,
DAG.getBasicBlock(B.Default));
- DAG.AssignOrdering(BrRange.getNode(), SDNodeOrder);
-
- if (MBB != NextBlock) {
+ if (MBB != NextBlock)
BrRange = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, CopyTo,
DAG.getBasicBlock(MBB));
- DAG.AssignOrdering(BrRange.getNode(), SDNodeOrder);
- }
DAG.setRoot(BrRange);
}
@@ -1520,11 +1453,6 @@ void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB,
AndOp, DAG.getConstant(0, TLI.getPointerTy()),
ISD::SETNE);
- DAG.AssignOrdering(ShiftOp.getNode(), SDNodeOrder);
- DAG.AssignOrdering(SwitchVal.getNode(), SDNodeOrder);
- DAG.AssignOrdering(AndOp.getNode(), SDNodeOrder);
- DAG.AssignOrdering(AndCmp.getNode(), SDNodeOrder);
-
CurMBB->addSuccessor(B.TargetBB);
CurMBB->addSuccessor(NextMBB);
@@ -1532,8 +1460,6 @@ void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB,
MVT::Other, getControlRoot(),
AndCmp, DAG.getBasicBlock(B.TargetBB));
- DAG.AssignOrdering(BrAnd.getNode(), SDNodeOrder);
-
// Set NextBlock to be the MBB immediately after the current one, if any.
// This is used to avoid emitting unnecessary branches to the next block.
MachineBasicBlock *NextBlock = 0;
@@ -1541,11 +1467,9 @@ void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB,
if (++BBI != FuncInfo.MF->end())
NextBlock = BBI;
- if (NextMBB != NextBlock) {
+ if (NextMBB != NextBlock)
BrAnd = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrAnd,
DAG.getBasicBlock(NextMBB));
- DAG.AssignOrdering(BrAnd.getNode(), SDNodeOrder);
- }
DAG.setRoot(BrAnd);
}
@@ -1570,11 +1494,9 @@ void SelectionDAGBuilder::visitInvoke(InvokeInst &I) {
CurMBB->addSuccessor(LandingPad);
// Drop into normal successor.
- SDValue Branch = DAG.getNode(ISD::BR, getCurDebugLoc(),
- MVT::Other, getControlRoot(),
- DAG.getBasicBlock(Return));
- DAG.setRoot(Branch);
- DAG.AssignOrdering(Branch.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(),
+ MVT::Other, getControlRoot(),
+ DAG.getBasicBlock(Return)));
}
void SelectionDAGBuilder::visitUnwind(UnwindInst &I) {
@@ -1733,8 +1655,8 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR,
std::vector<MachineBasicBlock*> DestBBs;
APInt TEI = First;
for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++TEI) {
- const APInt& Low = cast<ConstantInt>(I->Low)->getValue();
- const APInt& High = cast<ConstantInt>(I->High)->getValue();
+ const APInt &Low = cast<ConstantInt>(I->Low)->getValue();
+ const APInt &High = cast<ConstantInt>(I->High)->getValue();
if (Low.sle(TEI) && TEI.sle(High)) {
DestBBs.push_back(I->BB);
@@ -1757,7 +1679,9 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR,
// Create a jump table index for this jump table, or return an existing
// one.
- unsigned JTI = CurMF->getJumpTableInfo()->getJumpTableIndex(DestBBs);
+ unsigned JTEncoding = TLI.getJumpTableEncoding();
+ unsigned JTI = CurMF->getOrCreateJumpTableInfo(JTEncoding)
+ ->getJumpTableIndex(DestBBs);
// Set the jump table information so that we can codegen it as a second
// MachineBasicBlock
@@ -2086,13 +2010,10 @@ void SelectionDAGBuilder::visitSwitch(SwitchInst &SI) {
// If this is not a fall-through branch, emit the branch.
CurMBB->addSuccessor(Default);
- if (Default != NextBlock) {
- SDValue Res = DAG.getNode(ISD::BR, getCurDebugLoc(),
- MVT::Other, getControlRoot(),
- DAG.getBasicBlock(Default));
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- }
+ if (Default != NextBlock)
+ DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(),
+ MVT::Other, getControlRoot(),
+ DAG.getBasicBlock(Default)));
return;
}
@@ -2141,15 +2062,19 @@ void SelectionDAGBuilder::visitSwitch(SwitchInst &SI) {
}
void SelectionDAGBuilder::visitIndirectBr(IndirectBrInst &I) {
- // Update machine-CFG edges.
+ // Update machine-CFG edges with unique successors.
+ SmallVector<BasicBlock*, 32> succs;
+ succs.reserve(I.getNumSuccessors());
for (unsigned i = 0, e = I.getNumSuccessors(); i != e; ++i)
- CurMBB->addSuccessor(FuncInfo.MBBMap[I.getSuccessor(i)]);
-
- SDValue Res = DAG.getNode(ISD::BRIND, getCurDebugLoc(),
- MVT::Other, getControlRoot(),
- getValue(I.getAddress()));
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ succs.push_back(I.getSuccessor(i));
+ array_pod_sort(succs.begin(), succs.end());
+ succs.erase(std::unique(succs.begin(), succs.end()), succs.end());
+ for (unsigned i = 0, e = succs.size(); i != e; ++i)
+ CurMBB->addSuccessor(FuncInfo.MBBMap[succs[i]]);
+
+ DAG.setRoot(DAG.getNode(ISD::BRIND, getCurDebugLoc(),
+ MVT::Other, getControlRoot(),
+ getValue(I.getAddress())));
}
void SelectionDAGBuilder::visitFSub(User &I) {
@@ -2164,10 +2089,8 @@ void SelectionDAGBuilder::visitFSub(User &I) {
Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size());
if (CV == CNZ) {
SDValue Op2 = getValue(I.getOperand(1));
- SDValue Res = DAG.getNode(ISD::FNEG, getCurDebugLoc(),
- Op2.getValueType(), Op2);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(),
+ Op2.getValueType(), Op2));
return;
}
}
@@ -2176,10 +2099,8 @@ void SelectionDAGBuilder::visitFSub(User &I) {
if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0)))
if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) {
SDValue Op2 = getValue(I.getOperand(1));
- SDValue Res = DAG.getNode(ISD::FNEG, getCurDebugLoc(),
- Op2.getValueType(), Op2);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(),
+ Op2.getValueType(), Op2));
return;
}
@@ -2189,10 +2110,8 @@ void SelectionDAGBuilder::visitFSub(User &I) {
void SelectionDAGBuilder::visitBinary(User &I, unsigned OpCode) {
SDValue Op1 = getValue(I.getOperand(0));
SDValue Op2 = getValue(I.getOperand(1));
- SDValue Res = DAG.getNode(OpCode, getCurDebugLoc(),
- Op1.getValueType(), Op1, Op2);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(OpCode, getCurDebugLoc(),
+ Op1.getValueType(), Op1, Op2));
}
void SelectionDAGBuilder::visitShift(User &I, unsigned Opcode) {
@@ -2225,12 +2144,8 @@ void SelectionDAGBuilder::visitShift(User &I, unsigned Opcode) {
TLI.getPointerTy(), Op2);
}
- SDValue Res = DAG.getNode(Opcode, getCurDebugLoc(),
- Op1.getValueType(), Op1, Op2);
- setValue(&I, Res);
- DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Op2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(Opcode, getCurDebugLoc(),
+ Op1.getValueType(), Op1, Op2));
}
void SelectionDAGBuilder::visitICmp(User &I) {
@@ -2244,9 +2159,7 @@ void SelectionDAGBuilder::visitICmp(User &I) {
ISD::CondCode Opcode = getICmpCondCode(predicate);
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Opcode);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Opcode));
}
void SelectionDAGBuilder::visitFCmp(User &I) {
@@ -2259,9 +2172,7 @@ void SelectionDAGBuilder::visitFCmp(User &I) {
SDValue Op2 = getValue(I.getOperand(1));
ISD::CondCode Condition = getFCmpCondCode(predicate);
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Condition);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Condition));
}
void SelectionDAGBuilder::visitSelect(User &I) {
@@ -2275,7 +2186,7 @@ void SelectionDAGBuilder::visitSelect(User &I) {
SDValue TrueVal = getValue(I.getOperand(1));
SDValue FalseVal = getValue(I.getOperand(2));
- for (unsigned i = 0; i != NumValues; ++i) {
+ for (unsigned i = 0; i != NumValues; ++i)
Values[i] = DAG.getNode(ISD::SELECT, getCurDebugLoc(),
TrueVal.getNode()->getValueType(i), Cond,
SDValue(TrueVal.getNode(),
@@ -2283,23 +2194,16 @@ void SelectionDAGBuilder::visitSelect(User &I) {
SDValue(FalseVal.getNode(),
FalseVal.getResNo() + i));
- DAG.AssignOrdering(Values[i].getNode(), SDNodeOrder);
- }
-
- SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
- DAG.getVTList(&ValueVTs[0], NumValues),
- &Values[0], NumValues);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
+ DAG.getVTList(&ValueVTs[0], NumValues),
+ &Values[0], NumValues));
}
void SelectionDAGBuilder::visitTrunc(User &I) {
// TruncInst cannot be a no-op cast because sizeof(src) > sizeof(dest).
SDValue N = getValue(I.getOperand(0));
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGBuilder::visitZExt(User &I) {
@@ -2307,9 +2211,7 @@ void SelectionDAGBuilder::visitZExt(User &I) {
// ZExt also can't be a cast to bool for same reason. So, nothing much to do
SDValue N = getValue(I.getOperand(0));
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGBuilder::visitSExt(User &I) {
@@ -2317,64 +2219,50 @@ void SelectionDAGBuilder::visitSExt(User &I) {
// SExt also can't be a cast to bool for same reason. So, nothing much to do
SDValue N = getValue(I.getOperand(0));
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(), DestVT, N);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGBuilder::visitFPTrunc(User &I) {
// FPTrunc is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getNode(ISD::FP_ROUND, getCurDebugLoc(),
- DestVT, N, DAG.getIntPtrConstant(0));
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FP_ROUND, getCurDebugLoc(),
+ DestVT, N, DAG.getIntPtrConstant(0)));
}
void SelectionDAGBuilder::visitFPExt(User &I){
// FPTrunc is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getNode(ISD::FP_EXTEND, getCurDebugLoc(), DestVT, N);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FP_EXTEND, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGBuilder::visitFPToUI(User &I) {
// FPToUI is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getNode(ISD::FP_TO_UINT, getCurDebugLoc(), DestVT, N);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FP_TO_UINT, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGBuilder::visitFPToSI(User &I) {
// FPToSI is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getNode(ISD::FP_TO_SINT, getCurDebugLoc(), DestVT, N);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FP_TO_SINT, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGBuilder::visitUIToFP(User &I) {
// UIToFP is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getNode(ISD::UINT_TO_FP, getCurDebugLoc(), DestVT, N);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::UINT_TO_FP, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGBuilder::visitSIToFP(User &I){
// SIToFP is never a no-op cast, no need to check
SDValue N = getValue(I.getOperand(0));
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getNode(ISD::SINT_TO_FP, getCurDebugLoc(), DestVT, N);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::SINT_TO_FP, getCurDebugLoc(), DestVT, N));
}
void SelectionDAGBuilder::visitPtrToInt(User &I) {
@@ -2383,9 +2271,7 @@ void SelectionDAGBuilder::visitPtrToInt(User &I) {
SDValue N = getValue(I.getOperand(0));
EVT SrcVT = N.getValueType();
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT));
}
void SelectionDAGBuilder::visitIntToPtr(User &I) {
@@ -2394,9 +2280,7 @@ void SelectionDAGBuilder::visitIntToPtr(User &I) {
SDValue N = getValue(I.getOperand(0));
EVT SrcVT = N.getValueType();
EVT DestVT = TLI.getValueType(I.getType());
- SDValue Res = DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT));
}
void SelectionDAGBuilder::visitBitCast(User &I) {
@@ -2405,14 +2289,11 @@ void SelectionDAGBuilder::visitBitCast(User &I) {
// BitCast assures us that source and destination are the same size so this is
// either a BIT_CONVERT or a no-op.
- if (DestVT != N.getValueType()) {
- SDValue Res = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(),
- DestVT, N); // convert types.
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- } else {
+ if (DestVT != N.getValueType())
+ setValue(&I, DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(),
+ DestVT, N)); // convert types.
+ else
setValue(&I, N); // noop cast.
- }
}
void SelectionDAGBuilder::visitInsertElement(User &I) {
@@ -2421,13 +2302,9 @@ void SelectionDAGBuilder::visitInsertElement(User &I) {
SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(),
TLI.getPointerTy(),
getValue(I.getOperand(2)));
- SDValue Res = DAG.getNode(ISD::INSERT_VECTOR_ELT, getCurDebugLoc(),
- TLI.getValueType(I.getType()),
- InVec, InVal, InIdx);
- setValue(&I, Res);
-
- DAG.AssignOrdering(InIdx.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT, getCurDebugLoc(),
+ TLI.getValueType(I.getType()),
+ InVec, InVal, InIdx));
}
void SelectionDAGBuilder::visitExtractElement(User &I) {
@@ -2435,15 +2312,10 @@ void SelectionDAGBuilder::visitExtractElement(User &I) {
SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(),
TLI.getPointerTy(),
getValue(I.getOperand(1)));
- SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(),
- TLI.getValueType(I.getType()), InVec, InIdx);
- setValue(&I, Res);
-
- DAG.AssignOrdering(InIdx.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(),
+ TLI.getValueType(I.getType()), InVec, InIdx));
}
-
// Utility for visitShuffleVector - Returns true if the mask is mask starting
// from SIndx and increasing to the element length (undefs are allowed).
static bool SequentialMask(SmallVectorImpl<int> &Mask, unsigned SIndx) {
@@ -2462,8 +2334,7 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
// Convert the ConstantVector mask operand into an array of ints, with -1
// representing undef values.
SmallVector<Constant*, 8> MaskElts;
- cast<Constant>(I.getOperand(2))->getVectorElements(*DAG.getContext(),
- MaskElts);
+ cast<Constant>(I.getOperand(2))->getVectorElements(MaskElts);
unsigned MaskNumElts = MaskElts.size();
for (unsigned i = 0; i != MaskNumElts; ++i) {
if (isa<UndefValue>(MaskElts[i]))
@@ -2477,10 +2348,8 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
unsigned SrcNumElts = SrcVT.getVectorNumElements();
if (SrcNumElts == MaskNumElts) {
- SDValue Res = DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2,
- &Mask[0]);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2,
+ &Mask[0]));
return;
}
@@ -2491,10 +2360,8 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
// lengths match.
if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) {
// The shuffle is concatenating two vectors together.
- SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(),
- VT, Src1, Src2);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(),
+ VT, Src1, Src2));
return;
}
@@ -2526,12 +2393,8 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
MappedOps.push_back(Idx + MaskNumElts - SrcNumElts);
}
- SDValue Res = DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2,
- &MappedOps[0]);
- setValue(&I, Res);
- DAG.AssignOrdering(Src1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Src2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2,
+ &MappedOps[0]));
return;
}
@@ -2583,9 +2446,7 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
}
if (RangeUse[0] == 0 && RangeUse[1] == 0) {
- SDValue Res = DAG.getUNDEF(VT);
- setValue(&I, Res); // Vectors are not used.
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getUNDEF(VT)); // Vectors are not used.
return;
}
else if (RangeUse[0] < 2 && RangeUse[1] < 2) {
@@ -2597,8 +2458,6 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
else
Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, getCurDebugLoc(), VT,
Src, DAG.getIntPtrConstant(StartIdx[Input]));
-
- DAG.AssignOrdering(Src.getNode(), SDNodeOrder);
}
// Calculate new mask.
@@ -2613,10 +2472,8 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
MappedOps.push_back(Idx - SrcNumElts - StartIdx[1] + MaskNumElts);
}
- SDValue Res = DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2,
- &MappedOps[0]);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2,
+ &MappedOps[0]));
return;
}
}
@@ -2643,14 +2500,11 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
DAG.getConstant(Idx - SrcNumElts, PtrVT));
Ops.push_back(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
}
- SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
- VT, &Ops[0], Ops.size());
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
+ VT, &Ops[0], Ops.size()));
}
void SelectionDAGBuilder::visitInsertValue(InsertValueInst &I) {
@@ -2689,11 +2543,9 @@ void SelectionDAGBuilder::visitInsertValue(InsertValueInst &I) {
Values[i] = IntoUndef ? DAG.getUNDEF(AggValueVTs[i]) :
SDValue(Agg.getNode(), Agg.getResNo() + i);
- SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
- DAG.getVTList(&AggValueVTs[0], NumAggValues),
- &Values[0], NumAggValues);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
+ DAG.getVTList(&AggValueVTs[0], NumAggValues),
+ &Values[0], NumAggValues));
}
void SelectionDAGBuilder::visitExtractValue(ExtractValueInst &I) {
@@ -2719,11 +2571,9 @@ void SelectionDAGBuilder::visitExtractValue(ExtractValueInst &I) {
DAG.getUNDEF(Agg.getNode()->getValueType(Agg.getResNo() + i)) :
SDValue(Agg.getNode(), Agg.getResNo() + i);
- SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
- DAG.getVTList(&ValValueVTs[0], NumValValues),
- &Values[0], NumValValues);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
+ DAG.getVTList(&ValValueVTs[0], NumValValues),
+ &Values[0], NumValValues));
}
void SelectionDAGBuilder::visitGetElementPtr(User &I) {
@@ -2740,7 +2590,6 @@ void SelectionDAGBuilder::visitGetElementPtr(User &I) {
uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field);
N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N,
DAG.getIntPtrConstant(Offset));
- DAG.AssignOrdering(N.getNode(), SDNodeOrder);
}
Ty = StTy->getElementType(Field);
@@ -2764,9 +2613,6 @@ void SelectionDAGBuilder::visitGetElementPtr(User &I) {
N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N,
OffsVal);
-
- DAG.AssignOrdering(OffsVal.getNode(), SDNodeOrder);
- DAG.AssignOrdering(N.getNode(), SDNodeOrder);
continue;
}
@@ -2792,13 +2638,10 @@ void SelectionDAGBuilder::visitGetElementPtr(User &I) {
IdxN = DAG.getNode(ISD::MUL, getCurDebugLoc(),
N.getValueType(), IdxN, Scale);
}
-
- DAG.AssignOrdering(IdxN.getNode(), SDNodeOrder);
}
N = DAG.getNode(ISD::ADD, getCurDebugLoc(),
N.getValueType(), N, IdxN);
- DAG.AssignOrdering(N.getNode(), SDNodeOrder);
}
}
@@ -2823,11 +2666,8 @@ void SelectionDAGBuilder::visitAlloca(AllocaInst &I) {
AllocSize,
DAG.getConstant(TySize, AllocSize.getValueType()));
- DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
-
EVT IntPtr = TLI.getPointerTy();
AllocSize = DAG.getZExtOrTrunc(AllocSize, getCurDebugLoc(), IntPtr);
- DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
// Handle alignment. If the requested alignment is less than or equal to
// the stack alignment, ignore it. If the size is greater than or equal to
@@ -2842,13 +2682,11 @@ void SelectionDAGBuilder::visitAlloca(AllocaInst &I) {
AllocSize = DAG.getNode(ISD::ADD, getCurDebugLoc(),
AllocSize.getValueType(), AllocSize,
DAG.getIntPtrConstant(StackAlign-1));
- DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
// Mask out the low bits for alignment purposes.
AllocSize = DAG.getNode(ISD::AND, getCurDebugLoc(),
AllocSize.getValueType(), AllocSize,
DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1)));
- DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
SDValue Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) };
SDVTList VTs = DAG.getVTList(AllocSize.getValueType(), MVT::Other);
@@ -2856,7 +2694,6 @@ void SelectionDAGBuilder::visitAlloca(AllocaInst &I) {
VTs, Ops, 3);
setValue(&I, DSA);
DAG.setRoot(DSA.getValue(1));
- DAG.AssignOrdering(DSA.getNode(), SDNodeOrder);
// Inform the Frame Information that we have just allocated a variable-sized
// object.
@@ -2868,7 +2705,9 @@ void SelectionDAGBuilder::visitLoad(LoadInst &I) {
SDValue Ptr = getValue(SV);
const Type *Ty = I.getType();
+
bool isVolatile = I.isVolatile();
+ bool isNonTemporal = I.getMetadata("nontemporal") != 0;
unsigned Alignment = I.getAlignment();
SmallVector<EVT, 4> ValueVTs;
@@ -2900,13 +2739,11 @@ void SelectionDAGBuilder::visitLoad(LoadInst &I) {
PtrVT, Ptr,
DAG.getConstant(Offsets[i], PtrVT));
SDValue L = DAG.getLoad(ValueVTs[i], getCurDebugLoc(), Root,
- A, SV, Offsets[i], isVolatile, Alignment);
+ A, SV, Offsets[i], isVolatile,
+ isNonTemporal, Alignment);
Values[i] = L;
Chains[i] = L.getValue(1);
-
- DAG.AssignOrdering(A.getNode(), SDNodeOrder);
- DAG.AssignOrdering(L.getNode(), SDNodeOrder);
}
if (!ConstantMemory) {
@@ -2916,15 +2753,11 @@ void SelectionDAGBuilder::visitLoad(LoadInst &I) {
DAG.setRoot(Chain);
else
PendingLoads.push_back(Chain);
-
- DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
}
- SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
- DAG.getVTList(&ValueVTs[0], NumValues),
- &Values[0], NumValues);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
+ DAG.getVTList(&ValueVTs[0], NumValues),
+ &Values[0], NumValues));
}
void SelectionDAGBuilder::visitStore(StoreInst &I) {
@@ -2948,6 +2781,7 @@ void SelectionDAGBuilder::visitStore(StoreInst &I) {
SmallVector<SDValue, 4> Chains(NumValues);
EVT PtrVT = Ptr.getValueType();
bool isVolatile = I.isVolatile();
+ bool isNonTemporal = I.getMetadata("nontemporal") != 0;
unsigned Alignment = I.getAlignment();
for (unsigned i = 0; i != NumValues; ++i) {
@@ -2955,16 +2789,12 @@ void SelectionDAGBuilder::visitStore(StoreInst &I) {
DAG.getConstant(Offsets[i], PtrVT));
Chains[i] = DAG.getStore(Root, getCurDebugLoc(),
SDValue(Src.getNode(), Src.getResNo() + i),
- Add, PtrV, Offsets[i], isVolatile, Alignment);
-
- DAG.AssignOrdering(Add.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Chains[i].getNode(), SDNodeOrder);
+ Add, PtrV, Offsets[i], isVolatile,
+ isNonTemporal, Alignment);
}
- SDValue Res = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
- MVT::Other, &Chains[0], NumValues);
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
+ MVT::Other, &Chains[0], NumValues));
}
/// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
@@ -3035,8 +2865,6 @@ void SelectionDAGBuilder::visitTargetIntrinsic(CallInst &I,
VTs, &Ops[0], Ops.size());
}
- DAG.AssignOrdering(Result.getNode(), SDNodeOrder);
-
if (HasChain) {
SDValue Chain = Result.getValue(Result.getNode()->getNumValues()-1);
if (OnlyLoad)
@@ -3049,7 +2877,6 @@ void SelectionDAGBuilder::visitTargetIntrinsic(CallInst &I,
if (const VectorType *PTy = dyn_cast<VectorType>(I.getType())) {
EVT VT = TLI.getValueType(PTy);
Result = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), VT, Result);
- DAG.AssignOrdering(Result.getNode(), SDNodeOrder);
}
setValue(&I, Result);
@@ -3068,12 +2895,7 @@ GetSignificand(SelectionDAG &DAG, SDValue Op, DebugLoc dl, unsigned Order) {
DAG.getConstant(0x007fffff, MVT::i32));
SDValue t2 = DAG.getNode(ISD::OR, dl, MVT::i32, t1,
DAG.getConstant(0x3f800000, MVT::i32));
- SDValue Res = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t2);
-
- DAG.AssignOrdering(t1.getNode(), Order);
- DAG.AssignOrdering(t2.getNode(), Order);
- DAG.AssignOrdering(Res.getNode(), Order);
- return Res;
+ return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t2);
}
/// GetExponent - Get the exponent:
@@ -3090,13 +2912,7 @@ GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI,
DAG.getConstant(23, TLI.getPointerTy()));
SDValue t2 = DAG.getNode(ISD::SUB, dl, MVT::i32, t1,
DAG.getConstant(127, MVT::i32));
- SDValue Res = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2);
-
- DAG.AssignOrdering(t0.getNode(), Order);
- DAG.AssignOrdering(t1.getNode(), Order);
- DAG.AssignOrdering(t2.getNode(), Order);
- DAG.AssignOrdering(Res.getNode(), Order);
- return Res;
+ return DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2);
}
/// getF32Constant - Get 32-bit floating point constant.
@@ -3120,7 +2936,6 @@ SelectionDAGBuilder::implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op) {
I.getOperand(1));
setValue(&I, L);
DAG.setRoot(L.getValue(1));
- DAG.AssignOrdering(L.getNode(), SDNodeOrder);
return 0;
}
@@ -3131,10 +2946,7 @@ SelectionDAGBuilder::implVisitAluOverflow(CallInst &I, ISD::NodeType Op) {
SDValue Op2 = getValue(I.getOperand(2));
SDVTList VTs = DAG.getVTList(Op1.getValueType(), MVT::i1);
- SDValue Result = DAG.getNode(Op, getCurDebugLoc(), VTs, Op1, Op2);
-
- setValue(&I, Result);
- DAG.AssignOrdering(Result.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(Op, getCurDebugLoc(), VTs, Op1, Op2));
return 0;
}
@@ -3162,15 +2974,9 @@ SelectionDAGBuilder::visitExp(CallInst &I) {
SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0, t1);
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(X.getNode(), SDNodeOrder);
-
// IntegerPartOfX <<= 23;
IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
DAG.getConstant(23, TLI.getPointerTy()));
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -3194,14 +3000,6 @@ SelectionDAGBuilder::visitExp(CallInst &I) {
TwoToFracPartOfX, IntegerPartOfX);
result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t6);
-
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3228,16 +3026,6 @@ SelectionDAGBuilder::visitExp(CallInst &I) {
TwoToFracPartOfX, IntegerPartOfX);
result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t8);
-
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3277,29 +3065,12 @@ SelectionDAGBuilder::visitExp(CallInst &I) {
TwoToFracPartOfX, IntegerPartOfX);
result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t14);
-
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t11.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t12.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t13.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t14.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
result = DAG.getNode(ISD::FEXP, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -3317,15 +3088,11 @@ SelectionDAGBuilder::visitLog(CallInst &I) {
SDValue Op = getValue(I.getOperand(1));
SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
- DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
-
// Scale the exponent by log(2) [0.69314718f].
SDValue Exp = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder);
SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp,
getF32Constant(DAG, 0x3f317218));
- DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder);
-
// Get the significand and build it into a floating-point number with
// exponent of 1.
SDValue X = GetSignificand(DAG, Op1, dl, SDNodeOrder);
@@ -3348,12 +3115,6 @@ SelectionDAGBuilder::visitLog(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, LogOfMantissa);
-
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3380,16 +3141,6 @@ SelectionDAGBuilder::visitLog(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, LogOfMantissa);
-
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3424,27 +3175,12 @@ SelectionDAGBuilder::visitLog(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, LogOfMantissa);
-
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
- DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
result = DAG.getNode(ISD::FLOG, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -3462,13 +3198,9 @@ SelectionDAGBuilder::visitLog2(CallInst &I) {
SDValue Op = getValue(I.getOperand(1));
SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
- DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
-
// Get the exponent.
SDValue LogOfExponent = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder);
- DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder);
-
// Get the significand and build it into a floating-point number with
// exponent of 1.
SDValue X = GetSignificand(DAG, Op1, dl, SDNodeOrder);
@@ -3491,12 +3223,6 @@ SelectionDAGBuilder::visitLog2(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log2ofMantissa);
-
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3523,16 +3249,6 @@ SelectionDAGBuilder::visitLog2(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log2ofMantissa);
-
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3568,27 +3284,12 @@ SelectionDAGBuilder::visitLog2(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log2ofMantissa);
-
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
result = DAG.getNode(ISD::FLOG2, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -3606,15 +3307,11 @@ SelectionDAGBuilder::visitLog10(CallInst &I) {
SDValue Op = getValue(I.getOperand(1));
SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
- DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
-
// Scale the exponent by log10(2) [0.30102999f].
SDValue Exp = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder);
SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp,
getF32Constant(DAG, 0x3e9a209a));
- DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder);
-
// Get the significand and build it into a floating-point number with
// exponent of 1.
SDValue X = GetSignificand(DAG, Op1, dl, SDNodeOrder);
@@ -3637,12 +3334,6 @@ SelectionDAGBuilder::visitLog10(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log10ofMantissa);
-
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3665,14 +3356,6 @@ SelectionDAGBuilder::visitLog10(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log10ofMantissa);
-
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3703,25 +3386,12 @@ SelectionDAGBuilder::visitLog10(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log10ofMantissa);
-
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
result = DAG.getNode(ISD::FLOG10, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -3740,8 +3410,6 @@ SelectionDAGBuilder::visitExp2(CallInst &I) {
SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Op);
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
-
// FractionalPartOfX = x - (float)IntegerPartOfX;
SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, Op, t1);
@@ -3750,10 +3418,6 @@ SelectionDAGBuilder::visitExp2(CallInst &I) {
IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
DAG.getConstant(23, TLI.getPointerTy()));
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(X.getNode(), SDNodeOrder);
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
-
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
//
@@ -3775,14 +3439,6 @@ SelectionDAGBuilder::visitExp2(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
-
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3808,16 +3464,6 @@ SelectionDAGBuilder::visitExp2(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
-
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3854,29 +3500,12 @@ SelectionDAGBuilder::visitExp2(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
-
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t11.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t12.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t13.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t14.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
result = DAG.getNode(ISD::FEXP2, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -3918,17 +3547,10 @@ SelectionDAGBuilder::visitPow(CallInst &I) {
SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0, t1);
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(X.getNode(), SDNodeOrder);
-
// IntegerPartOfX <<= 23;
IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
DAG.getConstant(23, TLI.getPointerTy()));
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
-
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
//
@@ -3950,14 +3572,6 @@ SelectionDAGBuilder::visitPow(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
-
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3983,16 +3597,6 @@ SelectionDAGBuilder::visitPow(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
-
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -4029,22 +3633,6 @@ SelectionDAGBuilder::visitPow(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
-
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t11.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t12.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t13.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t14.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
@@ -4052,7 +3640,6 @@ SelectionDAGBuilder::visitPow(CallInst &I) {
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)),
getValue(I.getOperand(2)));
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -4129,16 +3716,12 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
case Intrinsic::vaend: visitVAEnd(I); return 0;
case Intrinsic::vacopy: visitVACopy(I); return 0;
case Intrinsic::returnaddress:
- Res = DAG.getNode(ISD::RETURNADDR, dl, TLI.getPointerTy(),
- getValue(I.getOperand(1)));
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::RETURNADDR, dl, TLI.getPointerTy(),
+ getValue(I.getOperand(1))));
return 0;
case Intrinsic::frameaddress:
- Res = DAG.getNode(ISD::FRAMEADDR, dl, TLI.getPointerTy(),
- getValue(I.getOperand(1)));
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FRAMEADDR, dl, TLI.getPointerTy(),
+ getValue(I.getOperand(1))));
return 0;
case Intrinsic::setjmp:
return "_setjmp"+!TLI.usesUnderscoreSetJmp();
@@ -4149,10 +3732,8 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
SDValue Op2 = getValue(I.getOperand(2));
SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
- Res = DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false,
- I.getOperand(1), 0, I.getOperand(2), 0);
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false,
+ I.getOperand(1), 0, I.getOperand(2), 0));
return 0;
}
case Intrinsic::memset: {
@@ -4160,10 +3741,8 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
SDValue Op2 = getValue(I.getOperand(2));
SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
- Res = DAG.getMemset(getRoot(), dl, Op1, Op2, Op3, Align,
- I.getOperand(1), 0);
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getMemset(getRoot(), dl, Op1, Op2, Op3, Align,
+ I.getOperand(1), 0));
return 0;
}
case Intrinsic::memmove: {
@@ -4179,20 +3758,18 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Size = C->getZExtValue();
if (AA->alias(I.getOperand(1), Size, I.getOperand(2), Size) ==
AliasAnalysis::NoAlias) {
- Res = DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false,
- I.getOperand(1), 0, I.getOperand(2), 0);
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false,
+ I.getOperand(1), 0, I.getOperand(2), 0));
return 0;
}
- Res = DAG.getMemmove(getRoot(), dl, Op1, Op2, Op3, Align,
- I.getOperand(1), 0, I.getOperand(2), 0);
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getMemmove(getRoot(), dl, Op1, Op2, Op3, Align,
+ I.getOperand(1), 0, I.getOperand(2), 0));
return 0;
}
case Intrinsic::dbg_declare: {
+ // FIXME: currently, we get here only if OptLevel != CodeGenOpt::None.
+ // The real handling of this intrinsic is in FastISel.
if (OptLevel != CodeGenOpt::None)
// FIXME: Variable debug info is not supported here.
return 0;
@@ -4205,6 +3782,8 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
MDNode *Variable = DI.getVariable();
Value *Address = DI.getAddress();
+ if (!Address)
+ return 0;
if (BitCastInst *BCI = dyn_cast<BitCastInst>(Address))
Address = BCI->getOperand(0);
AllocaInst *AI = dyn_cast<AllocaInst>(Address);
@@ -4222,6 +3801,39 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
MMI->setVariableDbgInfo(Variable, FI, Dbg);
return 0;
}
+ case Intrinsic::dbg_value: {
+ // FIXME: currently, we get here only if OptLevel != CodeGenOpt::None.
+ // The real handling of this intrinsic is in FastISel.
+ if (OptLevel != CodeGenOpt::None)
+ // FIXME: Variable debug info is not supported here.
+ return 0;
+ DwarfWriter *DW = DAG.getDwarfWriter();
+ if (!DW)
+ return 0;
+ DbgValueInst &DI = cast<DbgValueInst>(I);
+ if (!DIDescriptor::ValidDebugInfo(DI.getVariable(), CodeGenOpt::None))
+ return 0;
+
+ MDNode *Variable = DI.getVariable();
+ Value *V = DI.getValue();
+ if (!V)
+ return 0;
+ if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
+ V = BCI->getOperand(0);
+ AllocaInst *AI = dyn_cast<AllocaInst>(V);
+ // Don't handle byval struct arguments or VLAs, for example.
+ if (!AI)
+ return 0;
+ DenseMap<const AllocaInst*, int>::iterator SI =
+ FuncInfo.StaticAllocaMap.find(AI);
+ if (SI == FuncInfo.StaticAllocaMap.end())
+ return 0; // VLAs.
+ int FI = SI->second;
+ if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
+ if (MDNode *Dbg = DI.getMetadata("dbg"))
+ MMI->setVariableDbgInfo(Variable, FI, Dbg);
+ return 0;
+ }
case Intrinsic::eh_exception: {
// Insert the EXCEPTIONADDR instruction.
assert(CurMBB->isLandingPad() &&"Call to eh.exception not in landing pad!");
@@ -4231,7 +3843,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
SDValue Op = DAG.getNode(ISD::EXCEPTIONADDR, dl, VTs, Ops, 1);
setValue(&I, Op);
DAG.setRoot(Op.getValue(1));
- DAG.AssignOrdering(Op.getNode(), SDNodeOrder);
return 0;
}
@@ -4255,13 +3866,8 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Ops[0] = getValue(I.getOperand(1));
Ops[1] = getRoot();
SDValue Op = DAG.getNode(ISD::EHSELECTION, dl, VTs, Ops, 2);
-
DAG.setRoot(Op.getValue(1));
-
- Res = DAG.getSExtOrTrunc(Op, dl, MVT::i32);
- setValue(&I, Res);
- DAG.AssignOrdering(Op.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getSExtOrTrunc(Op, dl, MVT::i32));
return 0;
}
@@ -4279,7 +3885,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
}
setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
@@ -4287,13 +3892,11 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
case Intrinsic::eh_return_i64:
if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) {
MMI->setCallsEHReturn(true);
- Res = DAG.getNode(ISD::EH_RETURN, dl,
- MVT::Other,
- getControlRoot(),
- getValue(I.getOperand(1)),
- getValue(I.getOperand(2)));
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getNode(ISD::EH_RETURN, dl,
+ MVT::Other,
+ getControlRoot(),
+ getValue(I.getOperand(1)),
+ getValue(I.getOperand(2))));
} else {
setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
}
@@ -4316,15 +3919,20 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
SDValue FA = DAG.getNode(ISD::FRAMEADDR, dl,
TLI.getPointerTy(),
DAG.getConstant(0, TLI.getPointerTy()));
- Res = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(),
- FA, Offset);
- setValue(&I, Res);
- DAG.AssignOrdering(CfaArg.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Offset.getNode(), SDNodeOrder);
- DAG.AssignOrdering(FA.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(),
+ FA, Offset));
+ return 0;
+ }
+ case Intrinsic::eh_sjlj_callsite: {
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1));
+ assert(CI && "Non-constant call site value in eh.sjlj.callsite!");
+ assert(MMI->getCurrentCallSite() == 0 && "Overlapping call sites!");
+
+ MMI->setCurrentCallSite(CI->getZExtValue());
return 0;
}
+
case Intrinsic::convertff:
case Intrinsic::convertfsi:
case Intrinsic::convertfui:
@@ -4355,35 +3963,26 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
getValue(I.getOperand(3)),
Code);
setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::sqrt:
- Res = DAG.getNode(ISD::FSQRT, dl,
- getValue(I.getOperand(1)).getValueType(),
- getValue(I.getOperand(1)));
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FSQRT, dl,
+ getValue(I.getOperand(1)).getValueType(),
+ getValue(I.getOperand(1))));
return 0;
case Intrinsic::powi:
- Res = ExpandPowI(dl, getValue(I.getOperand(1)), getValue(I.getOperand(2)),
- DAG);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, ExpandPowI(dl, getValue(I.getOperand(1)),
+ getValue(I.getOperand(2)), DAG));
return 0;
case Intrinsic::sin:
- Res = DAG.getNode(ISD::FSIN, dl,
- getValue(I.getOperand(1)).getValueType(),
- getValue(I.getOperand(1)));
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FSIN, dl,
+ getValue(I.getOperand(1)).getValueType(),
+ getValue(I.getOperand(1))));
return 0;
case Intrinsic::cos:
- Res = DAG.getNode(ISD::FCOS, dl,
- getValue(I.getOperand(1)).getValueType(),
- getValue(I.getOperand(1)));
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FCOS, dl,
+ getValue(I.getOperand(1)).getValueType(),
+ getValue(I.getOperand(1))));
return 0;
case Intrinsic::log:
visitLog(I);
@@ -4405,9 +4004,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0;
case Intrinsic::pcmarker: {
SDValue Tmp = getValue(I.getOperand(1));
- Res = DAG.getNode(ISD::PCMARKER, dl, MVT::Other, getRoot(), Tmp);
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getNode(ISD::PCMARKER, dl, MVT::Other, getRoot(), Tmp));
return 0;
}
case Intrinsic::readcyclecounter: {
@@ -4417,38 +4014,29 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
&Op, 1);
setValue(&I, Res);
DAG.setRoot(Res.getValue(1));
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::bswap:
- Res = DAG.getNode(ISD::BSWAP, dl,
- getValue(I.getOperand(1)).getValueType(),
- getValue(I.getOperand(1)));
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::BSWAP, dl,
+ getValue(I.getOperand(1)).getValueType(),
+ getValue(I.getOperand(1))));
return 0;
case Intrinsic::cttz: {
SDValue Arg = getValue(I.getOperand(1));
EVT Ty = Arg.getValueType();
- Res = DAG.getNode(ISD::CTTZ, dl, Ty, Arg);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::CTTZ, dl, Ty, Arg));
return 0;
}
case Intrinsic::ctlz: {
SDValue Arg = getValue(I.getOperand(1));
EVT Ty = Arg.getValueType();
- Res = DAG.getNode(ISD::CTLZ, dl, Ty, Arg);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::CTLZ, dl, Ty, Arg));
return 0;
}
case Intrinsic::ctpop: {
SDValue Arg = getValue(I.getOperand(1));
EVT Ty = Arg.getValueType();
- Res = DAG.getNode(ISD::CTPOP, dl, Ty, Arg);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::CTPOP, dl, Ty, Arg));
return 0;
}
case Intrinsic::stacksave: {
@@ -4457,14 +4045,11 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
DAG.getVTList(TLI.getPointerTy(), MVT::Other), &Op, 1);
setValue(&I, Res);
DAG.setRoot(Res.getValue(1));
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::stackrestore: {
Res = getValue(I.getOperand(1));
- Res = DAG.getNode(ISD::STACKRESTORE, dl, MVT::Other, getRoot(), Res);
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getNode(ISD::STACKRESTORE, dl, MVT::Other, getRoot(), Res));
return 0;
}
case Intrinsic::stackprotector: {
@@ -4484,10 +4069,9 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
// Store the stack protector onto the stack.
Res = DAG.getStore(getRoot(), getCurDebugLoc(), Src, FIN,
PseudoSourceValue::getFixedStack(FI),
- 0, true);
+ 0, true, false, 0);
setValue(&I, Res);
DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::objectsize: {
@@ -4505,7 +4089,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Res = DAG.getConstant(0, Ty);
setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::var_annotation:
@@ -4529,7 +4112,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
setValue(&I, Res);
DAG.setRoot(Res.getValue(1));
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::gcroot:
@@ -4546,14 +4128,10 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
llvm_unreachable("GC failed to lower gcread/gcwrite intrinsics!");
return 0;
case Intrinsic::flt_rounds:
- Res = DAG.getNode(ISD::FLT_ROUNDS_, dl, MVT::i32);
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getNode(ISD::FLT_ROUNDS_, dl, MVT::i32));
return 0;
case Intrinsic::trap:
- Res = DAG.getNode(ISD::TRAP, dl,MVT::Other, getRoot());
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getNode(ISD::TRAP, dl,MVT::Other, getRoot()));
return 0;
case Intrinsic::uadd_with_overflow:
return implVisitAluOverflow(I, ISD::UADDO);
@@ -4574,9 +4152,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Ops[1] = getValue(I.getOperand(1));
Ops[2] = getValue(I.getOperand(2));
Ops[3] = getValue(I.getOperand(3));
- Res = DAG.getNode(ISD::PREFETCH, dl, MVT::Other, &Ops[0], 4);
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getNode(ISD::PREFETCH, dl, MVT::Other, &Ops[0], 4));
return 0;
}
@@ -4586,9 +4162,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
for (int x = 1; x < 6; ++x)
Ops[x] = getValue(I.getOperand(x));
- Res = DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, &Ops[0], 6);
- DAG.setRoot(Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, &Ops[0], 6));
return 0;
}
case Intrinsic::atomic_cmp_swap: {
@@ -4603,7 +4177,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
I.getOperand(1));
setValue(&I, L);
DAG.setRoot(L.getValue(1));
- DAG.AssignOrdering(L.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::atomic_load_add:
@@ -4632,9 +4205,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
case Intrinsic::invariant_start:
case Intrinsic::lifetime_start:
// Discard region information.
- Res = DAG.getUNDEF(TLI.getPointerTy());
- setValue(&I, Res);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ setValue(&I, DAG.getUNDEF(TLI.getPointerTy()));
return 0;
case Intrinsic::invariant_end:
case Intrinsic::lifetime_end:
@@ -4649,19 +4220,25 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
/// between it and the return.
///
/// This function only tests target-independent requirements.
-/// For target-dependent requirements, a target should override
-/// TargetLowering::IsEligibleForTailCallOptimization.
-///
static bool
-isInTailCallPosition(const Instruction *I, Attributes CalleeRetAttr,
+isInTailCallPosition(CallSite CS, Attributes CalleeRetAttr,
const TargetLowering &TLI) {
+ const Instruction *I = CS.getInstruction();
const BasicBlock *ExitBB = I->getParent();
const TerminatorInst *Term = ExitBB->getTerminator();
const ReturnInst *Ret = dyn_cast<ReturnInst>(Term);
const Function *F = ExitBB->getParent();
- // The block must end in a return statement or an unreachable.
- if (!Ret && !isa<UnreachableInst>(Term)) return false;
+ // The block must end in a return statement or unreachable.
+ //
+ // FIXME: Decline tailcall if it's not guaranteed and if the block ends in
+ // an unreachable, for now. The way tailcall optimization is currently
+ // implemented means it will add an epilogue followed by a jump. That is
+ // not profitable. Also, if the callee is a special function (e.g.
+ // longjmp on x86), it can end up causing miscompilation that has not
+ // been fully understood.
+ if (!Ret &&
+ (!GuaranteedTailCallOpt || !isa<UnreachableInst>(Term))) return false;
// If I will have a chain, make sure no other instruction that will have a
// chain interposes between I and the return.
@@ -4690,6 +4267,10 @@ isInTailCallPosition(const Instruction *I, Attributes CalleeRetAttr,
if ((CalleeRetAttr ^ CallerRetAttr) & ~Attribute::NoAlias)
return false;
+ // It's not safe to eliminate the sign / zero extension of the return value.
+ if ((CallerRetAttr & Attribute::ZExt) || (CallerRetAttr & Attribute::SExt))
+ return false;
+
// Otherwise, make sure the unmodified return value of I is the return value.
for (const Instruction *U = dyn_cast<Instruction>(Ret->getOperand(0)); ;
U = dyn_cast<Instruction>(U->getOperand(0))) {
@@ -4785,6 +4366,15 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
// used to detect deletion of the invoke via the MachineModuleInfo.
BeginLabel = MMI->NextLabelID();
+ // For SjLj, keep track of which landing pads go with which invokes
+ // so as to maintain the ordering of pads in the LSDA.
+ unsigned CallSiteIndex = MMI->getCurrentCallSite();
+ if (CallSiteIndex) {
+ MMI->setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
+ // Now that the call site is handled, stop tracking it.
+ MMI->setCurrentCallSite(0);
+ }
+
// Both PendingLoads and PendingExports must be flushed here;
// this call might not return.
(void)getRoot();
@@ -4795,9 +4385,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
// Check if target-independent constraints permit a tail call here.
// Target-dependent constraints are checked within TLI.LowerCallTo.
if (isTailCall &&
- !isInTailCallPosition(CS.getInstruction(),
- CS.getAttributes().getRetAttributes(),
- TLI))
+ !isInTailCallPosition(CS, CS.getAttributes().getRetAttributes(), TLI))
isTailCall = false;
std::pair<SDValue,SDValue> Result =
@@ -4815,7 +4403,6 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
"Null value expected with tail call!");
if (Result.first.getNode()) {
setValue(CS.getInstruction(), Result.first);
- DAG.AssignOrdering(Result.first.getNode(), SDNodeOrder);
} else if (!CanLowerReturn && Result.second.getNode()) {
// The instruction result is the result of loading from the
// hidden sret parameter.
@@ -4834,7 +4421,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
DemoteStackSlot,
DAG.getConstant(Offsets[i], PtrVT));
SDValue L = DAG.getLoad(OutVTs[i], getCurDebugLoc(), Result.second,
- Add, NULL, Offsets[i], false, 1);
+ Add, NULL, Offsets[i], false, false, 1);
Values[i] = L;
Chains[i] = L.getValue(1);
}
@@ -4860,27 +4447,22 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
getCopyFromParts(DAG, getCurDebugLoc(), SDNodeOrder, &Values[CurReg], NumRegs,
RegisterVT, VT, AssertOp);
ReturnValues.push_back(ReturnValue);
- DAG.AssignOrdering(ReturnValue.getNode(), SDNodeOrder);
CurReg += NumRegs;
}
- SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
- DAG.getVTList(&RetTys[0], RetTys.size()),
- &ReturnValues[0], ReturnValues.size());
- setValue(CS.getInstruction(), Res);
+ setValue(CS.getInstruction(),
+ DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
+ DAG.getVTList(&RetTys[0], RetTys.size()),
+ &ReturnValues[0], ReturnValues.size()));
- DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
// As a special case, a null chain means that a tail call has been emitted and
// the DAG root is already updated.
- if (Result.second.getNode()) {
+ if (Result.second.getNode())
DAG.setRoot(Result.second);
- DAG.AssignOrdering(Result.second.getNode(), SDNodeOrder);
- } else {
+ else
HasTailCall = true;
- }
if (LandingPad && MMI) {
// Insert a label at the end of the invoke call to mark the try range. This
@@ -4941,7 +4523,8 @@ static SDValue getMemCmpLoad(Value *PtrVal, MVT LoadVT, const Type *LoadTy,
SDValue Ptr = Builder.getValue(PtrVal);
SDValue LoadVal = Builder.DAG.getLoad(LoadVT, Builder.getCurDebugLoc(), Root,
Ptr, PtrVal /*SrcValue*/, 0/*SVOffset*/,
- false /*volatile*/, 1 /* align=1 */);
+ false /*volatile*/,
+ false /*nontemporal*/, 1 /* align=1 */);
if (!ConstantMemory)
Builder.PendingLoads.push_back(LoadVal.getValue(1));
@@ -5054,7 +4637,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
StringRef Name = F->getName();
if (Name == "copysign" || Name == "copysignf") {
if (I.getNumOperands() == 3 && // Basic sanity checks.
- I.getOperand(1)->getType()->isFloatingPoint() &&
+ I.getOperand(1)->getType()->isFloatingPointTy() &&
I.getType() == I.getOperand(1)->getType() &&
I.getType() == I.getOperand(2)->getType()) {
SDValue LHS = getValue(I.getOperand(1));
@@ -5065,7 +4648,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
}
} else if (Name == "fabs" || Name == "fabsf" || Name == "fabsl") {
if (I.getNumOperands() == 2 && // Basic sanity checks.
- I.getOperand(1)->getType()->isFloatingPoint() &&
+ I.getOperand(1)->getType()->isFloatingPointTy() &&
I.getType() == I.getOperand(1)->getType()) {
SDValue Tmp = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FABS, getCurDebugLoc(),
@@ -5074,7 +4657,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
}
} else if (Name == "sin" || Name == "sinf" || Name == "sinl") {
if (I.getNumOperands() == 2 && // Basic sanity checks.
- I.getOperand(1)->getType()->isFloatingPoint() &&
+ I.getOperand(1)->getType()->isFloatingPointTy() &&
I.getType() == I.getOperand(1)->getType() &&
I.onlyReadsMemory()) {
SDValue Tmp = getValue(I.getOperand(1));
@@ -5084,7 +4667,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
}
} else if (Name == "cos" || Name == "cosf" || Name == "cosl") {
if (I.getNumOperands() == 2 && // Basic sanity checks.
- I.getOperand(1)->getType()->isFloatingPoint() &&
+ I.getOperand(1)->getType()->isFloatingPointTy() &&
I.getType() == I.getOperand(1)->getType() &&
I.onlyReadsMemory()) {
SDValue Tmp = getValue(I.getOperand(1));
@@ -5094,7 +4677,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
}
} else if (Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl") {
if (I.getNumOperands() == 2 && // Basic sanity checks.
- I.getOperand(1)->getType()->isFloatingPoint() &&
+ I.getOperand(1)->getType()->isFloatingPointTy() &&
I.getType() == I.getOperand(1)->getType() &&
I.onlyReadsMemory()) {
SDValue Tmp = getValue(I.getOperand(1));
@@ -5120,9 +4703,7 @@ void SelectionDAGBuilder::visitCall(CallInst &I) {
// Check if we can potentially perform a tail call. More detailed checking is
// be done within LowerCallTo, after more information about the call is known.
- bool isTailCall = PerformTailCallOpt && I.isTailCall();
-
- LowerCallTo(&I, Callee, isTailCall);
+ LowerCallTo(&I, Callee, I.isTailCall());
}
/// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from
@@ -5152,7 +4733,6 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
}
Chain = P.getValue(1);
- DAG.AssignOrdering(P.getNode(), Order);
// If the source register was virtual and if we know something about it,
// add an assert node.
@@ -5188,11 +4768,9 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
else if (NumZeroBits >= RegSize-32)
isSExt = false, FromVT = MVT::i32; // ASSERT ZEXT 32
- if (FromVT != MVT::Other) {
+ if (FromVT != MVT::Other)
P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext, dl,
RegisterVT, P, DAG.getValueType(FromVT));
- DAG.AssignOrdering(P.getNode(), Order);
- }
}
}
@@ -5201,16 +4779,13 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
Values[Value] = getCopyFromParts(DAG, dl, Order, Parts.begin(),
NumRegs, RegisterVT, ValueVT);
- DAG.AssignOrdering(Values[Value].getNode(), Order);
Part += NumRegs;
Parts.clear();
}
- SDValue Res = DAG.getNode(ISD::MERGE_VALUES, dl,
- DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
- &Values[0], ValueVTs.size());
- DAG.AssignOrdering(Res.getNode(), Order);
- return Res;
+ return DAG.getNode(ISD::MERGE_VALUES, dl,
+ DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
+ &Values[0], ValueVTs.size());
}
/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
@@ -5246,7 +4821,6 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
}
Chains[i] = Part.getValue(0);
- DAG.AssignOrdering(Part.getNode(), Order);
}
if (NumRegs == 1 || Flag)
@@ -5263,8 +4837,6 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
Chain = Chains[NumRegs-1];
else
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Chains[0], NumRegs);
-
- DAG.AssignOrdering(Chain.getNode(), Order);
}
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
@@ -5281,16 +4853,12 @@ void RegsForValue::AddInlineAsmOperands(unsigned Code,
SDValue Res = DAG.getTargetConstant(Flag, MVT::i32);
Ops.push_back(Res);
- DAG.AssignOrdering(Res.getNode(), Order);
-
for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) {
unsigned NumRegs = TLI->getNumRegisters(*DAG.getContext(), ValueVTs[Value]);
EVT RegisterVT = RegVTs[Value];
for (unsigned i = 0; i != NumRegs; ++i) {
assert(Reg < Regs.size() && "Mismatch in # registers expected");
- SDValue Res = DAG.getRegister(Regs[Reg++], RegisterVT);
- Ops.push_back(Res);
- DAG.AssignOrdering(Res.getNode(), Order);
+ Ops.push_back(DAG.getRegister(Regs[Reg++], RegisterVT));
}
}
}
@@ -5309,7 +4877,7 @@ isAllocatableRegister(unsigned Reg, MachineFunction &MF,
EVT ThisVT = MVT::Other;
const TargetRegisterClass *RC = *RCI;
- // If none of the the value types for this register class are valid, we
+ // If none of the value types for this register class are valid, we
// can't use it. For example, 64-bit reg classes on 32-bit targets.
for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end();
I != E; ++I) {
@@ -5509,8 +5077,6 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
RegVT, OpInfo.CallOperand);
OpInfo.ConstraintVT = RegVT;
}
-
- DAG.AssignOrdering(OpInfo.CallOperand.getNode(), SDNodeOrder);
}
NumRegs = TLI.getNumRegisters(Context, OpInfo.ConstraintVT);
@@ -5776,7 +5342,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align, false);
SDValue StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
Chain = DAG.getStore(Chain, getCurDebugLoc(),
- OpInfo.CallOperand, StackSlot, NULL, 0);
+ OpInfo.CallOperand, StackSlot, NULL, 0,
+ false, false, 0);
OpInfo.CallOperand = StackSlot;
}
@@ -5972,7 +5539,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
"Don't know how to handle indirect register inputs yet!");
// Copy the input into the appropriate registers.
- if (OpInfo.AssignedRegs.Regs.empty()) {
+ if (OpInfo.AssignedRegs.Regs.empty() ||
+ !OpInfo.AssignedRegs.areValueTypesLegal()) {
llvm_report_error("Couldn't allocate input reg for"
" constraint '"+ OpInfo.ConstraintCode +"'!");
}
@@ -6061,7 +5629,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
SDValue Val = DAG.getStore(Chain, getCurDebugLoc(),
StoresToEmit[i].first,
getValue(StoresToEmit[i].second),
- StoresToEmit[i].second, 0);
+ StoresToEmit[i].second, 0,
+ false, false, 0);
OutChains.push_back(Val);
}
@@ -6116,9 +5685,6 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
SDValue Callee,
ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl,
unsigned Order) {
- assert((!isTailCall || PerformTailCallOpt) &&
- "isTailCall set when tail-call optimizations are disabled!");
-
// Handle all of the outgoing arguments.
SmallVector<ISD::OutputArg, 32> Outs;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
@@ -6207,12 +5773,6 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
}
}
- // Check if target-dependent constraints permit a tail call here.
- // Target-independent constraints should be checked by the caller.
- if (isTailCall &&
- !IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg, Ins, DAG))
- isTailCall = false;
-
SmallVector<SDValue, 4> InVals;
Chain = LowerCall(Chain, Callee, CallConv, isVarArg, isTailCall,
Outs, Ins, dl, DAG, InVals);
@@ -6231,8 +5791,6 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
"LowerCall emitted a value with the wrong type!");
});
- DAG.AssignOrdering(Chain.getNode(), Order);
-
// For a tail call, the return value is merely live-out and there aren't
// any nodes in the DAG representing it. Return a special value to
// indicate that a tail call has been emitted and no more Instructions
@@ -6256,11 +5814,9 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
EVT RegisterVT = getRegisterType(RetTy->getContext(), VT);
unsigned NumRegs = getNumRegisters(RetTy->getContext(), VT);
- SDValue ReturnValue =
- getCopyFromParts(DAG, dl, Order, &InVals[CurReg], NumRegs,
- RegisterVT, VT, AssertOp);
- ReturnValues.push_back(ReturnValue);
- DAG.AssignOrdering(ReturnValue.getNode(), Order);
+ ReturnValues.push_back(getCopyFromParts(DAG, dl, Order, &InVals[CurReg],
+ NumRegs, RegisterVT, VT,
+ AssertOp));
CurReg += NumRegs;
}
@@ -6273,7 +5829,6 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
SDValue Res = DAG.getNode(ISD::MERGE_VALUES, dl,
DAG.getVTList(&RetTys[0], RetTys.size()),
&ReturnValues[0], ReturnValues.size());
- DAG.AssignOrdering(Res.getNode(), Order);
return std::make_pair(Res, Chain);
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index db656e3..bc4b33d 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -342,6 +342,11 @@ public:
void CopyValueToVirtualRegister(Value *V, unsigned Reg);
+ /// AssignOrderingToNode - Assign an ordering to the node. The order is gotten
+ /// from how the code appeared in the source. The ordering is used by the
+ /// scheduler to effectively turn off scheduling.
+ void AssignOrderingToNode(const SDNode *Node);
+
void visit(Instruction &I);
void visit(unsigned Opcode, User &I);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 2bec964..eead526 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -457,6 +457,21 @@ public:
};
}
+/// TrivialTruncElim - Eliminate some trivial nops that can result from
+/// ShrinkDemandedOps: (trunc (ext n)) -> n.
+static bool TrivialTruncElim(SDValue Op,
+ TargetLowering::TargetLoweringOpt &TLO) {
+ SDValue N0 = Op.getOperand(0);
+ EVT VT = Op.getValueType();
+ if ((N0.getOpcode() == ISD::ZERO_EXTEND ||
+ N0.getOpcode() == ISD::SIGN_EXTEND ||
+ N0.getOpcode() == ISD::ANY_EXTEND) &&
+ N0.getOperand(0).getValueType() == VT) {
+ return TLO.CombineTo(Op, N0.getOperand(0));
+ }
+ return false;
+}
+
/// ShrinkDemandedOps - A late transformation pass that shrink expressions
/// using TargetLowering::TargetLoweringOpt::ShrinkDemandedOp. It converts
/// x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free.
@@ -489,7 +504,9 @@ void SelectionDAGISel::ShrinkDemandedOps() {
APInt Demanded = APInt::getAllOnesValue(BitWidth);
APInt KnownZero, KnownOne;
if (TLI.SimplifyDemandedBits(SDValue(N, 0), Demanded,
- KnownZero, KnownOne, TLO)) {
+ KnownZero, KnownOne, TLO) ||
+ (N->getOpcode() == ISD::TRUNCATE &&
+ TrivialTruncElim(SDValue(N, 0), TLO))) {
// Revisit the node.
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(), N),
Worklist.end());
@@ -801,7 +818,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
// landing pad can thus be detected via the MachineModuleInfo.
unsigned LabelID = MMI->addLandingPad(BB);
- const TargetInstrDesc &II = TII.get(TargetInstrInfo::EH_LABEL);
+ const TargetInstrDesc &II = TII.get(TargetOpcode::EH_LABEL);
BuildMI(BB, SDB->getCurDebugLoc(), II).addImm(LabelID);
// Mark exception register as live in.
@@ -953,7 +970,7 @@ SelectionDAGISel::FinishBasicBlock() {
SDB->BitTestCases.empty()) {
for (unsigned i = 0, e = SDB->PHINodesToUpdate.size(); i != e; ++i) {
MachineInstr *PHI = SDB->PHINodesToUpdate[i].first;
- assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
+ assert(PHI->isPHI() &&
"This is not a machine PHI node that we are updating!");
PHI->addOperand(MachineOperand::CreateReg(SDB->PHINodesToUpdate[i].second,
false));
@@ -1000,7 +1017,7 @@ SelectionDAGISel::FinishBasicBlock() {
for (unsigned pi = 0, pe = SDB->PHINodesToUpdate.size(); pi != pe; ++pi) {
MachineInstr *PHI = SDB->PHINodesToUpdate[pi].first;
MachineBasicBlock *PHIBB = PHI->getParent();
- assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
+ assert(PHI->isPHI() &&
"This is not a machine PHI node that we are updating!");
// This is "default" BB. We have two jumps to it. From "header" BB and
// from last "case" BB.
@@ -1056,7 +1073,7 @@ SelectionDAGISel::FinishBasicBlock() {
for (unsigned pi = 0, pe = SDB->PHINodesToUpdate.size(); pi != pe; ++pi) {
MachineInstr *PHI = SDB->PHINodesToUpdate[pi].first;
MachineBasicBlock *PHIBB = PHI->getParent();
- assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
+ assert(PHI->isPHI() &&
"This is not a machine PHI node that we are updating!");
// "default" BB. We can go there only from header BB.
if (PHIBB == SDB->JTCases[i].second.Default) {
@@ -1079,7 +1096,7 @@ SelectionDAGISel::FinishBasicBlock() {
// need to update PHI nodes in that block.
for (unsigned i = 0, e = SDB->PHINodesToUpdate.size(); i != e; ++i) {
MachineInstr *PHI = SDB->PHINodesToUpdate[i].first;
- assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
+ assert(PHI->isPHI() &&
"This is not a machine PHI node that we are updating!");
if (BB->isSuccessor(PHI->getParent())) {
PHI->addOperand(MachineOperand::CreateReg(SDB->PHINodesToUpdate[i].second,
@@ -1116,7 +1133,7 @@ SelectionDAGISel::FinishBasicBlock() {
// BB may have been removed from the CFG if a branch was constant folded.
if (ThisBB->isSuccessor(BB)) {
for (MachineBasicBlock::iterator Phi = BB->begin();
- Phi != BB->end() && Phi->getOpcode() == TargetInstrInfo::PHI;
+ Phi != BB->end() && Phi->isPHI();
++Phi) {
// This value for this PHI node is recorded in PHINodesToUpdate.
for (unsigned pn = 0; ; ++pn) {
@@ -1324,8 +1341,7 @@ static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,
/// isNonImmUse - Start searching from Root up the DAG to check is Def can
/// be reached. Return true if that's the case. However, ignore direct uses
/// by ImmedUse (which would be U in the example illustrated in
-/// IsLegalAndProfitableToFold) and by Root (which can happen in the store
-/// case).
+/// IsLegalToFold) and by Root (which can happen in the store case).
/// FIXME: to be really generic, we should allow direct use by any node
/// that is being folded. But realisticly since we only fold loads which
/// have one non-chain use, we only need to watch out for load/op/store
@@ -1336,11 +1352,17 @@ static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) {
return findNonImmUse(Root, Def, ImmedUse, Root, Visited);
}
-/// IsLegalAndProfitableToFold - Returns true if the specific operand node N of
-/// U can be folded during instruction selection that starts at Root and
-/// folding N is profitable.
-bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const {
+/// IsProfitableToFold - Returns true if it's profitable to fold the specific
+/// operand node N of U during instruction selection that starts at Root.
+bool SelectionDAGISel::IsProfitableToFold(SDValue N, SDNode *U,
+ SDNode *Root) const {
+ if (OptLevel == CodeGenOpt::None) return false;
+ return N.hasOneUse();
+}
+
+/// IsLegalToFold - Returns true if the specific operand node N of
+/// U can be folded during instruction selection that starts at Root.
+bool SelectionDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const {
if (OptLevel == CodeGenOpt::None) return false;
// If Root use can somehow reach N through a path that that doesn't contain
@@ -1394,7 +1416,7 @@ bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
VT = Root->getValueType(Root->getNumValues()-1);
}
- return !isNonImmUse(Root, N, U);
+ return !isNonImmUse(Root, N.getNode(), U);
}
SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) {
@@ -1410,15 +1432,14 @@ SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) {
}
SDNode *SelectionDAGISel::Select_UNDEF(SDNode *N) {
- return CurDAG->SelectNodeTo(N, TargetInstrInfo::IMPLICIT_DEF,
- N->getValueType(0));
+ return CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF,N->getValueType(0));
}
SDNode *SelectionDAGISel::Select_EH_LABEL(SDNode *N) {
SDValue Chain = N->getOperand(0);
unsigned C = cast<LabelSDNode>(N)->getLabelID();
SDValue Tmp = CurDAG->getTargetConstant(C, MVT::i32);
- return CurDAG->SelectNodeTo(N, TargetInstrInfo::EH_LABEL,
+ return CurDAG->SelectNodeTo(N, TargetOpcode::EH_LABEL,
MVT::Other, Tmp, Chain);
}
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 81c51c4..e88af4f 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -13,6 +13,7 @@
#include "llvm/Target/TargetLowering.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
@@ -21,6 +22,8 @@
#include "llvm/GlobalVariable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
@@ -507,7 +510,6 @@ TargetLowering::TargetLowering(TargetMachine &tm,TargetLoweringObjectFile *tlof)
setOperationAction(ISD::TRAP, MVT::Other, Expand);
IsLittleEndian = TD->isLittleEndian();
- UsesGlobalOffsetTable = false;
ShiftAmountTy = PointerTy = MVT::getIntegerVT(8*TD->getPointerSize());
memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*));
memset(TargetDAGCombineArray, 0, array_lengthof(TargetDAGCombineArray));
@@ -538,6 +540,24 @@ TargetLowering::~TargetLowering() {
delete &TLOF;
}
+/// canOpTrap - Returns true if the operation can trap for the value type.
+/// VT must be a legal type.
+bool TargetLowering::canOpTrap(unsigned Op, EVT VT) const {
+ assert(isTypeLegal(VT));
+ switch (Op) {
+ default:
+ return false;
+ case ISD::FDIV:
+ case ISD::FREM:
+ case ISD::SDIV:
+ case ISD::UDIV:
+ case ISD::SREM:
+ case ISD::UREM:
+ return true;
+ }
+}
+
+
static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT,
unsigned &NumIntermediates,
EVT &RegisterVT,
@@ -682,7 +702,7 @@ void TargetLowering::computeRegisterProperties() {
for (unsigned nVT = i+1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {
EVT SVT = (MVT::SimpleValueType)nVT;
if (isTypeLegal(SVT) && SVT.getVectorElementType() == EltVT &&
- SVT.getVectorNumElements() > NElts) {
+ SVT.getVectorNumElements() > NElts && NElts != 1) {
TransformToType[i] = SVT;
ValueTypeActions.setTypeAction(VT, Promote);
IsLegalWiderType = true;
@@ -793,13 +813,40 @@ unsigned TargetLowering::getByValTypeAlignment(const Type *Ty) const {
return TD->getCallFrameTypeAlignment(Ty);
}
+/// getJumpTableEncoding - Return the entry encoding for a jump table in the
+/// current function. The returned value is a member of the
+/// MachineJumpTableInfo::JTEntryKind enum.
+unsigned TargetLowering::getJumpTableEncoding() const {
+ // In non-pic modes, just use the address of a block.
+ if (getTargetMachine().getRelocationModel() != Reloc::PIC_)
+ return MachineJumpTableInfo::EK_BlockAddress;
+
+ // In PIC mode, if the target supports a GPRel32 directive, use it.
+ if (getTargetMachine().getMCAsmInfo()->getGPRel32Directive() != 0)
+ return MachineJumpTableInfo::EK_GPRel32BlockAddress;
+
+ // Otherwise, use a label difference.
+ return MachineJumpTableInfo::EK_LabelDifference32;
+}
+
SDValue TargetLowering::getPICJumpTableRelocBase(SDValue Table,
SelectionDAG &DAG) const {
- if (usesGlobalOffsetTable())
+ // If our PIC model is GP relative, use the global offset table as the base.
+ if (getJumpTableEncoding() == MachineJumpTableInfo::EK_GPRel32BlockAddress)
return DAG.getGLOBAL_OFFSET_TABLE(getPointerTy());
return Table;
}
+/// getPICJumpTableRelocBaseExpr - This returns the relocation base for the
+/// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an
+/// MCExpr.
+const MCExpr *
+TargetLowering::getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
+ unsigned JTI,MCContext &Ctx) const{
+ // The normal PIC reloc base is the label at the start of the jump table.
+ return MCSymbolRefExpr::Create(MF->getJTISymbol(JTI, Ctx), Ctx);
+}
+
bool
TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
// Assume that everything is safe in static mode.
@@ -1669,7 +1716,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
SDValue NewLoad = DAG.getLoad(newVT, dl, Lod->getChain(), Ptr,
Lod->getSrcValue(),
Lod->getSrcValueOffset() + bestOffset,
- false, NewAlign);
+ false, false, NewAlign);
return DAG.getSetCC(dl, VT,
DAG.getNode(ISD::AND, dl, newVT, NewLoad,
DAG.getConstant(bestMask.trunc(bestWidth),
@@ -2337,7 +2384,7 @@ getRegForInlineAsmConstraint(const std::string &Constraint,
E = RI->regclass_end(); RCI != E; ++RCI) {
const TargetRegisterClass *RC = *RCI;
- // If none of the the value types for this register class are valid, we
+ // If none of the value types for this register class are valid, we
// can't use it. For example, 64-bit reg classes on 32-bit targets.
bool isLegal = false;
for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end();
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp
index 27d429b..e7b0cff 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.cpp
+++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp
@@ -197,7 +197,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA,
SlotIndex FillerStart = ValLR->end, FillerEnd = BLR->start;
// We are about to delete CopyMI, so need to remove it as the 'instruction
- // that defines this value #'. Update the the valnum with the new defining
+ // that defines this value #'. Update the valnum with the new defining
// instruction #.
BValNo->def = FillerStart;
BValNo->setCopy(0);
@@ -375,8 +375,9 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
// If some of the uses of IntA.reg is already coalesced away, return false.
// It's not possible to determine whether it's safe to perform the coalescing.
- for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(IntA.reg),
- UE = mri_->use_end(); UI != UE; ++UI) {
+ for (MachineRegisterInfo::use_nodbg_iterator UI =
+ mri_->use_nodbg_begin(IntA.reg),
+ UE = mri_->use_nodbg_end(); UI != UE; ++UI) {
MachineInstr *UseMI = &*UI;
SlotIndex UseIdx = li_->getInstructionIndex(UseMI);
LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx);
@@ -430,6 +431,12 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
++UI;
if (JoinedCopies.count(UseMI))
continue;
+ if (UseMI->isDebugValue()) {
+ // FIXME These don't have an instruction index. Not clear we have enough
+ // info to decide whether to do this replacement or not. For now do it.
+ UseMO.setReg(NewReg);
+ continue;
+ }
SlotIndex UseIdx = li_->getInstructionIndex(UseMI).getUseIndex();
LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx);
if (ULR == IntA.end() || ULR->valno != AValNo)
@@ -659,7 +666,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
return false;
if (TID.getNumDefs() != 1)
return false;
- if (DefMI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) {
+ if (!DefMI->isImplicitDef()) {
// Make sure the copy destination register class fits the instruction
// definition register class. The mismatch can happen as a result of earlier
// extract_subreg, insert_subreg, subreg_to_reg coalescing.
@@ -764,11 +771,16 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg,
SubIdx = 0;
}
+ // Copy the register use-list before traversing it. We may be adding operands
+ // and invalidating pointers.
+ SmallVector<std::pair<MachineInstr*, unsigned>, 32> reglist;
for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(SrcReg),
- E = mri_->reg_end(); I != E; ) {
- MachineOperand &O = I.getOperand();
- MachineInstr *UseMI = &*I;
- ++I;
+ E = mri_->reg_end(); I != E; ++I)
+ reglist.push_back(std::make_pair(&*I, I.getOperandNo()));
+
+ for (unsigned N=0; N != reglist.size(); ++N) {
+ MachineInstr *UseMI = reglist[N].first;
+ MachineOperand &O = UseMI->getOperand(reglist[N].second);
unsigned OldSubIdx = O.getSubReg();
if (DstIsPhys) {
unsigned UseDstReg = DstReg;
@@ -789,6 +801,19 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg,
O.setReg(UseDstReg);
O.setSubReg(0);
+ if (OldSubIdx) {
+ // Def and kill of subregister of a virtual register actually defs and
+ // kills the whole register. Add imp-defs and imp-kills as needed.
+ if (O.isDef()) {
+ if(O.isDead())
+ UseMI->addRegisterDead(DstReg, tri_, true);
+ else
+ UseMI->addRegisterDefined(DstReg, tri_);
+ } else if (!O.isUndef() &&
+ (O.isKill() ||
+ UseMI->isRegTiedToDefOperand(&O-&UseMI->getOperand(0))))
+ UseMI->addRegisterKilled(DstReg, tri_, true);
+ }
continue;
}
@@ -1029,8 +1054,9 @@ SimpleRegisterCoalescing::isWinToJoinVRWithSrcPhysReg(MachineInstr *CopyMI,
unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
unsigned Length = li_->getApproximateInstructionCount(DstInt);
if (Length > Threshold &&
- (((float)std::distance(mri_->use_begin(DstInt.reg),
- mri_->use_end()) / Length) < (1.0 / Threshold)))
+ (((float)std::distance(mri_->use_nodbg_begin(DstInt.reg),
+ mri_->use_nodbg_end()) / Length) <
+ (1.0 / Threshold)))
return false;
// If the virtual register live interval extends into a loop, turn down
@@ -1079,15 +1105,16 @@ SimpleRegisterCoalescing::isWinToJoinVRWithDstPhysReg(MachineInstr *CopyMI,
MachineBasicBlock *CopyMBB,
LiveInterval &DstInt,
LiveInterval &SrcInt) {
- // If the virtual register live interval is long but it has low use desity,
+ // If the virtual register live interval is long but it has low use density,
// do not join them, instead mark the physical register as its allocation
// preference.
const TargetRegisterClass *RC = mri_->getRegClass(SrcInt.reg);
unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
unsigned Length = li_->getApproximateInstructionCount(SrcInt);
if (Length > Threshold &&
- (((float)std::distance(mri_->use_begin(SrcInt.reg),
- mri_->use_end()) / Length) < (1.0 / Threshold)))
+ (((float)std::distance(mri_->use_nodbg_begin(SrcInt.reg),
+ mri_->use_nodbg_end()) / Length) <
+ (1.0 / Threshold)))
return false;
if (SrcInt.empty())
@@ -1139,12 +1166,14 @@ SimpleRegisterCoalescing::isWinToJoinCrossClass(unsigned LargeReg,
LiveInterval &SmallInt = li_->getInterval(SmallReg);
unsigned LargeSize = li_->getApproximateInstructionCount(LargeInt);
unsigned SmallSize = li_->getApproximateInstructionCount(SmallInt);
- if (SmallSize > Threshold || LargeSize > Threshold)
- if ((float)std::distance(mri_->use_begin(SmallReg),
- mri_->use_end()) / SmallSize <
- (float)std::distance(mri_->use_begin(LargeReg),
- mri_->use_end()) / LargeSize)
+ if (LargeSize > Threshold) {
+ unsigned SmallUses = std::distance(mri_->use_nodbg_begin(SmallReg),
+ mri_->use_nodbg_end());
+ unsigned LargeUses = std::distance(mri_->use_nodbg_begin(LargeReg),
+ mri_->use_nodbg_end());
+ if (SmallUses*LargeSize < LargeUses*SmallSize)
return false;
+ }
return true;
}
@@ -1164,13 +1193,15 @@ SimpleRegisterCoalescing::HasIncompatibleSubRegDefUse(MachineInstr *CopyMI,
for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(VirtReg),
E = mri_->reg_end(); I != E; ++I) {
MachineOperand &O = I.getOperand();
+ if (O.isDebug())
+ continue;
MachineInstr *MI = &*I;
if (MI == CopyMI || JoinedCopies.count(MI))
continue;
unsigned SubIdx = O.getSubReg();
if (SubIdx && !tri_->getSubReg(PhysReg, SubIdx))
return true;
- if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ if (MI->isExtractSubreg()) {
SubIdx = MI->getOperand(2).getImm();
if (O.isUse() && !tri_->getSubReg(PhysReg, SubIdx))
return true;
@@ -1184,8 +1215,7 @@ SimpleRegisterCoalescing::HasIncompatibleSubRegDefUse(MachineInstr *CopyMI,
return true;
}
}
- if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) {
+ if (MI->isInsertSubreg() || MI->isSubregToReg()) {
SubIdx = MI->getOperand(3).getImm();
if (VirtReg == MI->getOperand(0).getReg()) {
if (!tri_->getSubReg(PhysReg, SubIdx))
@@ -1296,9 +1326,9 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
DEBUG(dbgs() << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI);
unsigned SrcReg, DstReg, SrcSubIdx = 0, DstSubIdx = 0;
- bool isExtSubReg = CopyMI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG;
- bool isInsSubReg = CopyMI->getOpcode() == TargetInstrInfo::INSERT_SUBREG;
- bool isSubRegToReg = CopyMI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG;
+ bool isExtSubReg = CopyMI->isExtractSubreg();
+ bool isInsSubReg = CopyMI->isInsertSubreg();
+ bool isSubRegToReg = CopyMI->isSubregToReg();
unsigned SubIdx = 0;
if (isExtSubReg) {
DstReg = CopyMI->getOperand(0).getReg();
@@ -1551,7 +1581,10 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
(isExtSubReg || DstRC->isASubClass()) &&
!isWinToJoinCrossClass(LargeReg, SmallReg,
allocatableRCRegs_[NewRC].count())) {
- DEBUG(dbgs() << "\tSrc/Dest are different register classes.\n");
+ DEBUG(dbgs() << "\tSrc/Dest are different register classes: "
+ << SrcRC->getName() << "/"
+ << DstRC->getName() << " -> "
+ << NewRC->getName() << ".\n");
// Allow the coalescer to try again in case either side gets coalesced to
// a physical register that's compatible with the other side. e.g.
// r1024 = MOV32to32_ r1025
@@ -1631,8 +1664,8 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
unsigned Length = li_->getApproximateInstructionCount(JoinVInt);
float Ratio = 1.0 / Threshold;
if (Length > Threshold &&
- (((float)std::distance(mri_->use_begin(JoinVReg),
- mri_->use_end()) / Length) < Ratio)) {
+ (((float)std::distance(mri_->use_nodbg_begin(JoinVReg),
+ mri_->use_nodbg_end()) / Length) < Ratio)) {
mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
++numAborts;
DEBUG(dbgs() << "\tMay tie down a physical register, abort!\n");
@@ -1755,6 +1788,23 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
UpdateRegDefsUses(SrcReg, DstReg, SubIdx);
+ // If we have extended the live range of a physical register, make sure we
+ // update live-in lists as well.
+ if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
+ const LiveInterval &VRegInterval = li_->getInterval(SrcReg);
+ SmallVector<MachineBasicBlock*, 16> BlockSeq;
+ for (LiveInterval::const_iterator I = VRegInterval.begin(),
+ E = VRegInterval.end(); I != E; ++I ) {
+ li_->findLiveInMBBs(I->start, I->end, BlockSeq);
+ for (unsigned idx = 0, size = BlockSeq.size(); idx != size; ++idx) {
+ MachineBasicBlock &block = *BlockSeq[idx];
+ if (!block.isLiveIn(DstReg))
+ block.addLiveIn(DstReg);
+ }
+ BlockSeq.clear();
+ }
+ }
+
// SrcReg is guarateed to be the register whose live interval that is
// being merged.
li_->removeInterval(SrcReg);
@@ -1849,11 +1899,11 @@ static bool isValNoDefMove(const MachineInstr *MI, unsigned DR, unsigned SR,
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
;
- else if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ else if (MI->isExtractSubreg()) {
DstReg = MI->getOperand(0).getReg();
SrcReg = MI->getOperand(1).getReg();
- } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
- MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
+ } else if (MI->isSubregToReg() ||
+ MI->isInsertSubreg()) {
DstReg = MI->getOperand(0).getReg();
SrcReg = MI->getOperand(2).getReg();
} else
@@ -2425,16 +2475,15 @@ void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
// If this isn't a copy nor a extract_subreg, we can't join intervals.
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
bool isInsUndef = false;
- if (Inst->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ if (Inst->isExtractSubreg()) {
DstReg = Inst->getOperand(0).getReg();
SrcReg = Inst->getOperand(1).getReg();
- } else if (Inst->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
+ } else if (Inst->isInsertSubreg()) {
DstReg = Inst->getOperand(0).getReg();
SrcReg = Inst->getOperand(2).getReg();
if (Inst->getOperand(1).isUndef())
isInsUndef = true;
- } else if (Inst->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- Inst->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) {
+ } else if (Inst->isInsertSubreg() || Inst->isSubregToReg()) {
DstReg = Inst->getOperand(0).getReg();
SrcReg = Inst->getOperand(2).getReg();
} else if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
@@ -2549,8 +2598,8 @@ SimpleRegisterCoalescing::differingRegisterClasses(unsigned RegA,
return !RegClassA->contains(RegB);
}
-/// lastRegisterUse - Returns the last use of the specific register between
-/// cycles Start and End or NULL if there are no uses.
+/// lastRegisterUse - Returns the last (non-debug) use of the specific register
+/// between cycles Start and End or NULL if there are no uses.
MachineOperand *
SimpleRegisterCoalescing::lastRegisterUse(SlotIndex Start,
SlotIndex End,
@@ -2559,8 +2608,8 @@ SimpleRegisterCoalescing::lastRegisterUse(SlotIndex Start,
UseIdx = SlotIndex();
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
MachineOperand *LastUse = NULL;
- for (MachineRegisterInfo::use_iterator I = mri_->use_begin(Reg),
- E = mri_->use_end(); I != E; ++I) {
+ for (MachineRegisterInfo::use_nodbg_iterator I = mri_->use_nodbg_begin(Reg),
+ E = mri_->use_nodbg_end(); I != E; ++I) {
MachineOperand &Use = I.getOperand();
MachineInstr *UseMI = Use.getParent();
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
@@ -2670,10 +2719,8 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
// Delete all coalesced copies.
bool DoDelete = true;
if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
- assert((MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
- MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) &&
- "Unrecognized copy instruction");
+ assert((MI->isExtractSubreg() || MI->isInsertSubreg() ||
+ MI->isSubregToReg()) && "Unrecognized copy instruction");
DstReg = MI->getOperand(0).getReg();
if (TargetRegisterInfo::isPhysicalRegister(DstReg))
// Do not delete extract_subreg, insert_subreg of physical
diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp
index 9558933..8d4d1b2 100644
--- a/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/lib/CodeGen/SjLjEHPrepare.cpp
@@ -51,6 +51,7 @@ namespace {
Value *PersonalityFn;
Constant *SelectorFn;
Constant *ExceptionFn;
+ Constant *CallSiteFn;
Value *CallSite;
public:
@@ -116,6 +117,7 @@ bool SjLjEHPass::doInitialization(Module &M) {
LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda);
SelectorFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_selector);
ExceptionFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_exception);
+ CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite);
PersonalityFn = 0;
return true;
@@ -143,15 +145,14 @@ void SjLjEHPass::markInvokeCallSite(InvokeInst *II, unsigned InvokeNo,
}
}
- // Insert a store of the invoke num before the invoke and store zero into the
- // location afterward.
+ // Insert a store of the invoke num before the invoke
new StoreInst(CallSiteNoC, CallSite, true, II); // volatile
+ CallInst::Create(CallSiteFn, CallSiteNoC, "", II);
// Add a switch case to our unwind block.
CatchSwitch->addCase(SwitchValC, II->getUnwindDest());
- // We still want this to look like an invoke so we emit the LSDA properly
- // FIXME: ??? Or will this cause strangeness with mis-matched IDs like
- // when it was in the front end?
+ // We still want this to look like an invoke so we emit the LSDA properly,
+ // so we don't transform the invoke into a call here.
}
/// MarkBlocksLiveIn - Insert BB and all of its predescessors into LiveBBs until
diff --git a/lib/CodeGen/SlotIndexes.cpp b/lib/CodeGen/SlotIndexes.cpp
index a23efb2..6110ef5 100644
--- a/lib/CodeGen/SlotIndexes.cpp
+++ b/lib/CodeGen/SlotIndexes.cpp
@@ -95,7 +95,7 @@ bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) {
push_back(createEntry(0, index));
- // Iterate over the the function.
+ // Iterate over the function.
for (MachineFunction::iterator mbbItr = mf->begin(), mbbEnd = mf->end();
mbbItr != mbbEnd; ++mbbItr) {
MachineBasicBlock *mbb = &*mbbItr;
@@ -107,8 +107,8 @@ bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) {
for (MachineBasicBlock::iterator miItr = mbb->begin(), miEnd = mbb->end();
miItr != miEnd; ++miItr) {
- MachineInstr *mi = &*miItr;
- if (mi->getOpcode()==TargetInstrInfo::DEBUG_VALUE)
+ MachineInstr *mi = miItr;
+ if (mi->isDebugValue())
continue;
if (miItr == mbb->getFirstTerminator()) {
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp
index 48bb5af..8a6a727 100644
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -113,7 +113,7 @@ bool StackProtector::RequiresStackProtector() const {
if (const ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType())) {
// We apparently only care about character arrays.
- if (!AT->getElementType()->isInteger(8))
+ if (!AT->getElementType()->isIntegerTy(8))
continue;
// If an array has more than SSPBufferSize bytes of allocated space,
diff --git a/lib/CodeGen/StackSlotColoring.cpp b/lib/CodeGen/StackSlotColoring.cpp
index 2170703..12d38f0 100644
--- a/lib/CodeGen/StackSlotColoring.cpp
+++ b/lib/CodeGen/StackSlotColoring.cpp
@@ -504,10 +504,8 @@ bool StackSlotColoring::PropagateBackward(MachineBasicBlock::iterator MII,
// Abort the use is actually a sub-register def. We don't have enough
// information to figure out if it is really legal.
- if (MO.getSubReg() ||
- TID.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
- TID.getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- TID.getOpcode() == TargetInstrInfo::SUBREG_TO_REG)
+ if (MO.getSubReg() || MII->isExtractSubreg() ||
+ MII->isInsertSubreg() || MII->isSubregToReg())
return false;
const TargetRegisterClass *RC = TID.OpInfo[i].getRegClass(TRI);
@@ -569,8 +567,7 @@ bool StackSlotColoring::PropagateForward(MachineBasicBlock::iterator MII,
// Abort the use is actually a sub-register use. We don't have enough
// information to figure out if it is really legal.
- if (MO.getSubReg() ||
- TID.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)
+ if (MO.getSubReg() || MII->isExtractSubreg())
return false;
const TargetRegisterClass *RC = TID.OpInfo[i].getRegClass(TRI);
diff --git a/lib/CodeGen/StrongPHIElimination.cpp b/lib/CodeGen/StrongPHIElimination.cpp
index bd7cb75..f8f6a55 100644
--- a/lib/CodeGen/StrongPHIElimination.cpp
+++ b/lib/CodeGen/StrongPHIElimination.cpp
@@ -49,7 +49,7 @@ namespace {
std::map<unsigned, std::vector<unsigned> > Stacks;
// Registers in UsedByAnother are PHI nodes that are themselves
- // used as operands to another another PHI node
+ // used as operands to another PHI node
std::set<unsigned> UsedByAnother;
// RenameSets are the is a map from a PHI-defined register
@@ -419,7 +419,7 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) {
// Iterate over all the PHI nodes in this block
MachineBasicBlock::iterator P = MBB->begin();
- while (P != MBB->end() && P->getOpcode() == TargetInstrInfo::PHI) {
+ while (P != MBB->end() && P->isPHI()) {
unsigned DestReg = P->getOperand(0).getReg();
// Don't both doing PHI elimination for dead PHI's.
@@ -452,7 +452,7 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) {
// We don't need to insert copies for implicit_defs.
MachineInstr* DefMI = MRI.getVRegDef(SrcReg);
- if (DefMI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
+ if (DefMI->isImplicitDef())
ProcessedNames.insert(SrcReg);
// Check for trivial interferences via liveness information, allowing us
@@ -470,7 +470,7 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) {
if (isLiveIn(SrcReg, P->getParent(), LI) ||
isLiveOut(P->getOperand(0).getReg(),
MRI.getVRegDef(SrcReg)->getParent(), LI) ||
- ( MRI.getVRegDef(SrcReg)->getOpcode() == TargetInstrInfo::PHI &&
+ ( MRI.getVRegDef(SrcReg)->isPHI() &&
isLiveIn(P->getOperand(0).getReg(),
MRI.getVRegDef(SrcReg)->getParent(), LI) ) ||
ProcessedNames.count(SrcReg) ||
@@ -810,7 +810,7 @@ void StrongPHIElimination::InsertCopies(MachineDomTreeNode* MDTN,
// Rewrite register uses from Stacks
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
I != E; ++I) {
- if (I->getOpcode() == TargetInstrInfo::PHI)
+ if (I->isPHI())
continue;
for (unsigned i = 0; i < I->getNumOperands(); ++i)
@@ -907,8 +907,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) {
// Determine which phi node operands need copies
for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
- if (!I->empty() &&
- I->begin()->getOpcode() == TargetInstrInfo::PHI)
+ if (!I->empty() && I->begin()->isPHI())
processBlock(I);
// Break interferences where two different phis want to coalesce
@@ -996,7 +995,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) {
for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
for (MachineBasicBlock::iterator BI = I->begin(), BE = I->end();
BI != BE; ++BI)
- if (BI->getOpcode() == TargetInstrInfo::PHI)
+ if (BI->isPHI())
phis.push_back(BI);
}
diff --git a/lib/CodeGen/TailDuplication.cpp b/lib/CodeGen/TailDuplication.cpp
index d6860bc..3223e53 100644
--- a/lib/CodeGen/TailDuplication.cpp
+++ b/lib/CodeGen/TailDuplication.cpp
@@ -121,7 +121,7 @@ static void VerifyPHIs(MachineFunction &MF, bool CheckExtra) {
MBB->pred_end());
MachineBasicBlock::iterator MI = MBB->begin();
while (MI != MBB->end()) {
- if (MI->getOpcode() != TargetInstrInfo::PHI)
+ if (!MI->isPHI())
break;
for (SmallSetVector<MachineBasicBlock *, 8>::iterator PI = Preds.begin(),
PE = Preds.end(); PI != PE; ++PI) {
@@ -378,7 +378,7 @@ TailDuplicatePass::UpdateSuccessorsPHIs(MachineBasicBlock *FromBB, bool isDead,
MachineBasicBlock *SuccBB = *SI;
for (MachineBasicBlock::iterator II = SuccBB->begin(), EE = SuccBB->end();
II != EE; ++II) {
- if (II->getOpcode() != TargetInstrInfo::PHI)
+ if (!II->isPHI())
break;
unsigned Idx = 0;
for (unsigned i = 1, e = II->getNumOperands(); i != e; i += 2) {
@@ -403,26 +403,45 @@ TailDuplicatePass::UpdateSuccessorsPHIs(MachineBasicBlock *FromBB, bool isDead,
II->RemoveOperand(i);
}
}
- II->RemoveOperand(Idx+1);
- II->RemoveOperand(Idx);
- }
+ } else
+ Idx = 0;
+
+ // If Idx is set, the operands at Idx and Idx+1 must be removed.
+ // We reuse the location to avoid expensive RemoveOperand calls.
+
DenseMap<unsigned,AvailableValsTy>::iterator LI=SSAUpdateVals.find(Reg);
if (LI != SSAUpdateVals.end()) {
// This register is defined in the tail block.
for (unsigned j = 0, ee = LI->second.size(); j != ee; ++j) {
MachineBasicBlock *SrcBB = LI->second[j].first;
unsigned SrcReg = LI->second[j].second;
- II->addOperand(MachineOperand::CreateReg(SrcReg, false));
- II->addOperand(MachineOperand::CreateMBB(SrcBB));
+ if (Idx != 0) {
+ II->getOperand(Idx).setReg(SrcReg);
+ II->getOperand(Idx+1).setMBB(SrcBB);
+ Idx = 0;
+ } else {
+ II->addOperand(MachineOperand::CreateReg(SrcReg, false));
+ II->addOperand(MachineOperand::CreateMBB(SrcBB));
+ }
}
} else {
// Live in tail block, must also be live in predecessors.
for (unsigned j = 0, ee = TDBBs.size(); j != ee; ++j) {
MachineBasicBlock *SrcBB = TDBBs[j];
- II->addOperand(MachineOperand::CreateReg(Reg, false));
- II->addOperand(MachineOperand::CreateMBB(SrcBB));
+ if (Idx != 0) {
+ II->getOperand(Idx).setReg(Reg);
+ II->getOperand(Idx+1).setMBB(SrcBB);
+ Idx = 0;
+ } else {
+ II->addOperand(MachineOperand::CreateReg(Reg, false));
+ II->addOperand(MachineOperand::CreateMBB(SrcBB));
+ }
}
}
+ if (Idx != 0) {
+ II->RemoveOperand(Idx+1);
+ II->RemoveOperand(Idx);
+ }
}
}
}
@@ -476,7 +495,7 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF,
if (InstrCount == MaxDuplicateCount) return false;
// Remember if we saw a call.
if (I->getDesc().isCall()) HasCall = true;
- if (I->getOpcode() != TargetInstrInfo::PHI)
+ if (!I->isPHI())
InstrCount += 1;
}
// Heuristically, don't tail-duplicate calls if it would expand code size,
@@ -528,7 +547,7 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF,
while (I != TailBB->end()) {
MachineInstr *MI = &*I;
++I;
- if (MI->getOpcode() == TargetInstrInfo::PHI) {
+ if (MI->isPHI()) {
// Replace the uses of the def of the PHI with the register coming
// from PredBB.
ProcessPHI(MI, TailBB, PredBB, LocalVRMap, CopyInfos);
@@ -580,7 +599,7 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF,
SmallVector<std::pair<unsigned,unsigned>, 4> CopyInfos;
MachineBasicBlock::iterator I = TailBB->begin();
// Process PHI instructions first.
- while (I != TailBB->end() && I->getOpcode() == TargetInstrInfo::PHI) {
+ while (I != TailBB->end() && I->isPHI()) {
// Replace the uses of the def of the PHI with the register coming
// from PredBB.
MachineInstr *MI = &*I++;
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
new file mode 100644
index 0000000..190b533
--- /dev/null
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -0,0 +1,874 @@
+//===-- llvm/CodeGen/TargetLoweringObjectFileImpl.cpp - Object File Info --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// ELF
+//===----------------------------------------------------------------------===//
+typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
+
+TargetLoweringObjectFileELF::~TargetLoweringObjectFileELF() {
+ // If we have the section uniquing map, free it.
+ delete (ELFUniqueMapTy*)UniquingMap;
+}
+
+const MCSection *TargetLoweringObjectFileELF::
+getELFSection(StringRef Section, unsigned Type, unsigned Flags,
+ SectionKind Kind, bool IsExplicit) const {
+ if (UniquingMap == 0)
+ UniquingMap = new ELFUniqueMapTy();
+ ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)UniquingMap;
+
+ // Do the lookup, if we have a hit, return it.
+ const MCSectionELF *&Entry = Map[Section];
+ if (Entry) return Entry;
+
+ return Entry = MCSectionELF::Create(Section, Type, Flags, Kind, IsExplicit,
+ getContext());
+}
+
+void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
+ const TargetMachine &TM) {
+ if (UniquingMap != 0)
+ ((ELFUniqueMapTy*)UniquingMap)->clear();
+ TargetLoweringObjectFile::Initialize(Ctx, TM);
+
+ BSSSection =
+ getELFSection(".bss", MCSectionELF::SHT_NOBITS,
+ MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
+ SectionKind::getBSS());
+
+ TextSection =
+ getELFSection(".text", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_EXECINSTR | MCSectionELF::SHF_ALLOC,
+ SectionKind::getText());
+
+ DataSection =
+ getELFSection(".data", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
+ SectionKind::getDataRel());
+
+ ReadOnlySection =
+ getELFSection(".rodata", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC,
+ SectionKind::getReadOnly());
+
+ TLSDataSection =
+ getELFSection(".tdata", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
+ MCSectionELF::SHF_WRITE, SectionKind::getThreadData());
+
+ TLSBSSSection =
+ getELFSection(".tbss", MCSectionELF::SHT_NOBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
+ MCSectionELF::SHF_WRITE, SectionKind::getThreadBSS());
+
+ DataRelSection =
+ getELFSection(".data.rel", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+
+ DataRelLocalSection =
+ getELFSection(".data.rel.local", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRelLocal());
+
+ DataRelROSection =
+ getELFSection(".data.rel.ro", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getReadOnlyWithRel());
+
+ DataRelROLocalSection =
+ getELFSection(".data.rel.ro.local", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getReadOnlyWithRelLocal());
+
+ MergeableConst4Section =
+ getELFSection(".rodata.cst4", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
+ SectionKind::getMergeableConst4());
+
+ MergeableConst8Section =
+ getELFSection(".rodata.cst8", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
+ SectionKind::getMergeableConst8());
+
+ MergeableConst16Section =
+ getELFSection(".rodata.cst16", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
+ SectionKind::getMergeableConst16());
+
+ StaticCtorSection =
+ getELFSection(".ctors", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+
+ StaticDtorSection =
+ getELFSection(".dtors", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+
+ // Exception Handling Sections.
+
+ // FIXME: We're emitting LSDA info into a readonly section on ELF, even though
+ // it contains relocatable pointers. In PIC mode, this is probably a big
+ // runtime hit for C++ apps. Either the contents of the LSDA need to be
+ // adjusted or this should be a data section.
+ LSDASection =
+ getELFSection(".gcc_except_table", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC, SectionKind::getReadOnly());
+ EHFrameSection =
+ getELFSection(".eh_frame", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+
+ // Debug Info Sections.
+ DwarfAbbrevSection =
+ getELFSection(".debug_abbrev", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfInfoSection =
+ getELFSection(".debug_info", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfLineSection =
+ getELFSection(".debug_line", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfFrameSection =
+ getELFSection(".debug_frame", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ getELFSection(".debug_pubnames", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfPubTypesSection =
+ getELFSection(".debug_pubtypes", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfStrSection =
+ getELFSection(".debug_str", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfLocSection =
+ getELFSection(".debug_loc", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfARangesSection =
+ getELFSection(".debug_aranges", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfRangesSection =
+ getELFSection(".debug_ranges", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfMacroInfoSection =
+ getELFSection(".debug_macinfo", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+}
+
+
+static SectionKind
+getELFKindForNamedSection(StringRef Name, SectionKind K) {
+ if (Name.empty() || Name[0] != '.') return K;
+
+ // Some lame default implementation based on some magic section names.
+ if (Name == ".bss" ||
+ Name.startswith(".bss.") ||
+ Name.startswith(".gnu.linkonce.b.") ||
+ Name.startswith(".llvm.linkonce.b.") ||
+ Name == ".sbss" ||
+ Name.startswith(".sbss.") ||
+ Name.startswith(".gnu.linkonce.sb.") ||
+ Name.startswith(".llvm.linkonce.sb."))
+ return SectionKind::getBSS();
+
+ if (Name == ".tdata" ||
+ Name.startswith(".tdata.") ||
+ Name.startswith(".gnu.linkonce.td.") ||
+ Name.startswith(".llvm.linkonce.td."))
+ return SectionKind::getThreadData();
+
+ if (Name == ".tbss" ||
+ Name.startswith(".tbss.") ||
+ Name.startswith(".gnu.linkonce.tb.") ||
+ Name.startswith(".llvm.linkonce.tb."))
+ return SectionKind::getThreadBSS();
+
+ return K;
+}
+
+
+static unsigned getELFSectionType(StringRef Name, SectionKind K) {
+
+ if (Name == ".init_array")
+ return MCSectionELF::SHT_INIT_ARRAY;
+
+ if (Name == ".fini_array")
+ return MCSectionELF::SHT_FINI_ARRAY;
+
+ if (Name == ".preinit_array")
+ return MCSectionELF::SHT_PREINIT_ARRAY;
+
+ if (K.isBSS() || K.isThreadBSS())
+ return MCSectionELF::SHT_NOBITS;
+
+ return MCSectionELF::SHT_PROGBITS;
+}
+
+
+static unsigned
+getELFSectionFlags(SectionKind K) {
+ unsigned Flags = 0;
+
+ if (!K.isMetadata())
+ Flags |= MCSectionELF::SHF_ALLOC;
+
+ if (K.isText())
+ Flags |= MCSectionELF::SHF_EXECINSTR;
+
+ if (K.isWriteable())
+ Flags |= MCSectionELF::SHF_WRITE;
+
+ if (K.isThreadLocal())
+ Flags |= MCSectionELF::SHF_TLS;
+
+ // K.isMergeableConst() is left out to honour PR4650
+ if (K.isMergeableCString() || K.isMergeableConst4() ||
+ K.isMergeableConst8() || K.isMergeableConst16())
+ Flags |= MCSectionELF::SHF_MERGE;
+
+ if (K.isMergeableCString())
+ Flags |= MCSectionELF::SHF_STRINGS;
+
+ return Flags;
+}
+
+
+const MCSection *TargetLoweringObjectFileELF::
+getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ StringRef SectionName = GV->getSection();
+
+ // Infer section flags from the section name if we can.
+ Kind = getELFKindForNamedSection(SectionName, Kind);
+
+ return getELFSection(SectionName,
+ getELFSectionType(SectionName, Kind),
+ getELFSectionFlags(Kind), Kind, true);
+}
+
+static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
+ if (Kind.isText()) return ".gnu.linkonce.t.";
+ if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
+
+ if (Kind.isThreadData()) return ".gnu.linkonce.td.";
+ if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
+
+ if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
+ if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
+ if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
+ if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
+
+ assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+ return ".gnu.linkonce.d.rel.ro.";
+}
+
+const MCSection *TargetLoweringObjectFileELF::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+
+ // If this global is linkonce/weak and the target handles this by emitting it
+ // into a 'uniqued' section name, create and return the section now.
+ if (GV->isWeakForLinker() && !Kind.isCommon() && !Kind.isBSS()) {
+ const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
+ SmallString<128> Name;
+ Name.append(Prefix, Prefix+strlen(Prefix));
+ Mang->getNameWithPrefix(Name, GV, false);
+ return getELFSection(Name.str(), getELFSectionType(Name.str(), Kind),
+ getELFSectionFlags(Kind), Kind);
+ }
+
+ if (Kind.isText()) return TextSection;
+
+ if (Kind.isMergeable1ByteCString() ||
+ Kind.isMergeable2ByteCString() ||
+ Kind.isMergeable4ByteCString()) {
+
+ // We also need alignment here.
+ // FIXME: this is getting the alignment of the character, not the
+ // alignment of the global!
+ unsigned Align =
+ TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV));
+
+ const char *SizeSpec = ".rodata.str1.";
+ if (Kind.isMergeable2ByteCString())
+ SizeSpec = ".rodata.str2.";
+ else if (Kind.isMergeable4ByteCString())
+ SizeSpec = ".rodata.str4.";
+ else
+ assert(Kind.isMergeable1ByteCString() && "unknown string width");
+
+
+ std::string Name = SizeSpec + utostr(Align);
+ return getELFSection(Name, MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC |
+ MCSectionELF::SHF_MERGE |
+ MCSectionELF::SHF_STRINGS,
+ Kind);
+ }
+
+ if (Kind.isMergeableConst()) {
+ if (Kind.isMergeableConst4() && MergeableConst4Section)
+ return MergeableConst4Section;
+ if (Kind.isMergeableConst8() && MergeableConst8Section)
+ return MergeableConst8Section;
+ if (Kind.isMergeableConst16() && MergeableConst16Section)
+ return MergeableConst16Section;
+ return ReadOnlySection; // .const
+ }
+
+ if (Kind.isReadOnly()) return ReadOnlySection;
+
+ if (Kind.isThreadData()) return TLSDataSection;
+ if (Kind.isThreadBSS()) return TLSBSSSection;
+
+ // Note: we claim that common symbols are put in BSSSection, but they are
+ // really emitted with the magic .comm directive, which creates a symbol table
+ // entry but not a section.
+ if (Kind.isBSS() || Kind.isCommon()) return BSSSection;
+
+ if (Kind.isDataNoRel()) return DataSection;
+ if (Kind.isDataRelLocal()) return DataRelLocalSection;
+ if (Kind.isDataRel()) return DataRelSection;
+ if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
+
+ assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+ return DataRelROSection;
+}
+
+/// getSectionForConstant - Given a mergeable constant with the
+/// specified size and relocation information, return a section that it
+/// should be placed in.
+const MCSection *TargetLoweringObjectFileELF::
+getSectionForConstant(SectionKind Kind) const {
+ if (Kind.isMergeableConst4() && MergeableConst4Section)
+ return MergeableConst4Section;
+ if (Kind.isMergeableConst8() && MergeableConst8Section)
+ return MergeableConst8Section;
+ if (Kind.isMergeableConst16() && MergeableConst16Section)
+ return MergeableConst16Section;
+ if (Kind.isReadOnly())
+ return ReadOnlySection;
+
+ if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
+ assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+ return DataRelROSection;
+}
+
+const MCExpr *TargetLoweringObjectFileELF::
+getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding) const {
+
+ if (Encoding & dwarf::DW_EH_PE_indirect) {
+ MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
+
+ SmallString<128> Name;
+ Mang->getNameWithPrefix(Name, GV, true);
+ Name += ".DW.stub";
+
+ // Add information about the stub reference to ELFMMI so that the stub
+ // gets emitted by the asmprinter.
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
+ MCSymbol *&StubSym = ELFMMI.getGVStubEntry(Sym);
+ if (StubSym == 0) {
+ Name.clear();
+ Mang->getNameWithPrefix(Name, GV, false);
+ StubSym = getContext().GetOrCreateSymbol(Name.str());
+ }
+
+ return TargetLoweringObjectFile::
+ getSymbolForDwarfReference(Sym, MMI,
+ Encoding & ~dwarf::DW_EH_PE_indirect);
+ }
+
+ return TargetLoweringObjectFile::
+ getSymbolForDwarfGlobalReference(GV, Mang, MMI, Encoding);
+}
+
+//===----------------------------------------------------------------------===//
+// MachO
+//===----------------------------------------------------------------------===//
+
+typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
+
+TargetLoweringObjectFileMachO::~TargetLoweringObjectFileMachO() {
+ // If we have the MachO uniquing map, free it.
+ delete (MachOUniqueMapTy*)UniquingMap;
+}
+
+
+const MCSectionMachO *TargetLoweringObjectFileMachO::
+getMachOSection(StringRef Segment, StringRef Section,
+ unsigned TypeAndAttributes,
+ unsigned Reserved2, SectionKind Kind) const {
+ // We unique sections by their segment/section pair. The returned section
+ // may not have the same flags as the requested section, if so this should be
+ // diagnosed by the client as an error.
+
+ // Create the map if it doesn't already exist.
+ if (UniquingMap == 0)
+ UniquingMap = new MachOUniqueMapTy();
+ MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)UniquingMap;
+
+ // Form the name to look up.
+ SmallString<64> Name;
+ Name += Segment;
+ Name.push_back(',');
+ Name += Section;
+
+ // Do the lookup, if we have a hit, return it.
+ const MCSectionMachO *&Entry = Map[Name.str()];
+ if (Entry) return Entry;
+
+ // Otherwise, return a new section.
+ return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes,
+ Reserved2, Kind, getContext());
+}
+
+
+void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
+ const TargetMachine &TM) {
+ if (UniquingMap != 0)
+ ((MachOUniqueMapTy*)UniquingMap)->clear();
+ TargetLoweringObjectFile::Initialize(Ctx, TM);
+
+ TextSection // .text
+ = getMachOSection("__TEXT", "__text",
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ SectionKind::getText());
+ DataSection // .data
+ = getMachOSection("__DATA", "__data", 0, SectionKind::getDataRel());
+
+ CStringSection // .cstring
+ = getMachOSection("__TEXT", "__cstring", MCSectionMachO::S_CSTRING_LITERALS,
+ SectionKind::getMergeable1ByteCString());
+ UStringSection
+ = getMachOSection("__TEXT","__ustring", 0,
+ SectionKind::getMergeable2ByteCString());
+ FourByteConstantSection // .literal4
+ = getMachOSection("__TEXT", "__literal4", MCSectionMachO::S_4BYTE_LITERALS,
+ SectionKind::getMergeableConst4());
+ EightByteConstantSection // .literal8
+ = getMachOSection("__TEXT", "__literal8", MCSectionMachO::S_8BYTE_LITERALS,
+ SectionKind::getMergeableConst8());
+
+ // ld_classic doesn't support .literal16 in 32-bit mode, and ld64 falls back
+ // to using it in -static mode.
+ SixteenByteConstantSection = 0;
+ if (TM.getRelocationModel() != Reloc::Static &&
+ TM.getTargetData()->getPointerSize() == 32)
+ SixteenByteConstantSection = // .literal16
+ getMachOSection("__TEXT", "__literal16",MCSectionMachO::S_16BYTE_LITERALS,
+ SectionKind::getMergeableConst16());
+
+ ReadOnlySection // .const
+ = getMachOSection("__TEXT", "__const", 0, SectionKind::getReadOnly());
+
+ TextCoalSection
+ = getMachOSection("__TEXT", "__textcoal_nt",
+ MCSectionMachO::S_COALESCED |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ SectionKind::getText());
+ ConstTextCoalSection
+ = getMachOSection("__TEXT", "__const_coal", MCSectionMachO::S_COALESCED,
+ SectionKind::getText());
+ ConstDataCoalSection
+ = getMachOSection("__DATA","__const_coal", MCSectionMachO::S_COALESCED,
+ SectionKind::getText());
+ ConstDataSection // .const_data
+ = getMachOSection("__DATA", "__const", 0,
+ SectionKind::getReadOnlyWithRel());
+ DataCoalSection
+ = getMachOSection("__DATA","__datacoal_nt", MCSectionMachO::S_COALESCED,
+ SectionKind::getDataRel());
+ DataCommonSection
+ = getMachOSection("__DATA","__common", MCSectionMachO::S_ZEROFILL,
+ SectionKind::getBSS());
+ DataBSSSection
+ = getMachOSection("__DATA","__bss", MCSectionMachO::S_ZEROFILL,
+ SectionKind::getBSS());
+
+
+ LazySymbolPointerSection
+ = getMachOSection("__DATA", "__la_symbol_ptr",
+ MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
+ SectionKind::getMetadata());
+ NonLazySymbolPointerSection
+ = getMachOSection("__DATA", "__nl_symbol_ptr",
+ MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
+ SectionKind::getMetadata());
+
+ if (TM.getRelocationModel() == Reloc::Static) {
+ StaticCtorSection
+ = getMachOSection("__TEXT", "__constructor", 0,SectionKind::getDataRel());
+ StaticDtorSection
+ = getMachOSection("__TEXT", "__destructor", 0, SectionKind::getDataRel());
+ } else {
+ StaticCtorSection
+ = getMachOSection("__DATA", "__mod_init_func",
+ MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
+ SectionKind::getDataRel());
+ StaticDtorSection
+ = getMachOSection("__DATA", "__mod_term_func",
+ MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
+ SectionKind::getDataRel());
+ }
+
+ // Exception Handling.
+ LSDASection = getMachOSection("__DATA", "__gcc_except_tab", 0,
+ SectionKind::getDataRel());
+ EHFrameSection =
+ getMachOSection("__TEXT", "__eh_frame",
+ MCSectionMachO::S_COALESCED |
+ MCSectionMachO::S_ATTR_NO_TOC |
+ MCSectionMachO::S_ATTR_STRIP_STATIC_SYMS |
+ MCSectionMachO::S_ATTR_LIVE_SUPPORT,
+ SectionKind::getReadOnly());
+
+ // Debug Information.
+ DwarfAbbrevSection =
+ getMachOSection("__DWARF", "__debug_abbrev", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfInfoSection =
+ getMachOSection("__DWARF", "__debug_info", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfLineSection =
+ getMachOSection("__DWARF", "__debug_line", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfFrameSection =
+ getMachOSection("__DWARF", "__debug_frame", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ getMachOSection("__DWARF", "__debug_pubnames", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfPubTypesSection =
+ getMachOSection("__DWARF", "__debug_pubtypes", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfStrSection =
+ getMachOSection("__DWARF", "__debug_str", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfLocSection =
+ getMachOSection("__DWARF", "__debug_loc", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfARangesSection =
+ getMachOSection("__DWARF", "__debug_aranges", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfRangesSection =
+ getMachOSection("__DWARF", "__debug_ranges", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfMacroInfoSection =
+ getMachOSection("__DWARF", "__debug_macinfo", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfDebugInlineSection =
+ getMachOSection("__DWARF", "__debug_inlined", MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+}
+
+const MCSection *TargetLoweringObjectFileMachO::
+getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ // Parse the section specifier and create it if valid.
+ StringRef Segment, Section;
+ unsigned TAA, StubSize;
+ std::string ErrorCode =
+ MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section,
+ TAA, StubSize);
+ if (!ErrorCode.empty()) {
+ // If invalid, report the error with llvm_report_error.
+ llvm_report_error("Global variable '" + GV->getNameStr() +
+ "' has an invalid section specifier '" + GV->getSection()+
+ "': " + ErrorCode + ".");
+ // Fall back to dropping it into the data section.
+ return DataSection;
+ }
+
+ // Get the section.
+ const MCSectionMachO *S =
+ getMachOSection(Segment, Section, TAA, StubSize, Kind);
+
+ // Okay, now that we got the section, verify that the TAA & StubSize agree.
+ // If the user declared multiple globals with different section flags, we need
+ // to reject it here.
+ if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) {
+ // If invalid, report the error with llvm_report_error.
+ llvm_report_error("Global variable '" + GV->getNameStr() +
+ "' section type or attributes does not match previous"
+ " section specifier");
+ }
+
+ return S;
+}
+
+const MCSection *TargetLoweringObjectFileMachO::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS");
+
+ if (Kind.isText())
+ return GV->isWeakForLinker() ? TextCoalSection : TextSection;
+
+ // If this is weak/linkonce, put this in a coalescable section, either in text
+ // or data depending on if it is writable.
+ if (GV->isWeakForLinker()) {
+ if (Kind.isReadOnly())
+ return ConstTextCoalSection;
+ return DataCoalSection;
+ }
+
+ // FIXME: Alignment check should be handled by section classifier.
+ if (Kind.isMergeable1ByteCString() ||
+ Kind.isMergeable2ByteCString()) {
+ if (TM.getTargetData()->getPreferredAlignment(
+ cast<GlobalVariable>(GV)) < 32) {
+ if (Kind.isMergeable1ByteCString())
+ return CStringSection;
+ assert(Kind.isMergeable2ByteCString());
+ return UStringSection;
+ }
+ }
+
+ if (Kind.isMergeableConst()) {
+ if (Kind.isMergeableConst4())
+ return FourByteConstantSection;
+ if (Kind.isMergeableConst8())
+ return EightByteConstantSection;
+ if (Kind.isMergeableConst16() && SixteenByteConstantSection)
+ return SixteenByteConstantSection;
+ }
+
+ // Otherwise, if it is readonly, but not something we can specially optimize,
+ // just drop it in .const.
+ if (Kind.isReadOnly())
+ return ReadOnlySection;
+
+ // If this is marked const, put it into a const section. But if the dynamic
+ // linker needs to write to it, put it in the data segment.
+ if (Kind.isReadOnlyWithRel())
+ return ConstDataSection;
+
+ // Put zero initialized globals with strong external linkage in the
+ // DATA, __common section with the .zerofill directive.
+ if (Kind.isBSSExtern())
+ return DataCommonSection;
+
+ // Put zero initialized globals with local linkage in __DATA,__bss directive
+ // with the .zerofill directive (aka .lcomm).
+ if (Kind.isBSSLocal())
+ return DataBSSSection;
+
+ // Otherwise, just drop the variable in the normal data section.
+ return DataSection;
+}
+
+const MCSection *
+TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind) const {
+ // If this constant requires a relocation, we have to put it in the data
+ // segment, not in the text segment.
+ if (Kind.isDataRel() || Kind.isReadOnlyWithRel())
+ return ConstDataSection;
+
+ if (Kind.isMergeableConst4())
+ return FourByteConstantSection;
+ if (Kind.isMergeableConst8())
+ return EightByteConstantSection;
+ if (Kind.isMergeableConst16() && SixteenByteConstantSection)
+ return SixteenByteConstantSection;
+ return ReadOnlySection; // .const
+}
+
+/// shouldEmitUsedDirectiveFor - This hook allows targets to selectively decide
+/// not to emit the UsedDirective for some symbols in llvm.used.
+// FIXME: REMOVE this (rdar://7071300)
+bool TargetLoweringObjectFileMachO::
+shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const {
+ /// On Darwin, internally linked data beginning with "L" or "l" does not have
+ /// the directive emitted (this occurs in ObjC metadata).
+ if (!GV) return false;
+
+ // Check whether the mangled name has the "Private" or "LinkerPrivate" prefix.
+ if (GV->hasLocalLinkage() && !isa<Function>(GV)) {
+ // FIXME: ObjC metadata is currently emitted as internal symbols that have
+ // \1L and \0l prefixes on them. Fix them to be Private/LinkerPrivate and
+ // this horrible hack can go away.
+ SmallString<64> Name;
+ Mang->getNameWithPrefix(Name, GV, false);
+ if (Name[0] == 'L' || Name[0] == 'l')
+ return false;
+ }
+
+ return true;
+}
+
+const MCExpr *TargetLoweringObjectFileMachO::
+getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding) const {
+ // The mach-o version of this method defaults to returning a stub reference.
+
+ if (Encoding & dwarf::DW_EH_PE_indirect) {
+ SmallString<128> Name;
+ Mang->getNameWithPrefix(Name, GV, true);
+ Name += "$non_lazy_ptr";
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
+
+ return TargetLoweringObjectFile::
+ getSymbolForDwarfReference(Sym, MMI,
+ Encoding & ~dwarf::DW_EH_PE_indirect);
+ }
+
+ return TargetLoweringObjectFile::
+ getSymbolForDwarfGlobalReference(GV, Mang, MMI, Encoding);
+}
+
+
+//===----------------------------------------------------------------------===//
+// COFF
+//===----------------------------------------------------------------------===//
+
+typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
+
+TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() {
+ delete (COFFUniqueMapTy*)UniquingMap;
+}
+
+
+const MCSection *TargetLoweringObjectFileCOFF::
+getCOFFSection(StringRef Name, bool isDirective, SectionKind Kind) const {
+ // Create the map if it doesn't already exist.
+ if (UniquingMap == 0)
+ UniquingMap = new MachOUniqueMapTy();
+ COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)UniquingMap;
+
+ // Do the lookup, if we have a hit, return it.
+ const MCSectionCOFF *&Entry = Map[Name];
+ if (Entry) return Entry;
+
+ return Entry = MCSectionCOFF::Create(Name, isDirective, Kind, getContext());
+}
+
+void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
+ const TargetMachine &TM) {
+ if (UniquingMap != 0)
+ ((COFFUniqueMapTy*)UniquingMap)->clear();
+ TargetLoweringObjectFile::Initialize(Ctx, TM);
+ TextSection = getCOFFSection("\t.text", true, SectionKind::getText());
+ DataSection = getCOFFSection("\t.data", true, SectionKind::getDataRel());
+ StaticCtorSection =
+ getCOFFSection(".ctors", false, SectionKind::getDataRel());
+ StaticDtorSection =
+ getCOFFSection(".dtors", false, SectionKind::getDataRel());
+
+ // FIXME: We're emitting LSDA info into a readonly section on COFF, even
+ // though it contains relocatable pointers. In PIC mode, this is probably a
+ // big runtime hit for C++ apps. Either the contents of the LSDA need to be
+ // adjusted or this should be a data section.
+ LSDASection =
+ getCOFFSection(".gcc_except_table", false, SectionKind::getReadOnly());
+ EHFrameSection =
+ getCOFFSection(".eh_frame", false, SectionKind::getDataRel());
+
+ // Debug info.
+ // FIXME: Don't use 'directive' mode here.
+ DwarfAbbrevSection =
+ getCOFFSection("\t.section\t.debug_abbrev,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfInfoSection =
+ getCOFFSection("\t.section\t.debug_info,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfLineSection =
+ getCOFFSection("\t.section\t.debug_line,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfFrameSection =
+ getCOFFSection("\t.section\t.debug_frame,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ getCOFFSection("\t.section\t.debug_pubnames,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfPubTypesSection =
+ getCOFFSection("\t.section\t.debug_pubtypes,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfStrSection =
+ getCOFFSection("\t.section\t.debug_str,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfLocSection =
+ getCOFFSection("\t.section\t.debug_loc,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfARangesSection =
+ getCOFFSection("\t.section\t.debug_aranges,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfRangesSection =
+ getCOFFSection("\t.section\t.debug_ranges,\"dr\"",
+ true, SectionKind::getMetadata());
+ DwarfMacroInfoSection =
+ getCOFFSection("\t.section\t.debug_macinfo,\"dr\"",
+ true, SectionKind::getMetadata());
+}
+
+const MCSection *TargetLoweringObjectFileCOFF::
+getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ return getCOFFSection(GV->getSection(), false, Kind);
+}
+
+static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
+ if (Kind.isText())
+ return ".text$linkonce";
+ if (Kind.isWriteable())
+ return ".data$linkonce";
+ return ".rdata$linkonce";
+}
+
+
+const MCSection *TargetLoweringObjectFileCOFF::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const {
+ assert(!Kind.isThreadLocal() && "Doesn't support TLS");
+
+ // If this global is linkonce/weak and the target handles this by emitting it
+ // into a 'uniqued' section name, create and return the section now.
+ if (GV->isWeakForLinker()) {
+ const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind);
+ SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
+ Mang->getNameWithPrefix(Name, GV, false);
+ return getCOFFSection(Name.str(), false, Kind);
+ }
+
+ if (Kind.isText())
+ return getTextSection();
+
+ return getDataSection();
+}
+
diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp
index a3f6364..6f4ca82 100644
--- a/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -213,6 +213,9 @@ bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB,
unsigned NumVisited = 0;
for (MachineBasicBlock::iterator I = llvm::next(OldPos); I != KillPos; ++I) {
MachineInstr *OtherMI = I;
+ // DBG_VALUE cannot be counted against the limit.
+ if (OtherMI->isDebugValue())
+ continue;
if (NumVisited > 30) // FIXME: Arbitrary limit to reduce compile time cost.
return false;
++NumVisited;
@@ -316,7 +319,7 @@ bool TwoAddressInstructionPass::NoUseAfterLastDef(unsigned Reg,
E = MRI->reg_end(); I != E; ++I) {
MachineOperand &MO = I.getOperand();
MachineInstr *MI = MO.getParent();
- if (MI->getParent() != MBB)
+ if (MI->getParent() != MBB || MI->isDebugValue())
continue;
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(MI);
if (DI == DistanceMap.end())
@@ -339,7 +342,7 @@ MachineInstr *TwoAddressInstructionPass::FindLastUseInMBB(unsigned Reg,
E = MRI->reg_end(); I != E; ++I) {
MachineOperand &MO = I.getOperand();
MachineInstr *MI = MO.getParent();
- if (MI->getParent() != MBB)
+ if (MI->getParent() != MBB || MI->isDebugValue())
continue;
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(MI);
if (DI == DistanceMap.end())
@@ -365,13 +368,13 @@ static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII,
DstReg = 0;
unsigned SrcSubIdx, DstSubIdx;
if (!TII->isMoveInstr(MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
- if (MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ if (MI.isExtractSubreg()) {
DstReg = MI.getOperand(0).getReg();
SrcReg = MI.getOperand(1).getReg();
- } else if (MI.getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
+ } else if (MI.isInsertSubreg()) {
DstReg = MI.getOperand(0).getReg();
SrcReg = MI.getOperand(2).getReg();
- } else if (MI.getOpcode() == TargetInstrInfo::SUBREG_TO_REG) {
+ } else if (MI.isSubregToReg()) {
DstReg = MI.getOperand(0).getReg();
SrcReg = MI.getOperand(2).getReg();
}
@@ -429,8 +432,7 @@ static bool isKilled(MachineInstr &MI, unsigned Reg,
/// as a two-address use. If so, return the destination register by reference.
static bool isTwoAddrUse(MachineInstr &MI, unsigned Reg, unsigned &DstReg) {
const TargetInstrDesc &TID = MI.getDesc();
- unsigned NumOps = (MI.getOpcode() == TargetInstrInfo::INLINEASM)
- ? MI.getNumOperands() : TID.getNumOperands();
+ unsigned NumOps = MI.isInlineAsm() ? MI.getNumOperands():TID.getNumOperands();
for (unsigned i = 0; i != NumOps; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg)
@@ -452,11 +454,11 @@ MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB,
const TargetInstrInfo *TII,
bool &IsCopy,
unsigned &DstReg, bool &IsDstPhys) {
- MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg);
- if (UI == MRI->use_end())
+ MachineRegisterInfo::use_nodbg_iterator UI = MRI->use_nodbg_begin(Reg);
+ if (UI == MRI->use_nodbg_end())
return 0;
MachineInstr &UseMI = *UI;
- if (++UI != MRI->use_end())
+ if (++UI != MRI->use_nodbg_end())
// More than one use.
return 0;
if (UseMI.getParent() != MBB)
@@ -924,6 +926,10 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end();
mi != me; ) {
MachineBasicBlock::iterator nmi = llvm::next(mi);
+ if (mi->isDebugValue()) {
+ mi = nmi;
+ continue;
+ }
const TargetInstrDesc &TID = mi->getDesc();
bool FirstTied = true;
@@ -933,7 +939,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
// First scan through all the tied register uses in this instruction
// and record a list of pairs of tied operands for each register.
- unsigned NumOps = (mi->getOpcode() == TargetInstrInfo::INLINEASM)
+ unsigned NumOps = mi->isInlineAsm()
? mi->getNumOperands() : TID.getNumOperands();
for (unsigned SrcIdx = 0; SrcIdx < NumOps; ++SrcIdx) {
unsigned DstIdx = 0;
diff --git a/lib/CodeGen/UnreachableBlockElim.cpp b/lib/CodeGen/UnreachableBlockElim.cpp
index 6ab5db2..b0f0a07 100644
--- a/lib/CodeGen/UnreachableBlockElim.cpp
+++ b/lib/CodeGen/UnreachableBlockElim.cpp
@@ -148,8 +148,7 @@ bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) {
MachineBasicBlock* succ = *BB->succ_begin();
MachineBasicBlock::iterator start = succ->begin();
- while (start != succ->end() &&
- start->getOpcode() == TargetInstrInfo::PHI) {
+ while (start != succ->end() && start->isPHI()) {
for (unsigned i = start->getNumOperands() - 1; i >= 2; i-=2)
if (start->getOperand(i).isMBB() &&
start->getOperand(i).getMBB() == BB) {
@@ -188,8 +187,7 @@ bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) {
SmallPtrSet<MachineBasicBlock*, 8> preds(BB->pred_begin(),
BB->pred_end());
MachineBasicBlock::iterator phi = BB->begin();
- while (phi != BB->end() &&
- phi->getOpcode() == TargetInstrInfo::PHI) {
+ while (phi != BB->end() && phi->isPHI()) {
for (unsigned i = phi->getNumOperands() - 1; i >= 2; i-=2)
if (!preds.count(phi->getOperand(i).getMBB())) {
phi->RemoveOperand(i);
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index d4fb2e4..5956b61 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -9,7 +9,7 @@
//
// This file implements the VirtRegMap class.
//
-// It also contains implementations of the the Spiller interface, which, given a
+// It also contains implementations of the Spiller interface, which, given a
// virtual register map and a machine function, eliminates all virtual
// references by replacing them with physical register references - adding spill
// code as necessary.
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp
index df2b8d2..84e0398 100644
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -62,6 +62,7 @@ VirtRegRewriter::~VirtRegRewriter() {}
/// substitutePhysReg - Replace virtual register in MachineOperand with a
/// physical register. Do the right thing with the sub-register index.
+/// Note that operands may be added, so the MO reference is no longer valid.
static void substitutePhysReg(MachineOperand &MO, unsigned Reg,
const TargetRegisterInfo &TRI) {
if (unsigned SubIdx = MO.getSubReg()) {
@@ -123,14 +124,15 @@ struct TrivialRewriter : public VirtRegRewriter {
continue;
unsigned pReg = VRM.getPhys(reg);
mri->setPhysRegUsed(pReg);
- for (MachineRegisterInfo::reg_iterator regItr = mri->reg_begin(reg),
- regEnd = mri->reg_end(); regItr != regEnd;) {
- MachineOperand &mop = regItr.getOperand();
- assert(mop.isReg() && mop.getReg() == reg && "reg_iterator broken?");
- ++regItr;
- substitutePhysReg(mop, pReg, *tri);
- changed = true;
- }
+ // Copy the register use-list before traversing it.
+ SmallVector<std::pair<MachineInstr*, unsigned>, 32> reglist;
+ for (MachineRegisterInfo::reg_iterator I = mri->reg_begin(reg),
+ E = mri->reg_end(); I != E; ++I)
+ reglist.push_back(std::make_pair(&*I, I.getOperandNo()));
+ for (unsigned N=0; N != reglist.size(); ++N)
+ substitutePhysReg(reglist[N].first->getOperand(reglist[N].second),
+ pReg, *tri);
+ changed |= !reglist.empty();
}
}
@@ -1759,7 +1761,7 @@ private:
// Mark is killed.
MachineInstr *CopyMI = prior(InsertLoc);
- CopyMI->setAsmPrinterFlag(AsmPrinter::ReloadReuse);
+ CopyMI->setAsmPrinterFlag(MachineInstr::ReloadReuse);
MachineOperand *KillOpnd = CopyMI->findRegisterUseOperand(InReg);
KillOpnd->setIsKill();
UpdateKills(*CopyMI, TRI, RegKills, KillOps);
@@ -1850,31 +1852,30 @@ private:
KilledMIRegs.clear();
for (unsigned j = 0, e = VirtUseOps.size(); j != e; ++j) {
unsigned i = VirtUseOps[j];
- MachineOperand &MO = MI.getOperand(i);
- unsigned VirtReg = MO.getReg();
+ unsigned VirtReg = MI.getOperand(i).getReg();
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
"Not a virtual register?");
- unsigned SubIdx = MO.getSubReg();
+ unsigned SubIdx = MI.getOperand(i).getSubReg();
if (VRM.isAssignedReg(VirtReg)) {
// This virtual register was assigned a physreg!
unsigned Phys = VRM.getPhys(VirtReg);
RegInfo->setPhysRegUsed(Phys);
- if (MO.isDef())
+ if (MI.getOperand(i).isDef())
ReusedOperands.markClobbered(Phys);
- substitutePhysReg(MO, Phys, *TRI);
+ substitutePhysReg(MI.getOperand(i), Phys, *TRI);
if (VRM.isImplicitlyDefined(VirtReg))
// FIXME: Is this needed?
BuildMI(MBB, &MI, MI.getDebugLoc(),
- TII->get(TargetInstrInfo::IMPLICIT_DEF), Phys);
+ TII->get(TargetOpcode::IMPLICIT_DEF), Phys);
continue;
}
// This virtual register is now known to be a spilled value.
- if (!MO.isUse())
+ if (!MI.getOperand(i).isUse())
continue; // Handle defs in the loop below (handle use&def here though)
- bool AvoidReload = MO.isUndef();
+ bool AvoidReload = MI.getOperand(i).isUndef();
// Check if it is defined by an implicit def. It should not be spilled.
// Note, this is for correctness reason. e.g.
// 8 %reg1024<def> = IMPLICIT_DEF
@@ -1902,8 +1903,7 @@ private:
// = EXTRACT_SUBREG fi#1
// fi#1 is available in EDI, but it cannot be reused because it's not in
// the right register file.
- if (PhysReg && !AvoidReload &&
- (SubIdx || MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)) {
+ if (PhysReg && !AvoidReload && (SubIdx || MI.isExtractSubreg())) {
const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
if (!RC->contains(PhysReg))
PhysReg = 0;
@@ -2038,7 +2038,7 @@ private:
TII->copyRegToReg(MBB, InsertLoc, DesignatedReg, PhysReg, RC, RC);
MachineInstr *CopyMI = prior(InsertLoc);
- CopyMI->setAsmPrinterFlag(AsmPrinter::ReloadReuse);
+ CopyMI->setAsmPrinterFlag(MachineInstr::ReloadReuse);
UpdateKills(*CopyMI, TRI, RegKills, KillOps);
// This invalidates DesignatedReg.
@@ -2167,7 +2167,7 @@ private:
// virtual or needing to clobber any values if it's physical).
NextMII = &MI;
--NextMII; // backtrack to the copy.
- NextMII->setAsmPrinterFlag(AsmPrinter::ReloadReuse);
+ NextMII->setAsmPrinterFlag(MachineInstr::ReloadReuse);
// Propagate the sub-register index over.
if (SubIdx) {
DefMO = NextMII->findRegisterDefOperand(DestReg);
diff --git a/lib/CompilerDriver/CompilationGraph.cpp b/lib/CompilerDriver/CompilationGraph.cpp
index 56e5b9c..524607b 100644
--- a/lib/CompilerDriver/CompilationGraph.cpp
+++ b/lib/CompilerDriver/CompilationGraph.cpp
@@ -33,9 +33,11 @@ using namespace llvmc;
namespace llvmc {
const std::string& LanguageMap::GetLanguage(const sys::Path& File) const {
- LanguageMap::const_iterator Lang = this->find(File.getSuffix());
+ StringRef suf = File.getSuffix();
+ LanguageMap::const_iterator Lang = this->find(suf);
if (Lang == this->end())
- throw std::runtime_error(("Unknown suffix: " + File.getSuffix()).str());
+ throw std::runtime_error("File '" + File.str() +
+ "' has unknown suffix '" + suf.str() + '\'');
return Lang->second;
}
}
diff --git a/lib/CompilerDriver/Makefile b/lib/CompilerDriver/Makefile
index a5ecfd5..66c6d11 100644
--- a/lib/CompilerDriver/Makefile
+++ b/lib/CompilerDriver/Makefile
@@ -22,6 +22,7 @@ else
endif
REQUIRES_EH := 1
+REQUIRES_RTTI := 1
include $(LEVEL)/Makefile.common
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index 89c4290..6db3ef9 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -18,7 +18,6 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
@@ -36,25 +35,29 @@ using namespace llvm;
STATISTIC(NumInitBytes, "Number of bytes of global vars initialized");
STATISTIC(NumGlobals , "Number of global vars initialized");
-ExecutionEngine *(*ExecutionEngine::JITCtor)(ModuleProvider *MP,
- std::string *ErrorStr,
- JITMemoryManager *JMM,
- CodeGenOpt::Level OptLevel,
- bool GVsWithCode,
- CodeModel::Model CMM) = 0;
-ExecutionEngine *(*ExecutionEngine::InterpCtor)(ModuleProvider *MP,
+ExecutionEngine *(*ExecutionEngine::JITCtor)(
+ Module *M,
+ std::string *ErrorStr,
+ JITMemoryManager *JMM,
+ CodeGenOpt::Level OptLevel,
+ bool GVsWithCode,
+ CodeModel::Model CMM,
+ StringRef MArch,
+ StringRef MCPU,
+ const SmallVectorImpl<std::string>& MAttrs) = 0;
+ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M,
std::string *ErrorStr) = 0;
ExecutionEngine::EERegisterFn ExecutionEngine::ExceptionTableRegister = 0;
-ExecutionEngine::ExecutionEngine(ModuleProvider *P)
+ExecutionEngine::ExecutionEngine(Module *M)
: EEState(*this),
LazyFunctionCreator(0) {
CompilingLazily = false;
GVCompilationDisabled = false;
SymbolSearchingDisabled = false;
- Modules.push_back(P);
- assert(P && "ModuleProvider is null?");
+ Modules.push_back(M);
+ assert(M && "Module is null?");
}
ExecutionEngine::~ExecutionEngine() {
@@ -69,38 +72,18 @@ char* ExecutionEngine::getMemoryForGV(const GlobalVariable* GV) {
return new char[GVSize];
}
-/// removeModuleProvider - Remove a ModuleProvider from the list of modules.
-/// Relases the Module from the ModuleProvider, materializing it in the
-/// process, and returns the materialized Module.
-Module* ExecutionEngine::removeModuleProvider(ModuleProvider *P,
- std::string *ErrInfo) {
- for(SmallVector<ModuleProvider *, 1>::iterator I = Modules.begin(),
+/// removeModule - Remove a Module from the list of modules.
+bool ExecutionEngine::removeModule(Module *M) {
+ for(SmallVector<Module *, 1>::iterator I = Modules.begin(),
E = Modules.end(); I != E; ++I) {
- ModuleProvider *MP = *I;
- if (MP == P) {
+ Module *Found = *I;
+ if (Found == M) {
Modules.erase(I);
- clearGlobalMappingsFromModule(MP->getModule());
- return MP->releaseModule(ErrInfo);
- }
- }
- return NULL;
-}
-
-/// deleteModuleProvider - Remove a ModuleProvider from the list of modules,
-/// and deletes the ModuleProvider and owned Module. Avoids materializing
-/// the underlying module.
-void ExecutionEngine::deleteModuleProvider(ModuleProvider *P,
- std::string *ErrInfo) {
- for(SmallVector<ModuleProvider *, 1>::iterator I = Modules.begin(),
- E = Modules.end(); I != E; ++I) {
- ModuleProvider *MP = *I;
- if (MP == P) {
- Modules.erase(I);
- clearGlobalMappingsFromModule(MP->getModule());
- delete MP;
- return;
+ clearGlobalMappingsFromModule(M);
+ return true;
}
}
+ return false;
}
/// FindFunctionNamed - Search all of the active modules to find the one that
@@ -108,7 +91,7 @@ void ExecutionEngine::deleteModuleProvider(ModuleProvider *P,
/// general code.
Function *ExecutionEngine::FindFunctionNamed(const char *FnName) {
for (unsigned i = 0, e = Modules.size(); i != e; ++i) {
- if (Function *F = Modules[i]->getModule()->getFunction(FnName))
+ if (Function *F = Modules[i]->getFunction(FnName))
return F;
}
return 0;
@@ -316,7 +299,7 @@ void ExecutionEngine::runStaticConstructorsDestructors(Module *module,
void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) {
// Execute global ctors/dtors for each module in the program.
for (unsigned m = 0, e = Modules.size(); m != e; ++m)
- runStaticConstructorsDestructors(Modules[m]->getModule(), isDtors);
+ runStaticConstructorsDestructors(Modules[m], isDtors);
}
#ifndef NDEBUG
@@ -356,7 +339,7 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn,
}
// FALLS THROUGH
case 1:
- if (!FTy->getParamType(0)->isInteger(32)) {
+ if (!FTy->getParamType(0)->isIntegerTy(32)) {
llvm_report_error("Invalid type for first argument of main() supplied");
}
// FALLS THROUGH
@@ -393,12 +376,12 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn,
/// Interpreter or there's an error. If even an Interpreter cannot be created,
/// NULL is returned.
///
-ExecutionEngine *ExecutionEngine::create(ModuleProvider *MP,
+ExecutionEngine *ExecutionEngine::create(Module *M,
bool ForceInterpreter,
std::string *ErrorStr,
CodeGenOpt::Level OptLevel,
bool GVsWithCode) {
- return EngineBuilder(MP)
+ return EngineBuilder(M)
.setEngineKind(ForceInterpreter
? EngineKind::Interpreter
: EngineKind::JIT)
@@ -408,16 +391,6 @@ ExecutionEngine *ExecutionEngine::create(ModuleProvider *MP,
.create();
}
-ExecutionEngine *ExecutionEngine::create(Module *M) {
- return EngineBuilder(M).create();
-}
-
-/// EngineBuilder - Overloaded constructor that automatically creates an
-/// ExistingModuleProvider for an existing module.
-EngineBuilder::EngineBuilder(Module *m) : MP(new ExistingModuleProvider(m)) {
- InitEngine();
-}
-
ExecutionEngine *EngineBuilder::create() {
// Make sure we can resolve symbols in the program as well. The zero arg
// to the function tells DynamicLibrary to load the program, not a library.
@@ -442,8 +415,9 @@ ExecutionEngine *EngineBuilder::create() {
if (WhichEngine & EngineKind::JIT) {
if (ExecutionEngine::JITCtor) {
ExecutionEngine *EE =
- ExecutionEngine::JITCtor(MP, ErrorStr, JMM, OptLevel,
- AllocateGVsWithCode, CMModel);
+ ExecutionEngine::JITCtor(M, ErrorStr, JMM, OptLevel,
+ AllocateGVsWithCode, CMModel,
+ MArch, MCPU, MAttrs);
if (EE) return EE;
}
}
@@ -452,7 +426,7 @@ ExecutionEngine *EngineBuilder::create() {
// an interpreter instead.
if (WhichEngine & EngineKind::Interpreter) {
if (ExecutionEngine::InterpCtor)
- return ExecutionEngine::InterpCtor(MP, ErrorStr);
+ return ExecutionEngine::InterpCtor(M, ErrorStr);
if (ErrorStr)
*ErrorStr = "Interpreter has not been linked in.";
return 0;
@@ -625,18 +599,18 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
switch (Op0->getType()->getTypeID()) {
default: llvm_unreachable("Invalid bitcast operand");
case Type::IntegerTyID:
- assert(DestTy->isFloatingPoint() && "invalid bitcast");
+ assert(DestTy->isFloatingPointTy() && "invalid bitcast");
if (DestTy->isFloatTy())
GV.FloatVal = GV.IntVal.bitsToFloat();
else if (DestTy->isDoubleTy())
GV.DoubleVal = GV.IntVal.bitsToDouble();
break;
case Type::FloatTyID:
- assert(DestTy->isInteger(32) && "Invalid bitcast");
+ assert(DestTy->isIntegerTy(32) && "Invalid bitcast");
GV.IntVal.floatToBits(GV.FloatVal);
break;
case Type::DoubleTyID:
- assert(DestTy->isInteger(64) && "Invalid bitcast");
+ assert(DestTy->isIntegerTy(64) && "Invalid bitcast");
GV.IntVal.doubleToBits(GV.DoubleVal);
break;
case Type::PointerTyID:
@@ -968,7 +942,7 @@ void ExecutionEngine::emitGlobals() {
if (Modules.size() != 1) {
for (unsigned m = 0, e = Modules.size(); m != e; ++m) {
- Module &M = *Modules[m]->getModule();
+ Module &M = *Modules[m];
for (Module::const_global_iterator I = M.global_begin(),
E = M.global_end(); I != E; ++I) {
const GlobalValue *GV = I;
@@ -1002,7 +976,7 @@ void ExecutionEngine::emitGlobals() {
std::vector<const GlobalValue*> NonCanonicalGlobals;
for (unsigned m = 0, e = Modules.size(); m != e; ++m) {
- Module &M = *Modules[m]->getModule();
+ Module &M = *Modules[m];
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
// In the multi-module case, see what this global maps to.
diff --git a/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/lib/ExecutionEngine/ExecutionEngineBindings.cpp
index 412b493..141cb27 100644
--- a/lib/ExecutionEngine/ExecutionEngineBindings.cpp
+++ b/lib/ExecutionEngine/ExecutionEngineBindings.cpp
@@ -174,20 +174,16 @@ void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
}
void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP){
- unwrap(EE)->addModuleProvider(unwrap(MP));
+ unwrap(EE)->addModule(unwrap(MP));
}
LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
LLVMModuleProviderRef MP,
LLVMModuleRef *OutMod, char **OutError) {
- std::string Error;
- if (Module *Gone = unwrap(EE)->removeModuleProvider(unwrap(MP), &Error)) {
- *OutMod = wrap(Gone);
- return 0;
- }
- if (OutError)
- *OutError = strdup(Error.c_str());
- return 1;
+ Module *M = unwrap(MP);
+ unwrap(EE)->removeModule(M);
+ *OutMod = wrap(M);
+ return 0;
}
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index 73f5558..e234cf1 100644
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/lib/ExecutionEngine/Interpreter/Execution.cpp
@@ -591,7 +591,7 @@ void Interpreter::popStackAndReturnValueToCaller(const Type *RetTy,
ECStack.pop_back();
if (ECStack.empty()) { // Finished main. Put result into exit code...
- if (RetTy && RetTy->isInteger()) { // Nonvoid return type?
+ if (RetTy && RetTy->isIntegerTy()) { // Nonvoid return type?
ExitValue = Result; // Capture the exit value of the program
} else {
memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
@@ -979,7 +979,7 @@ GenericValue Interpreter::executeFPToUIInst(Value *SrcVal, const Type *DstTy,
const Type *SrcTy = SrcVal->getType();
uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- assert(SrcTy->isFloatingPoint() && "Invalid FPToUI instruction");
+ assert(SrcTy->isFloatingPointTy() && "Invalid FPToUI instruction");
if (SrcTy->getTypeID() == Type::FloatTyID)
Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
@@ -993,7 +993,7 @@ GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, const Type *DstTy,
const Type *SrcTy = SrcVal->getType();
uint32_t DBitWidth = cast<IntegerType>(DstTy)->getBitWidth();
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- assert(SrcTy->isFloatingPoint() && "Invalid FPToSI instruction");
+ assert(SrcTy->isFloatingPointTy() && "Invalid FPToSI instruction");
if (SrcTy->getTypeID() == Type::FloatTyID)
Dest.IntVal = APIntOps::RoundFloatToAPInt(Src.FloatVal, DBitWidth);
@@ -1005,7 +1005,7 @@ GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, const Type *DstTy,
GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF) {
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- assert(DstTy->isFloatingPoint() && "Invalid UIToFP instruction");
+ assert(DstTy->isFloatingPointTy() && "Invalid UIToFP instruction");
if (DstTy->getTypeID() == Type::FloatTyID)
Dest.FloatVal = APIntOps::RoundAPIntToFloat(Src.IntVal);
@@ -1017,7 +1017,7 @@ GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, const Type *DstTy,
GenericValue Interpreter::executeSIToFPInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF) {
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- assert(DstTy->isFloatingPoint() && "Invalid SIToFP instruction");
+ assert(DstTy->isFloatingPointTy() && "Invalid SIToFP instruction");
if (DstTy->getTypeID() == Type::FloatTyID)
Dest.FloatVal = APIntOps::RoundSignedAPIntToFloat(Src.IntVal);
@@ -1058,24 +1058,24 @@ GenericValue Interpreter::executeBitCastInst(Value *SrcVal, const Type *DstTy,
if (isa<PointerType>(DstTy)) {
assert(isa<PointerType>(SrcTy) && "Invalid BitCast");
Dest.PointerVal = Src.PointerVal;
- } else if (DstTy->isInteger()) {
+ } else if (DstTy->isIntegerTy()) {
if (SrcTy->isFloatTy()) {
Dest.IntVal.zext(sizeof(Src.FloatVal) * CHAR_BIT);
Dest.IntVal.floatToBits(Src.FloatVal);
} else if (SrcTy->isDoubleTy()) {
Dest.IntVal.zext(sizeof(Src.DoubleVal) * CHAR_BIT);
Dest.IntVal.doubleToBits(Src.DoubleVal);
- } else if (SrcTy->isInteger()) {
+ } else if (SrcTy->isIntegerTy()) {
Dest.IntVal = Src.IntVal;
} else
llvm_unreachable("Invalid BitCast");
} else if (DstTy->isFloatTy()) {
- if (SrcTy->isInteger())
+ if (SrcTy->isIntegerTy())
Dest.FloatVal = Src.IntVal.bitsToFloat();
else
Dest.FloatVal = Src.FloatVal;
} else if (DstTy->isDoubleTy()) {
- if (SrcTy->isInteger())
+ if (SrcTy->isIntegerTy())
Dest.DoubleVal = Src.IntVal.bitsToDouble();
else
Dest.DoubleVal = Src.DoubleVal;
diff --git a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
index c02d84f..7b061d3 100644
--- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
+++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
@@ -368,7 +368,7 @@ GenericValue lle_X_sprintf(const FunctionType *FT,
switch (Last) {
case '%':
- strcpy(Buffer, "%"); break;
+ memcpy(Buffer, "%", 2); break;
case 'c':
sprintf(Buffer, FmtBuf, uint32_t(Args[ArgNo++].IntVal.getZExtValue()));
break;
@@ -400,8 +400,9 @@ GenericValue lle_X_sprintf(const FunctionType *FT,
errs() << "<unknown printf code '" << *FmtStr << "'!>";
ArgNo++; break;
}
- strcpy(OutputBuffer, Buffer);
- OutputBuffer += strlen(Buffer);
+ size_t Len = strlen(Buffer);
+ memcpy(OutputBuffer, Buffer, Len + 1);
+ OutputBuffer += Len;
}
break;
}
diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.cpp b/lib/ExecutionEngine/Interpreter/Interpreter.cpp
index 9be6a92..43e3453 100644
--- a/lib/ExecutionEngine/Interpreter/Interpreter.cpp
+++ b/lib/ExecutionEngine/Interpreter/Interpreter.cpp
@@ -17,7 +17,6 @@
#include "llvm/CodeGen/IntrinsicLowering.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include <cstring>
using namespace llvm;
@@ -33,20 +32,20 @@ extern "C" void LLVMLinkInInterpreter() { }
/// create - Create a new interpreter object. This can never fail.
///
-ExecutionEngine *Interpreter::create(ModuleProvider *MP, std::string* ErrStr) {
- // Tell this ModuleProvide to materialize and release the module
- if (!MP->materializeModule(ErrStr))
+ExecutionEngine *Interpreter::create(Module *M, std::string* ErrStr) {
+ // Tell this Module to materialize everything and release the GVMaterializer.
+ if (M->MaterializeAllPermanently(ErrStr))
// We got an error, just return 0
return 0;
- return new Interpreter(MP);
+ return new Interpreter(M);
}
//===----------------------------------------------------------------------===//
// Interpreter ctor - Initialize stuff
//
-Interpreter::Interpreter(ModuleProvider *M)
- : ExecutionEngine(M), TD(M->getModule()) {
+Interpreter::Interpreter(Module *M)
+ : ExecutionEngine(M), TD(M) {
memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
setTargetData(&TD);
diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h
index 038830c..bc4200b 100644
--- a/lib/ExecutionEngine/Interpreter/Interpreter.h
+++ b/lib/ExecutionEngine/Interpreter/Interpreter.h
@@ -94,7 +94,7 @@ class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
std::vector<Function*> AtExitHandlers;
public:
- explicit Interpreter(ModuleProvider *M);
+ explicit Interpreter(Module *M);
~Interpreter();
/// runAtExitHandlers - Run any functions registered by the program's calls to
@@ -108,7 +108,7 @@ public:
/// create - Create an interpreter ExecutionEngine. This can never fail.
///
- static ExecutionEngine *create(ModuleProvider *M, std::string *ErrorStr = 0);
+ static ExecutionEngine *create(Module *M, std::string *ErrorStr = 0);
/// run - Start execution with the specified function and arguments.
///
diff --git a/lib/ExecutionEngine/Interpreter/Makefile b/lib/ExecutionEngine/Interpreter/Makefile
index 4df38ea..5def136 100644
--- a/lib/ExecutionEngine/Interpreter/Makefile
+++ b/lib/ExecutionEngine/Interpreter/Makefile
@@ -9,6 +9,5 @@
LEVEL = ../../..
LIBRARYNAME = LLVMInterpreter
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp
index faf724f..18a996e 100644
--- a/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/lib/ExecutionEngine/JIT/JIT.cpp
@@ -18,7 +18,7 @@
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h"
-#include "llvm/ModuleProvider.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/ExecutionEngine/GenericValue.h"
@@ -28,6 +28,7 @@
#include "llvm/Target/TargetJITInfo.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/System/DynamicLibrary.h"
#include "llvm/Config/config.h"
@@ -172,7 +173,7 @@ void DarwinRegisterFrame(void* FrameBegin) {
ob->encoding.i = 0;
ob->encoding.b.encoding = llvm::dwarf::DW_EH_PE_omit;
- // Put the info on both places, as libgcc uses the first or the the second
+ // Put the info on both places, as libgcc uses the first or the second
// field. Note that we rely on having two pointers here. If fde_end was a
// char, things would get complicated.
ob->fde_end = (char*)LOI->unseenObjects;
@@ -193,35 +194,44 @@ void DarwinRegisterFrame(void* FrameBegin) {
/// createJIT - This is the factory method for creating a JIT for the current
/// machine, it does not fall back to the interpreter. This takes ownership
-/// of the module provider.
-ExecutionEngine *ExecutionEngine::createJIT(ModuleProvider *MP,
+/// of the module.
+ExecutionEngine *ExecutionEngine::createJIT(Module *M,
std::string *ErrorStr,
JITMemoryManager *JMM,
CodeGenOpt::Level OptLevel,
bool GVsWithCode,
- CodeModel::Model CMM) {
- return JIT::createJIT(MP, ErrorStr, JMM, OptLevel, GVsWithCode, CMM);
+ CodeModel::Model CMM) {
+ // Use the defaults for extra parameters. Users can use EngineBuilder to
+ // set them.
+ StringRef MArch = "";
+ StringRef MCPU = "";
+ SmallVector<std::string, 1> MAttrs;
+ return JIT::createJIT(M, ErrorStr, JMM, OptLevel, GVsWithCode, CMM,
+ MArch, MCPU, MAttrs);
}
-ExecutionEngine *JIT::createJIT(ModuleProvider *MP,
+ExecutionEngine *JIT::createJIT(Module *M,
std::string *ErrorStr,
JITMemoryManager *JMM,
CodeGenOpt::Level OptLevel,
bool GVsWithCode,
- CodeModel::Model CMM) {
+ CodeModel::Model CMM,
+ StringRef MArch,
+ StringRef MCPU,
+ const SmallVectorImpl<std::string>& MAttrs) {
// Make sure we can resolve symbols in the program as well. The zero arg
// to the function tells DynamicLibrary to load the program, not a library.
if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr))
return 0;
// Pick a target either via -march or by guessing the native arch.
- TargetMachine *TM = JIT::selectTarget(MP, ErrorStr);
+ TargetMachine *TM = JIT::selectTarget(M, MArch, MCPU, MAttrs, ErrorStr);
if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0;
TM->setCodeModel(CMM);
// If the target supports JIT code generation, create a the JIT.
if (TargetJITInfo *TJ = TM->getJITInfo()) {
- return new JIT(MP, *TM, *TJ, JMM, OptLevel, GVsWithCode);
+ return new JIT(M, *TM, *TJ, JMM, OptLevel, GVsWithCode);
} else {
if (ErrorStr)
*ErrorStr = "target does not support JIT code generation";
@@ -229,16 +239,63 @@ ExecutionEngine *JIT::createJIT(ModuleProvider *MP,
}
}
-JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji,
+namespace {
+/// This class supports the global getPointerToNamedFunction(), which allows
+/// bugpoint or gdb users to search for a function by name without any context.
+class JitPool {
+ SmallPtrSet<JIT*, 1> JITs; // Optimize for process containing just 1 JIT.
+ mutable sys::Mutex Lock;
+public:
+ void Add(JIT *jit) {
+ MutexGuard guard(Lock);
+ JITs.insert(jit);
+ }
+ void Remove(JIT *jit) {
+ MutexGuard guard(Lock);
+ JITs.erase(jit);
+ }
+ void *getPointerToNamedFunction(const char *Name) const {
+ MutexGuard guard(Lock);
+ assert(JITs.size() != 0 && "No Jit registered");
+ //search function in every instance of JIT
+ for (SmallPtrSet<JIT*, 1>::const_iterator Jit = JITs.begin(),
+ end = JITs.end();
+ Jit != end; ++Jit) {
+ if (Function *F = (*Jit)->FindFunctionNamed(Name))
+ return (*Jit)->getPointerToFunction(F);
+ }
+ // The function is not available : fallback on the first created (will
+ // search in symbol of the current program/library)
+ return (*JITs.begin())->getPointerToNamedFunction(Name);
+ }
+};
+ManagedStatic<JitPool> AllJits;
+}
+extern "C" {
+ // getPointerToNamedFunction - This function is used as a global wrapper to
+ // JIT::getPointerToNamedFunction for the purpose of resolving symbols when
+ // bugpoint is debugging the JIT. In that scenario, we are loading an .so and
+ // need to resolve function(s) that are being mis-codegenerated, so we need to
+ // resolve their addresses at runtime, and this is the way to do it.
+ void *getPointerToNamedFunction(const char *Name) {
+ return AllJits->getPointerToNamedFunction(Name);
+ }
+}
+
+JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode)
- : ExecutionEngine(MP), TM(tm), TJI(tji), AllocateGVsWithCode(GVsWithCode) {
+ : ExecutionEngine(M), TM(tm), TJI(tji), AllocateGVsWithCode(GVsWithCode),
+ isAlreadyCodeGenerating(false) {
setTargetData(TM.getTargetData());
- jitstate = new JITState(MP);
+ jitstate = new JITState(M);
// Initialize JCE
JCE = createEmitter(*this, JMM, TM);
+ // Register in global list of all JITs.
+ AllJits->Add(this);
+
// Add target data
MutexGuard locked(lock);
FunctionPassManager &PM = jitstate->getPM(locked);
@@ -273,21 +330,21 @@ JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji,
}
JIT::~JIT() {
+ AllJits->Remove(this);
delete jitstate;
delete JCE;
delete &TM;
}
-/// addModuleProvider - Add a new ModuleProvider to the JIT. If we previously
-/// removed the last ModuleProvider, we need re-initialize jitstate with a valid
-/// ModuleProvider.
-void JIT::addModuleProvider(ModuleProvider *MP) {
+/// addModule - Add a new Module to the JIT. If we previously removed the last
+/// Module, we need re-initialize jitstate with a valid Module.
+void JIT::addModule(Module *M) {
MutexGuard locked(lock);
if (Modules.empty()) {
assert(!jitstate && "jitstate should be NULL if Modules vector is empty!");
- jitstate = new JITState(MP);
+ jitstate = new JITState(M);
FunctionPassManager &PM = jitstate->getPM(locked);
PM.add(new TargetData(*TM.getTargetData()));
@@ -302,18 +359,17 @@ void JIT::addModuleProvider(ModuleProvider *MP) {
PM.doInitialization();
}
- ExecutionEngine::addModuleProvider(MP);
+ ExecutionEngine::addModule(M);
}
-/// removeModuleProvider - If we are removing the last ModuleProvider,
-/// invalidate the jitstate since the PassManager it contains references a
-/// released ModuleProvider.
-Module *JIT::removeModuleProvider(ModuleProvider *MP, std::string *E) {
- Module *result = ExecutionEngine::removeModuleProvider(MP, E);
+/// removeModule - If we are removing the last Module, invalidate the jitstate
+/// since the PassManager it contains references a released Module.
+bool JIT::removeModule(Module *M) {
+ bool result = ExecutionEngine::removeModule(M);
MutexGuard locked(lock);
- if (jitstate->getMP() == MP) {
+ if (jitstate->getModule() == M) {
delete jitstate;
jitstate = 0;
}
@@ -336,62 +392,6 @@ Module *JIT::removeModuleProvider(ModuleProvider *MP, std::string *E) {
return result;
}
-/// deleteModuleProvider - Remove a ModuleProvider from the list of modules,
-/// and deletes the ModuleProvider and owned Module. Avoids materializing
-/// the underlying module.
-void JIT::deleteModuleProvider(ModuleProvider *MP, std::string *E) {
- ExecutionEngine::deleteModuleProvider(MP, E);
-
- MutexGuard locked(lock);
-
- if (jitstate->getMP() == MP) {
- delete jitstate;
- jitstate = 0;
- }
-
- if (!jitstate && !Modules.empty()) {
- jitstate = new JITState(Modules[0]);
-
- FunctionPassManager &PM = jitstate->getPM(locked);
- PM.add(new TargetData(*TM.getTargetData()));
-
- // Turn the machine code intermediate representation into bytes in memory
- // that may be executed.
- if (TM.addPassesToEmitMachineCode(PM, *JCE, CodeGenOpt::Default)) {
- llvm_report_error("Target does not support machine code emission!");
- }
-
- // Initialize passes.
- PM.doInitialization();
- }
-}
-
-/// materializeFunction - make sure the given function is fully read. If the
-/// module is corrupt, this returns true and fills in the optional string with
-/// information about the problem. If successful, this returns false.
-bool JIT::materializeFunction(Function *F, std::string *ErrInfo) {
- // Read in the function if it exists in this Module.
- if (F->hasNotBeenReadFromBitcode()) {
- // Determine the module provider this function is provided by.
- Module *M = F->getParent();
- ModuleProvider *MP = 0;
- for (unsigned i = 0, e = Modules.size(); i != e; ++i) {
- if (Modules[i]->getModule() == M) {
- MP = Modules[i];
- break;
- }
- }
- if (MP)
- return MP->materializeFunction(F, ErrInfo);
-
- if (ErrInfo)
- *ErrInfo = "Function isn't in a module we know about!";
- return true;
- }
- // Succeed if the function is already read.
- return false;
-}
-
/// run - Start execution with the specified function and arguments.
///
GenericValue JIT::runFunction(Function *F,
@@ -411,10 +411,10 @@ GenericValue JIT::runFunction(Function *F,
// Handle some common cases first. These cases correspond to common `main'
// prototypes.
- if (RetTy->isInteger(32) || RetTy->isVoidTy()) {
+ if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
switch (ArgValues.size()) {
case 3:
- if (FTy->getParamType(0)->isInteger(32) &&
+ if (FTy->getParamType(0)->isIntegerTy(32) &&
isa<PointerType>(FTy->getParamType(1)) &&
isa<PointerType>(FTy->getParamType(2))) {
int (*PF)(int, char **, const char **) =
@@ -429,7 +429,7 @@ GenericValue JIT::runFunction(Function *F,
}
break;
case 2:
- if (FTy->getParamType(0)->isInteger(32) &&
+ if (FTy->getParamType(0)->isIntegerTy(32) &&
isa<PointerType>(FTy->getParamType(1))) {
int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
@@ -442,7 +442,7 @@ GenericValue JIT::runFunction(Function *F,
break;
case 1:
if (FTy->getNumParams() == 1 &&
- FTy->getParamType(0)->isInteger(32)) {
+ FTy->getParamType(0)->isIntegerTy(32)) {
GenericValue rv;
int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
@@ -553,8 +553,12 @@ GenericValue JIT::runFunction(Function *F,
else
ReturnInst::Create(F->getContext(), StubBB); // Just return void.
- // Finally, return the value returned by our nullary stub function.
- return runFunction(Stub, std::vector<GenericValue>());
+ // Finally, call our nullary stub function.
+ GenericValue Result = runFunction(Stub, std::vector<GenericValue>());
+ // Erase it, since no other function can have a reference to it.
+ Stub->eraseFromParent();
+ // And return the result.
+ return Result;
}
void JIT::RegisterJITEventListener(JITEventListener *L) {
@@ -620,7 +624,6 @@ void JIT::runJITOnFunction(Function *F, MachineCodeInfo *MCI) {
}
void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) {
- static bool isAlreadyCodeGenerating = false;
assert(!isAlreadyCodeGenerating && "Error: Recursive compilation detected!");
// JIT the function
@@ -661,7 +664,7 @@ void *JIT::getPointerToFunction(Function *F) {
// Now that this thread owns the lock, make sure we read in the function if it
// exists in this Module.
std::string ErrorMsg;
- if (materializeFunction(F, &ErrorMsg)) {
+ if (F->Materialize(&ErrorMsg)) {
llvm_report_error("Error reading function '" + F->getName()+
"' from bitcode file: " + ErrorMsg);
}
diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h
index b6f74ff..edae719 100644
--- a/lib/ExecutionEngine/JIT/JIT.h
+++ b/lib/ExecutionEngine/JIT/JIT.h
@@ -30,20 +30,20 @@ class TargetMachine;
class JITState {
private:
FunctionPassManager PM; // Passes to compile a function
- ModuleProvider *MP; // ModuleProvider used to create the PM
+ Module *M; // Module used to create the PM
/// PendingFunctions - Functions which have not been code generated yet, but
/// were called from a function being code generated.
std::vector<AssertingVH<Function> > PendingFunctions;
public:
- explicit JITState(ModuleProvider *MP) : PM(MP), MP(MP) {}
+ explicit JITState(Module *M) : PM(M), M(M) {}
FunctionPassManager &getPM(const MutexGuard &L) {
return PM;
}
- ModuleProvider *getMP() const { return MP; }
+ Module *getModule() const { return M; }
std::vector<AssertingVH<Function> > &getPendingFunctions(const MutexGuard &L){
return PendingFunctions;
}
@@ -61,16 +61,20 @@ class JIT : public ExecutionEngine {
/// should be set to true. Doing so breaks freeMachineCodeForFunction.
bool AllocateGVsWithCode;
+ /// True while the JIT is generating code. Used to assert against recursive
+ /// entry.
+ bool isAlreadyCodeGenerating;
+
JITState *jitstate;
- JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji,
+ JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
JITMemoryManager *JMM, CodeGenOpt::Level OptLevel,
bool AllocateGVsWithCode);
public:
~JIT();
static void Register() {
- JITCtor = create;
+ JITCtor = createJIT;
}
/// getJITInfo - Return the target JIT information structure.
@@ -80,35 +84,22 @@ public:
/// create - Create an return a new JIT compiler if there is one available
/// for the current target. Otherwise, return null.
///
- static ExecutionEngine *create(ModuleProvider *MP,
+ static ExecutionEngine *create(Module *M,
std::string *Err,
JITMemoryManager *JMM,
CodeGenOpt::Level OptLevel =
CodeGenOpt::Default,
bool GVsWithCode = true,
CodeModel::Model CMM = CodeModel::Default) {
- return ExecutionEngine::createJIT(MP, Err, JMM, OptLevel, GVsWithCode,
+ return ExecutionEngine::createJIT(M, Err, JMM, OptLevel, GVsWithCode,
CMM);
}
- virtual void addModuleProvider(ModuleProvider *MP);
+ virtual void addModule(Module *M);
- /// removeModuleProvider - Remove a ModuleProvider from the list of modules.
- /// Relases the Module from the ModuleProvider, materializing it in the
- /// process, and returns the materialized Module.
- virtual Module *removeModuleProvider(ModuleProvider *MP,
- std::string *ErrInfo = 0);
-
- /// deleteModuleProvider - Remove a ModuleProvider from the list of modules,
- /// and deletes the ModuleProvider and owned Module. Avoids materializing
- /// the underlying module.
- virtual void deleteModuleProvider(ModuleProvider *P,std::string *ErrInfo = 0);
-
- /// materializeFunction - make sure the given function is fully read. If the
- /// module is corrupt, this returns true and fills in the optional string with
- /// information about the problem. If successful, this returns false.
- ///
- bool materializeFunction(Function *F, std::string *ErrInfo = 0);
+ /// removeModule - Remove a Module from the list of modules. Returns true if
+ /// M is found.
+ virtual bool removeModule(Module *M);
/// runFunction - Start execution with the specified function and arguments.
///
@@ -177,14 +168,21 @@ public:
/// selectTarget - Pick a target either via -march or by guessing the native
/// arch. Add any CPU features specified via -mcpu or -mattr.
- static TargetMachine *selectTarget(ModuleProvider *MP, std::string *Err);
+ static TargetMachine *selectTarget(Module *M,
+ StringRef MArch,
+ StringRef MCPU,
+ const SmallVectorImpl<std::string>& MAttrs,
+ std::string *Err);
- static ExecutionEngine *createJIT(ModuleProvider *MP,
+ static ExecutionEngine *createJIT(Module *M,
std::string *ErrorStr,
JITMemoryManager *JMM,
CodeGenOpt::Level OptLevel,
bool GVsWithCode,
- CodeModel::Model CMM);
+ CodeModel::Model CMM,
+ StringRef MArch,
+ StringRef MCPU,
+ const SmallVectorImpl<std::string>& MAttrs);
// Run the JIT on F and return information about the generated code
void runJITOnFunction(Function *F, MachineCodeInfo *MCI = 0);
diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
index c1051a9..946351b 100644
--- a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
@@ -522,7 +522,11 @@ JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
JCE->emitInt64(((intptr_t)Jit.getPointerToGlobal(Personality)));
}
- JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
+ // LSDA encoding: This must match the encoding used in EmitEHFrame ()
+ if (PointerSize == 4)
+ JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
+ else
+ JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8);
JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
} else {
JCE->emitULEB128Bytes(1);
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index 4dc119d..57c4375 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -37,6 +37,7 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
@@ -57,13 +58,12 @@ using namespace llvm;
STATISTIC(NumBytes, "Number of bytes of machine code compiled");
STATISTIC(NumRelos, "Number of relocations applied");
STATISTIC(NumRetries, "Number of retries with more memory");
-static JIT *TheJIT = 0;
// A declaration may stop being a declaration once it's fully read from bitcode.
// This function returns true if F is fully read and is still a declaration.
static bool isNonGhostDeclaration(const Function *F) {
- return F->isDeclaration() && !F->hasNotBeenReadFromBitcode();
+ return F->isDeclaration() && !F->isMaterializable();
}
//===----------------------------------------------------------------------===//
@@ -109,9 +109,13 @@ namespace {
/// particular GlobalVariable so that we can reuse them if necessary.
GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
+ /// Instance of the JIT this ResolverState serves.
+ JIT *TheJIT;
+
public:
- JITResolverState() : FunctionToLazyStubMap(this),
- FunctionToCallSitesMap(this) {}
+ JITResolverState(JIT *jit) : FunctionToLazyStubMap(this),
+ FunctionToCallSitesMap(this),
+ TheJIT(jit) {}
FunctionToLazyStubMapTy& getFunctionToLazyStubMap(
const MutexGuard& locked) {
@@ -227,18 +231,13 @@ namespace {
JITEmitter &JE;
- static JITResolver *TheJITResolver;
- public:
- explicit JITResolver(JIT &jit, JITEmitter &je) : nextGOTIndex(0), JE(je) {
- TheJIT = &jit;
+ /// Instance of JIT corresponding to this Resolver.
+ JIT *TheJIT;
+ public:
+ explicit JITResolver(JIT &jit, JITEmitter &je)
+ : state(&jit), nextGOTIndex(0), JE(je), TheJIT(&jit) {
LazyResolverFn = jit.getJITInfo().getLazyResolverFunction(JITCompilerFn);
- assert(TheJITResolver == 0 && "Multiple JIT resolvers?");
- TheJITResolver = this;
- }
-
- ~JITResolver() {
- TheJITResolver = 0;
}
/// getLazyFunctionStubIfAvailable - This returns a pointer to a function's
@@ -273,6 +272,44 @@ namespace {
static void *JITCompilerFn(void *Stub);
};
+ class StubToResolverMapTy {
+ /// Map a stub address to a specific instance of a JITResolver so that
+ /// lazily-compiled functions can find the right resolver to use.
+ ///
+ /// Guarded by Lock.
+ std::map<void*, JITResolver*> Map;
+
+ /// Guards Map from concurrent accesses.
+ mutable sys::Mutex Lock;
+
+ public:
+ /// Registers a Stub to be resolved by Resolver.
+ void RegisterStubResolver(void *Stub, JITResolver *Resolver) {
+ MutexGuard guard(Lock);
+ Map.insert(std::make_pair(Stub, Resolver));
+ }
+ /// Unregisters the Stub when it's invalidated.
+ void UnregisterStubResolver(void *Stub) {
+ MutexGuard guard(Lock);
+ Map.erase(Stub);
+ }
+ /// Returns the JITResolver instance that owns the Stub.
+ JITResolver *getResolverFromStub(void *Stub) const {
+ MutexGuard guard(Lock);
+ // The address given to us for the stub may not be exactly right, it might
+ // be a little bit after the stub. As such, use upper_bound to find it.
+ // This is the same trick as in LookupFunctionFromCallSite from
+ // JITResolverState.
+ std::map<void*, JITResolver*>::const_iterator I = Map.upper_bound(Stub);
+ assert(I != Map.begin() && "This is not a known stub!");
+ --I;
+ return I->second;
+ }
+ };
+ /// This needs to be static so that a lazy call stub can access it with no
+ /// context except the address of the stub.
+ ManagedStatic<StubToResolverMapTy> StubToResolverMap;
+
/// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is
/// used to output functions to memory for execution.
class JITEmitter : public JITCodeEmitter {
@@ -371,10 +408,13 @@ namespace {
DILocation PrevDLT;
+ /// Instance of the JIT
+ JIT *TheJIT;
+
public:
JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM)
: SizeEstimate(0), Resolver(jit, *this), MMI(0), CurFn(0),
- EmittedFunctions(this), PrevDLT(NULL) {
+ EmittedFunctions(this), PrevDLT(NULL), TheJIT(&jit) {
MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
if (jit.getJITInfo().needsGOT()) {
MemMgr->AllocateGOT();
@@ -495,8 +535,6 @@ namespace {
};
}
-JITResolver *JITResolver::TheJITResolver = 0;
-
void CallSiteValueMapConfig::onDelete(JITResolverState *JRS, Function *F) {
JRS->EraseAllCallSitesPrelocked(F);
}
@@ -551,6 +589,10 @@ void *JITResolver::getLazyFunctionStub(Function *F) {
DEBUG(dbgs() << "JIT: Lazy stub emitted at [" << Stub << "] for function '"
<< F->getName() << "'\n");
+ // Register this JITResolver as the one corresponding to this call site so
+ // JITCompilerFn will be able to find it.
+ StubToResolverMap->RegisterStubResolver(Stub, this);
+
// Finally, keep track of the stub-to-Function mapping so that the
// JITCompilerFn knows which function to compile!
state.AddCallSite(locked, Stub, F);
@@ -637,6 +679,9 @@ void JITResolver::getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs,
GlobalValue *JITResolver::invalidateStub(void *Stub) {
MutexGuard locked(TheJIT->lock);
+ // Remove the stub from the StubToResolverMap.
+ StubToResolverMap->UnregisterStubResolver(Stub);
+
GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked);
// Look up the cheap way first, to see if it's a function stub we are
@@ -671,7 +716,8 @@ GlobalValue *JITResolver::invalidateStub(void *Stub) {
/// been entered. It looks up which function this stub corresponds to, compiles
/// it if necessary, then returns the resultant function pointer.
void *JITResolver::JITCompilerFn(void *Stub) {
- JITResolver &JR = *TheJITResolver;
+ JITResolver *JR = StubToResolverMap->getResolverFromStub(Stub);
+ assert(JR && "Unable to find the corresponding JITResolver to the call site");
Function* F = 0;
void* ActualPtr = 0;
@@ -680,24 +726,24 @@ void *JITResolver::JITCompilerFn(void *Stub) {
// Only lock for getting the Function. The call getPointerToFunction made
// in this function might trigger function materializing, which requires
// JIT lock to be unlocked.
- MutexGuard locked(TheJIT->lock);
+ MutexGuard locked(JR->TheJIT->lock);
// The address given to us for the stub may not be exactly right, it might
// be a little bit after the stub. As such, use upper_bound to find it.
pair<void*, Function*> I =
- JR.state.LookupFunctionFromCallSite(locked, Stub);
+ JR->state.LookupFunctionFromCallSite(locked, Stub);
F = I.second;
ActualPtr = I.first;
}
// If we have already code generated the function, just return the address.
- void *Result = TheJIT->getPointerToGlobalIfAvailable(F);
+ void *Result = JR->TheJIT->getPointerToGlobalIfAvailable(F);
if (!Result) {
// Otherwise we don't have it, do lazy compilation now.
// If lazy compilation is disabled, emit a useful error message and abort.
- if (!TheJIT->isCompilingLazily()) {
+ if (!JR->TheJIT->isCompilingLazily()) {
llvm_report_error("LLVM JIT requested to do lazy compilation of function '"
+ F->getName() + "' when lazy compiles are disabled!");
}
@@ -706,11 +752,11 @@ void *JITResolver::JITCompilerFn(void *Stub) {
<< "' In stub ptr = " << Stub << " actual ptr = "
<< ActualPtr << "\n");
- Result = TheJIT->getPointerToFunction(F);
+ Result = JR->TheJIT->getPointerToFunction(F);
}
// Reacquire the lock to update the GOT map.
- MutexGuard locked(TheJIT->lock);
+ MutexGuard locked(JR->TheJIT->lock);
// We might like to remove the call site from the CallSiteToFunction map, but
// we can't do that! Multiple threads could be stuck, waiting to acquire the
@@ -725,8 +771,8 @@ void *JITResolver::JITCompilerFn(void *Stub) {
// if they see it still using the stub address.
// Note: this is done so the Resolver doesn't have to manage GOT memory
// Do this without allocating map space if the target isn't using a GOT
- if(JR.revGOTMap.find(Stub) != JR.revGOTMap.end())
- JR.revGOTMap[Result] = JR.revGOTMap[Stub];
+ if(JR->revGOTMap.find(Stub) != JR->revGOTMap.end())
+ JR->revGOTMap[Result] = JR->revGOTMap[Stub];
return Result;
}
@@ -839,7 +885,7 @@ static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP,
return Size;
}
-static unsigned GetJumpTableSizeInBytes(MachineJumpTableInfo *MJTI) {
+static unsigned GetJumpTableSizeInBytes(MachineJumpTableInfo *MJTI, JIT *jit) {
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
if (JT.empty()) return 0;
@@ -847,9 +893,7 @@ static unsigned GetJumpTableSizeInBytes(MachineJumpTableInfo *MJTI) {
for (unsigned i = 0, e = JT.size(); i != e; ++i)
NumEntries += JT[i].MBBs.size();
- unsigned EntrySize = MJTI->getEntrySize();
-
- return NumEntries * EntrySize;
+ return NumEntries * MJTI->getEntrySize(*jit->getTargetData());
}
static uintptr_t RoundUpToAlign(uintptr_t Size, unsigned Alignment) {
@@ -1017,7 +1061,6 @@ void JITEmitter::startFunction(MachineFunction &F) {
if (MemMgr->NeedsExactSize()) {
DEBUG(dbgs() << "JIT: ExactSize\n");
const TargetInstrInfo* TII = F.getTarget().getInstrInfo();
- MachineJumpTableInfo *MJTI = F.getJumpTableInfo();
MachineConstantPool *MCP = F.getConstantPool();
// Ensure the constant pool/jump table info is at least 4-byte aligned.
@@ -1029,11 +1072,14 @@ void JITEmitter::startFunction(MachineFunction &F) {
// Add the constant pool size
ActualSize += GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData());
- // Add the aligment of the jump table info
- ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment());
+ if (MachineJumpTableInfo *MJTI = F.getJumpTableInfo()) {
+ // Add the aligment of the jump table info
+ ActualSize = RoundUpToAlign(ActualSize,
+ MJTI->getEntryAlignment(*TheJIT->getTargetData()));
- // Add the jump table size
- ActualSize += GetJumpTableSizeInBytes(MJTI);
+ // Add the jump table size
+ ActualSize += GetJumpTableSizeInBytes(MJTI, TheJIT);
+ }
// Add the alignment for the function
ActualSize = RoundUpToAlign(ActualSize,
@@ -1062,7 +1108,8 @@ void JITEmitter::startFunction(MachineFunction &F) {
emitAlignment(16);
emitConstantPool(F.getConstantPool());
- initJumpTableInfo(F.getJumpTableInfo());
+ if (MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
+ initJumpTableInfo(MJTI);
// About to start emitting the machine code for the function.
emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
@@ -1084,7 +1131,8 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
return true;
}
- emitJumpTableInfo(F.getJumpTableInfo());
+ if (MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
+ emitJumpTableInfo(MJTI);
// FnStart is the start of the text, not the start of the constant pool and
// other per-function data.
@@ -1404,13 +1452,14 @@ void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) {
for (unsigned i = 0, e = JT.size(); i != e; ++i)
NumEntries += JT[i].MBBs.size();
- unsigned EntrySize = MJTI->getEntrySize();
+ unsigned EntrySize = MJTI->getEntrySize(*TheJIT->getTargetData());
// Just allocate space for all the jump tables now. We will fix up the actual
// MBB entries in the tables after we emit the code for each block, since then
// we will know the final locations of the MBBs in memory.
JumpTable = MJTI;
- JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment());
+ JumpTableBase = allocateSpace(NumEntries * EntrySize,
+ MJTI->getEntryAlignment(*TheJIT->getTargetData()));
}
void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
@@ -1420,8 +1469,32 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
if (JT.empty() || JumpTableBase == 0) return;
- if (TargetMachine::getRelocationModel() == Reloc::PIC_) {
- assert(MJTI->getEntrySize() == 4 && "Cross JIT'ing?");
+
+ switch (MJTI->getEntryKind()) {
+ case MachineJumpTableInfo::EK_BlockAddress: {
+ // EK_BlockAddress - Each entry is a plain address of block, e.g.:
+ // .word LBB123
+ assert(MJTI->getEntrySize(*TheJIT->getTargetData()) == sizeof(void*) &&
+ "Cross JIT'ing?");
+
+ // For each jump table, map each target in the jump table to the address of
+ // an emitted MachineBasicBlock.
+ intptr_t *SlotPtr = (intptr_t*)JumpTableBase;
+
+ for (unsigned i = 0, e = JT.size(); i != e; ++i) {
+ const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
+ // Store the address of the basic block for this jump table slot in the
+ // memory we allocated for the jump table in 'initJumpTableInfo'
+ for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi)
+ *SlotPtr++ = getMachineBasicBlockAddress(MBBs[mi]);
+ }
+ break;
+ }
+
+ case MachineJumpTableInfo::EK_Custom32:
+ case MachineJumpTableInfo::EK_GPRel32BlockAddress:
+ case MachineJumpTableInfo::EK_LabelDifference32: {
+ assert(MJTI->getEntrySize(*TheJIT->getTargetData()) == 4&&"Cross JIT'ing?");
// For each jump table, place the offset from the beginning of the table
// to the target address.
int *SlotPtr = (int*)JumpTableBase;
@@ -1433,23 +1506,12 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
uintptr_t Base = (uintptr_t)SlotPtr;
for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
uintptr_t MBBAddr = getMachineBasicBlockAddress(MBBs[mi]);
+ /// FIXME: USe EntryKind instead of magic "getPICJumpTableEntry" hook.
*SlotPtr++ = TheJIT->getJITInfo().getPICJumpTableEntry(MBBAddr, Base);
}
}
- } else {
- assert(MJTI->getEntrySize() == sizeof(void*) && "Cross JIT'ing?");
-
- // For each jump table, map each target in the jump table to the address of
- // an emitted MachineBasicBlock.
- intptr_t *SlotPtr = (intptr_t*)JumpTableBase;
-
- for (unsigned i = 0, e = JT.size(); i != e; ++i) {
- const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
- // Store the address of the basic block for this jump table slot in the
- // memory we allocated for the jump table in 'initJumpTableInfo'
- for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi)
- *SlotPtr++ = getMachineBasicBlockAddress(MBBs[mi]);
- }
+ break;
+ }
}
}
@@ -1505,9 +1567,9 @@ uintptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const {
const std::vector<MachineJumpTableEntry> &JT = JumpTable->getJumpTables();
assert(Index < JT.size() && "Invalid jump table index!");
- unsigned Offset = 0;
- unsigned EntrySize = JumpTable->getEntrySize();
+ unsigned EntrySize = JumpTable->getEntrySize(*TheJIT->getTargetData());
+ unsigned Offset = 0;
for (unsigned i = 0; i < Index; ++i)
Offset += JT[i].MBBs.size();
@@ -1536,19 +1598,6 @@ JITCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM,
return new JITEmitter(jit, JMM, tm);
}
-// getPointerToNamedFunction - This function is used as a global wrapper to
-// JIT::getPointerToNamedFunction for the purpose of resolving symbols when
-// bugpoint is debugging the JIT. In that scenario, we are loading an .so and
-// need to resolve function(s) that are being mis-codegenerated, so we need to
-// resolve their addresses at runtime, and this is the way to do it.
-extern "C" {
- void *getPointerToNamedFunction(const char *Name) {
- if (Function *F = TheJIT->FindFunctionNamed(Name))
- return TheJIT->getPointerToFunction(F);
- return TheJIT->getPointerToNamedFunction(Name);
- }
-}
-
// getPointerToFunctionOrStub - If the specified function has been
// code-gen'd, return a pointer to the function. If not, compile it, or use
// a stub to implement lazy compilation if available.
diff --git a/lib/ExecutionEngine/JIT/Makefile b/lib/ExecutionEngine/JIT/Makefile
index 1c93c06..aafa3d9 100644
--- a/lib/ExecutionEngine/JIT/Makefile
+++ b/lib/ExecutionEngine/JIT/Makefile
@@ -9,7 +9,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMJIT
-CXXFLAGS = -fno-rtti
# Get the $(ARCH) setting
include $(LEVEL)/Makefile.config
diff --git a/lib/ExecutionEngine/JIT/TargetSelect.cpp b/lib/ExecutionEngine/JIT/TargetSelect.cpp
index 8bed33b..3349c33 100644
--- a/lib/ExecutionEngine/JIT/TargetSelect.cpp
+++ b/lib/ExecutionEngine/JIT/TargetSelect.cpp
@@ -15,7 +15,6 @@
#include "JIT.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
@@ -25,28 +24,14 @@
#include "llvm/Target/TargetRegistry.h"
using namespace llvm;
-static cl::opt<std::string>
-MArch("march",
- cl::desc("Architecture to generate assembly for (see --version)"));
-
-static cl::opt<std::string>
-MCPU("mcpu",
- cl::desc("Target a specific cpu type (-mcpu=help for details)"),
- cl::value_desc("cpu-name"),
- cl::init(""));
-
-static cl::list<std::string>
-MAttrs("mattr",
- cl::CommaSeparated,
- cl::desc("Target specific attributes (-mattr=help for details)"),
- cl::value_desc("a1,+a2,-a3,..."));
-
/// selectTarget - Pick a target either via -march or by guessing the native
/// arch. Add any CPU features specified via -mcpu or -mattr.
-TargetMachine *JIT::selectTarget(ModuleProvider *MP, std::string *ErrorStr) {
- Module &Mod = *MP->getModule();
-
- Triple TheTriple(Mod.getTargetTriple());
+TargetMachine *JIT::selectTarget(Module *Mod,
+ StringRef MArch,
+ StringRef MCPU,
+ const SmallVectorImpl<std::string>& MAttrs,
+ std::string *ErrorStr) {
+ Triple TheTriple(Mod->getTargetTriple());
if (TheTriple.getTriple().empty())
TheTriple.setTriple(sys::getHostTriple());
diff --git a/lib/ExecutionEngine/Makefile b/lib/ExecutionEngine/Makefile
index 2387b0e..e0e050e 100644
--- a/lib/ExecutionEngine/Makefile
+++ b/lib/ExecutionEngine/Makefile
@@ -9,6 +9,5 @@
LEVEL = ../..
LIBRARYNAME = LLVMExecutionEngine
PARALLEL_DIRS = Interpreter JIT
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Linker/LinkArchives.cpp b/lib/Linker/LinkArchives.cpp
index 365ec05..2c4ed7f 100644
--- a/lib/Linker/LinkArchives.cpp
+++ b/lib/Linker/LinkArchives.cpp
@@ -14,7 +14,6 @@
#include "llvm/Linker.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/Bitcode/Archive.h"
#include "llvm/Config/config.h"
@@ -139,8 +138,10 @@ Linker::LinkInArchive(const sys::Path &Filename, bool &is_native) {
do {
CurrentlyUndefinedSymbols = UndefinedSymbols;
- // Find the modules we need to link into the target module
- std::set<ModuleProvider*> Modules;
+ // Find the modules we need to link into the target module. Note that arch
+ // keeps ownership of these modules and may return the same Module* from a
+ // subsequent call.
+ std::set<Module*> Modules;
if (!arch->findModulesDefiningSymbols(UndefinedSymbols, Modules, &ErrMsg))
return error("Cannot find symbols in '" + Filename.str() +
"': " + ErrMsg);
@@ -156,19 +157,17 @@ Linker::LinkInArchive(const sys::Path &Filename, bool &is_native) {
NotDefinedByArchive.insert(UndefinedSymbols.begin(),
UndefinedSymbols.end());
- // Loop over all the ModuleProviders that we got back from the archive
- for (std::set<ModuleProvider*>::iterator I=Modules.begin(), E=Modules.end();
+ // Loop over all the Modules that we got back from the archive
+ for (std::set<Module*>::iterator I=Modules.begin(), E=Modules.end();
I != E; ++I) {
// Get the module we must link in.
std::string moduleErrorMsg;
- std::auto_ptr<Module> AutoModule((*I)->releaseModule( &moduleErrorMsg ));
- if (!moduleErrorMsg.empty())
- return error("Could not load a module: " + moduleErrorMsg);
-
- Module* aModule = AutoModule.get();
-
+ Module* aModule = *I;
if (aModule != NULL) {
+ if (aModule->MaterializeAll(&moduleErrorMsg))
+ return error("Could not load a module: " + moduleErrorMsg);
+
verbose(" Linking in module: " + aModule->getModuleIdentifier());
// Link it in
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index e2cd47a..7f441b0 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -392,9 +392,20 @@ static Value *RemapOperand(const Value *In,
assert(!isa<GlobalValue>(CPV) && "Unmapped global?");
llvm_unreachable("Unknown type of derived type constant value!");
}
- } else if (isa<MDNode>(In) || isa<MDString>(In)) {
- Result = const_cast<Value*>(In);
- } else if (isa<InlineAsm>(In)) {
+ } else if (const MDNode *MD = dyn_cast<MDNode>(In)) {
+ if (MD->isFunctionLocal()) {
+ SmallVector<Value*, 4> Elts;
+ for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) {
+ if (MD->getOperand(i))
+ Elts.push_back(RemapOperand(MD->getOperand(i), ValueMap));
+ else
+ Elts.push_back(NULL);
+ }
+ Result = MDNode::get(In->getContext(), Elts.data(), MD->getNumOperands());
+ } else {
+ Result = const_cast<Value*>(In);
+ }
+ } else if (isa<MDString>(In) || isa<InlineAsm>(In) || isa<Instruction>(In)) {
Result = const_cast<Value*>(In);
}
diff --git a/lib/Linker/Makefile b/lib/Linker/Makefile
index 2179fd2..19e646b 100644
--- a/lib/Linker/Makefile
+++ b/lib/Linker/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../..
LIBRARYNAME = LLVMLinker
BUILD_ARCHIVE := 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index 547f904..f3f063f 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -22,11 +22,10 @@ MCAsmInfo::MCAsmInfo() {
HasSubsectionsViaSymbols = false;
HasMachoZeroFillDirective = false;
HasStaticCtorDtorReferenceInStaticMode = false;
- NeedsSet = false;
MaxInstLength = 4;
PCSymbol = "$";
SeparatorChar = ';';
- CommentColumn = 60;
+ CommentColumn = 40;
CommentString = "#";
GlobalPrefix = "";
PrivateGlobalPrefix = ".";
@@ -48,12 +47,11 @@ MCAsmInfo::MCAsmInfo() {
AlignDirective = "\t.align\t";
AlignmentIsInBytes = true;
TextAlignFillValue = 0;
- JumpTableDirective = 0;
- PICJumpTableDirective = 0;
+ GPRel32Directive = 0;
GlobalDirective = "\t.globl\t";
- SetDirective = 0;
+ HasSetDirective = true;
HasLCOMMDirective = false;
- COMMDirectiveTakesAlignment = true;
+ COMMDirectiveAlignmentIsInBytes = true;
HasDotTypeDotSizeDirective = true;
HasSingleParameterDotFile = true;
HasNoDeadStrip = false;
diff --git a/lib/MC/MCAsmInfoCOFF.cpp b/lib/MC/MCAsmInfoCOFF.cpp
index e395acd..9130493 100644
--- a/lib/MC/MCAsmInfoCOFF.cpp
+++ b/lib/MC/MCAsmInfoCOFF.cpp
@@ -18,14 +18,13 @@ using namespace llvm;
MCAsmInfoCOFF::MCAsmInfoCOFF() {
GlobalPrefix = "_";
+ COMMDirectiveAlignmentIsInBytes = false;
HasLCOMMDirective = true;
- COMMDirectiveTakesAlignment = false;
HasDotTypeDotSizeDirective = false;
HasSingleParameterDotFile = false;
PrivateGlobalPrefix = "L"; // Prefix for private global symbols
WeakRefDirective = "\t.weak\t";
- LinkOnceDirective = "\t.linkonce same_size\n";
- SetDirective = "\t.set\t";
+ LinkOnceDirective = "\t.linkonce discard\n";
// Doesn't support visibility:
HiddenVisibilityAttr = ProtectedVisibilityAttr = MCSA_Invalid;
@@ -37,4 +36,3 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() {
SupportsDebugInformation = true;
DwarfSectionOffsetDirective = "\t.secrel32\t";
}
-
diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp
index 9902f50..da865ad 100644
--- a/lib/MC/MCAsmInfoDarwin.cpp
+++ b/lib/MC/MCAsmInfoDarwin.cpp
@@ -21,12 +21,12 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
GlobalPrefix = "_";
PrivateGlobalPrefix = "L";
LinkerPrivateGlobalPrefix = "l";
- NeedsSet = true;
AllowQuotesInName = true;
HasSingleParameterDotFile = false;
HasSubsectionsViaSymbols = true;
AlignmentIsInBytes = false;
+ COMMDirectiveAlignmentIsInBytes = false;
InlineAsmStart = " InlineAsm Start";
InlineAsmEnd = " InlineAsm End";
@@ -36,7 +36,6 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
HasMachoZeroFillDirective = true; // Uses .zerofill
HasStaticCtorDtorReferenceInStaticMode = true;
- SetDirective = "\t.set";
HiddenVisibilityAttr = MCSA_PrivateExtern;
// Doesn't support protected visibility.
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index bf39239..6add1b4 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -29,25 +29,32 @@ namespace {
class MCAsmStreamer : public MCStreamer {
formatted_raw_ostream &OS;
const MCAsmInfo &MAI;
- bool IsLittleEndian, IsVerboseAsm;
MCInstPrinter *InstPrinter;
MCCodeEmitter *Emitter;
SmallString<128> CommentToEmit;
raw_svector_ostream CommentStream;
+
+ unsigned IsLittleEndian : 1;
+ unsigned IsVerboseAsm : 1;
+ unsigned ShowInst : 1;
+
public:
MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
const MCAsmInfo &mai,
bool isLittleEndian, bool isVerboseAsm, MCInstPrinter *printer,
- MCCodeEmitter *emitter)
- : MCStreamer(Context), OS(os), MAI(mai), IsLittleEndian(isLittleEndian),
- IsVerboseAsm(isVerboseAsm), InstPrinter(printer), Emitter(emitter),
- CommentStream(CommentToEmit) {}
+ MCCodeEmitter *emitter, bool showInst)
+ : MCStreamer(Context), OS(os), MAI(mai), InstPrinter(printer),
+ Emitter(emitter), CommentStream(CommentToEmit),
+ IsLittleEndian(isLittleEndian), IsVerboseAsm(isVerboseAsm),
+ ShowInst(showInst) {
+ if (InstPrinter && IsVerboseAsm)
+ InstPrinter->setCommentStream(CommentStream);
+ }
~MCAsmStreamer() {}
bool isLittleEndian() const { return IsLittleEndian; }
-
-
+
inline void EmitEOL() {
// If we don't have any comments, just emit a \n.
if (!IsVerboseAsm) {
@@ -57,13 +64,20 @@ public:
EmitCommentsAndEOL();
}
void EmitCommentsAndEOL();
-
+
+ /// isVerboseAsm - Return true if this streamer supports verbose assembly at
+ /// all.
+ virtual bool isVerboseAsm() const { return IsVerboseAsm; }
+
/// AddComment - Add a comment that can be emitted to the generated .s
/// file if applicable as a QoI issue to make the output of the compiler
/// more readable. This only affects the MCAsmStreamer, and only when
/// verbose assembly output is enabled.
virtual void AddComment(const Twine &T);
-
+
+ /// AddEncodingComment - Add a comment showing the encoding of an instruction.
+ virtual void AddEncodingComment(const MCInst &Inst);
+
/// GetCommentOS - Return a raw_ostream that comments can be written to.
/// Unlike AddComment, you are required to terminate comments with \n if you
/// use this method.
@@ -72,12 +86,12 @@ public:
return nulls(); // Discard comments unless in verbose asm mode.
return CommentStream;
}
-
+
/// AddBlankLine - Emit a blank line to a .s file to pretty it up.
virtual void AddBlankLine() {
EmitEOL();
}
-
+
/// @name MCStreamer Interface
/// @{
@@ -93,6 +107,7 @@ public:
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
+ virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
@@ -109,6 +124,8 @@ public:
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
virtual void EmitIntValue(uint64_t Value, unsigned Size, unsigned AddrSpace);
+ virtual void EmitGPRel32Value(const MCExpr *Value);
+
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
unsigned AddrSpace);
@@ -119,9 +136,12 @@ public:
virtual void EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0);
-
- virtual void EmitInstruction(const MCInst &Inst);
+ virtual void EmitFileDirective(StringRef Filename);
+ virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename);
+
+ virtual void EmitInstruction(const MCInst &Inst);
+
virtual void Finish();
/// @}
@@ -178,12 +198,6 @@ static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
}
-static inline const MCExpr *truncateToSize(const MCExpr *Value,
- unsigned Bytes) {
- // FIXME: Do we really need this routine?
- return Value;
-}
-
void MCAsmStreamer::SwitchSection(const MCSection *Section) {
assert(Section && "Cannot switch to a null section!");
if (Section != CurSection) {
@@ -226,7 +240,29 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) {
switch (Attribute) {
case MCSA_Invalid: assert(0 && "Invalid symbol attribute");
- case MCSA_Global: OS << MAI.getGlobalDirective(); break; // .globl
+ case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
+ case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
+ case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
+ case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
+ case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
+ case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
+ assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
+ OS << "\t.type\t" << *Symbol << ','
+ << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
+ switch (Attribute) {
+ default: assert(0 && "Unknown ELF .type");
+ case MCSA_ELF_TypeFunction: OS << "function"; break;
+ case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
+ case MCSA_ELF_TypeObject: OS << "object"; break;
+ case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
+ case MCSA_ELF_TypeCommon: OS << "common"; break;
+ case MCSA_ELF_TypeNoType: OS << "no_type"; break;
+ }
+ EmitEOL();
+ return;
+ case MCSA_Global: // .globl/.global
+ OS << MAI.getGlobalDirective();
+ break;
case MCSA_Hidden: OS << ".hidden "; break;
case MCSA_IndirectSymbol: OS << ".indirect_symbol "; break;
case MCSA_Internal: OS << ".internal "; break;
@@ -251,11 +287,16 @@ void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
EmitEOL();
}
+void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
+ assert(MAI.hasDotTypeDotSizeDirective());
+ OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
+}
+
void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
OS << "\t.comm\t" << *Symbol << ',' << Size;
- if (ByteAlignment != 0 && MAI.getCOMMDirectiveTakesAlignment()) {
- if (MAI.getAlignmentIsInBytes())
+ if (ByteAlignment != 0) {
+ if (MAI.getCOMMDirectiveAlignmentIsInBytes())
OS << ',' << ByteAlignment;
else
OS << ',' << Log2_32(ByteAlignment);
@@ -292,6 +333,40 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
static inline char toOctal(int X) { return (X&7)+'0'; }
+static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
+ OS << '"';
+
+ for (unsigned i = 0, e = Data.size(); i != e; ++i) {
+ unsigned char C = Data[i];
+ if (C == '"' || C == '\\') {
+ OS << '\\' << (char)C;
+ continue;
+ }
+
+ if (isprint((unsigned char)C)) {
+ OS << (char)C;
+ continue;
+ }
+
+ switch (C) {
+ case '\b': OS << "\\b"; break;
+ case '\f': OS << "\\f"; break;
+ case '\n': OS << "\\n"; break;
+ case '\r': OS << "\\r"; break;
+ case '\t': OS << "\\t"; break;
+ default:
+ OS << '\\';
+ OS << toOctal(C >> 6);
+ OS << toOctal(C >> 3);
+ OS << toOctal(C >> 0);
+ break;
+ }
+ }
+
+ OS << '"';
+}
+
+
void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
assert(CurSection && "Cannot emit contents before setting section!");
if (Data.empty()) return;
@@ -312,34 +387,8 @@ void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
OS << MAI.getAsciiDirective();
}
- OS << " \"";
- for (unsigned i = 0, e = Data.size(); i != e; ++i) {
- unsigned char C = Data[i];
- if (C == '"' || C == '\\') {
- OS << '\\' << (char)C;
- continue;
- }
-
- if (isprint((unsigned char)C)) {
- OS << (char)C;
- continue;
- }
-
- switch (C) {
- case '\b': OS << "\\b"; break;
- case '\f': OS << "\\f"; break;
- case '\n': OS << "\\n"; break;
- case '\r': OS << "\\r"; break;
- case '\t': OS << "\\t"; break;
- default:
- OS << '\\';
- OS << toOctal(C >> 6);
- OS << toOctal(C >> 3);
- OS << toOctal(C >> 0);
- break;
- }
- }
- OS << '"';
+ OS << ' ';
+ PrintQuotedString(Data, OS);
EmitEOL();
}
@@ -386,10 +435,17 @@ void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
}
assert(Directive && "Invalid size for machine code value!");
- OS << Directive << *truncateToSize(Value, Size);
+ OS << Directive << *Value;
+ EmitEOL();
+}
+
+void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
+ assert(MAI.getGPRel32Directive() != 0);
+ OS << MAI.getGPRel32Directive() << *Value;
EmitEOL();
}
+
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
@@ -464,49 +520,133 @@ void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
EmitEOL();
}
-void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
- assert(CurSection && "Cannot emit contents before setting section!");
- // If we have an AsmPrinter, use that to print.
- if (InstPrinter) {
- InstPrinter->printInst(&Inst);
- EmitEOL();
+void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
+ assert(MAI.hasSingleParameterDotFile());
+ OS << "\t.file\t";
+ PrintQuotedString(Filename, OS);
+ EmitEOL();
+}
- // Show the encoding if we have a code emitter.
- if (Emitter) {
- SmallString<256> Code;
- raw_svector_ostream VecOS(Code);
- Emitter->EncodeInstruction(Inst, VecOS);
- VecOS.flush();
-
- OS.indent(20);
- OS << " # encoding: [";
- for (unsigned i = 0, e = Code.size(); i != e; ++i) {
- if (i)
- OS << ',';
- OS << format("%#04x", uint8_t(Code[i]));
+void MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Filename){
+ OS << "\t.file\t" << FileNo << ' ';
+ PrintQuotedString(Filename, OS);
+ EmitEOL();
+}
+
+void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
+ raw_ostream &OS = GetCommentOS();
+ SmallString<256> Code;
+ SmallVector<MCFixup, 4> Fixups;
+ raw_svector_ostream VecOS(Code);
+ Emitter->EncodeInstruction(Inst, VecOS, Fixups);
+ VecOS.flush();
+
+ // If we are showing fixups, create symbolic markers in the encoded
+ // representation. We do this by making a per-bit map to the fixup item index,
+ // then trying to display it as nicely as possible.
+ SmallVector<uint8_t, 64> FixupMap;
+ FixupMap.resize(Code.size() * 8);
+ for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
+ FixupMap[i] = 0;
+
+ for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+ MCFixup &F = Fixups[i];
+ const MCFixupKindInfo &Info = Emitter->getFixupKindInfo(F.getKind());
+ for (unsigned j = 0; j != Info.TargetSize; ++j) {
+ unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
+ assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
+ FixupMap[Index] = 1 + i;
+ }
+ }
+
+ OS << "encoding: [";
+ for (unsigned i = 0, e = Code.size(); i != e; ++i) {
+ if (i)
+ OS << ',';
+
+ // See if all bits are the same map entry.
+ uint8_t MapEntry = FixupMap[i * 8 + 0];
+ for (unsigned j = 1; j != 8; ++j) {
+ if (FixupMap[i * 8 + j] == MapEntry)
+ continue;
+
+ MapEntry = uint8_t(~0U);
+ break;
+ }
+
+ if (MapEntry != uint8_t(~0U)) {
+ if (MapEntry == 0) {
+ OS << format("0x%02x", uint8_t(Code[i]));
+ } else {
+ assert(Code[i] == 0 && "Encoder wrote into fixed up bit!");
+ OS << char('A' + MapEntry - 1);
+ }
+ } else {
+ // Otherwise, write out in binary.
+ OS << "0b";
+ for (unsigned j = 8; j--;) {
+ unsigned Bit = (Code[i] >> j) & 1;
+ if (uint8_t MapEntry = FixupMap[i * 8 + j]) {
+ assert(Bit == 0 && "Encoder wrote into fixed up bit!");
+ OS << char('A' + MapEntry - 1);
+ } else
+ OS << Bit;
}
- OS << "]\n";
}
+ }
+ OS << "]\n";
- return;
+ for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+ MCFixup &F = Fixups[i];
+ const MCFixupKindInfo &Info = Emitter->getFixupKindInfo(F.getKind());
+ OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
+ << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
}
+}
+
+void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
+ assert(CurSection && "Cannot emit contents before setting section!");
- // Otherwise fall back to a structural printing for now. Eventually we should
- // always have access to the target specific printer.
- Inst.print(OS, &MAI);
+ // Show the encoding in a comment if we have a code emitter.
+ if (Emitter)
+ AddEncodingComment(Inst);
+
+ // Show the MCInst if enabled.
+ if (ShowInst) {
+ raw_ostream &OS = GetCommentOS();
+ OS << "<MCInst #" << Inst.getOpcode();
+
+ StringRef InstName;
+ if (InstPrinter)
+ InstName = InstPrinter->getOpcodeName(Inst.getOpcode());
+ if (!InstName.empty())
+ OS << ' ' << InstName;
+
+ for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) {
+ OS << "\n ";
+ Inst.getOperand(i).print(OS, &MAI);
+ }
+ OS << ">\n";
+ }
+
+ // If we have an AsmPrinter, use that to print, otherwise dump the MCInst.
+ if (InstPrinter)
+ InstPrinter->printInst(&Inst);
+ else
+ Inst.print(OS, &MAI);
EmitEOL();
}
void MCAsmStreamer::Finish() {
OS.flush();
}
-
+
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
formatted_raw_ostream &OS,
const MCAsmInfo &MAI, bool isLittleEndian,
bool isVerboseAsm, MCInstPrinter *IP,
- MCCodeEmitter *CE) {
+ MCCodeEmitter *CE, bool ShowInst) {
return new MCAsmStreamer(Context, OS, MAI, isLittleEndian, isVerboseAsm,
- IP, CE);
+ IP, CE, ShowInst);
}
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index f0f5a47..653fbf2 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -13,14 +13,20 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
-#include "llvm/Target/TargetMachOWriterInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MachO.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Debug.h"
+
+// FIXME: Gross.
+#include "../Target/X86/X86FixupKinds.h"
+
#include <vector>
using namespace llvm;
@@ -45,6 +51,30 @@ static bool isVirtualSection(const MCSection &Section) {
return (Type == MCSectionMachO::S_ZEROFILL);
}
+static unsigned getFixupKindLog2Size(MCFixupKind Kind) {
+ switch (Kind) {
+ default: llvm_unreachable("invalid fixup kind!");
+ case X86::reloc_pcrel_1byte:
+ case FK_Data_1: return 0;
+ case FK_Data_2: return 1;
+ case X86::reloc_pcrel_4byte:
+ case X86::reloc_riprel_4byte:
+ case FK_Data_4: return 2;
+ case FK_Data_8: return 3;
+ }
+}
+
+static bool isFixupKindPCRel(MCFixupKind Kind) {
+ switch (Kind) {
+ default:
+ return false;
+ case X86::reloc_pcrel_1byte:
+ case X86::reloc_pcrel_4byte:
+ case X86::reloc_riprel_4byte:
+ return true;
+ }
+}
+
class MachObjectWriter {
// See <mach-o/loader.h>.
enum {
@@ -203,9 +233,9 @@ public:
Write32(Header_Magic32);
// FIXME: Support cputype.
- Write32(TargetMachOWriterInfo::HDR_CPU_TYPE_I386);
+ Write32(MachO::CPUTypeI386);
// FIXME: Support cpusubtype.
- Write32(TargetMachOWriterInfo::HDR_CPU_SUBTYPE_I386_ALL);
+ Write32(MachO::CPUSubType_I386_ALL);
Write32(HFT_Object);
Write32(NumLoadCommands); // Object files have a single load command, the
// segment.
@@ -266,11 +296,15 @@ public:
Write32(SD.getSize()); // size
Write32(FileOffset);
+ unsigned Flags = Section.getTypeAndAttributes();
+ if (SD.hasInstructions())
+ Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS;
+
assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
Write32(Log2_32(SD.getAlignment()));
Write32(NumRelocations ? RelocationsStart : 0);
Write32(NumRelocations);
- Write32(Section.getTypeAndAttributes());
+ Write32(Flags);
Write32(0); // reserved1
Write32(Section.getStubSize()); // reserved2
@@ -398,12 +432,12 @@ public:
uint32_t Word0;
uint32_t Word1;
};
- void ComputeScatteredRelocationInfo(MCAssembler &Asm,
- MCSectionData::Fixup &Fixup,
+ void ComputeScatteredRelocationInfo(MCAssembler &Asm, MCFragment &Fragment,
+ MCAsmFixup &Fixup,
const MCValue &Target,
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
std::vector<MachRelocationEntry> &Relocs) {
- uint32_t Address = Fixup.Fragment->getOffset() + Fixup.Offset;
+ uint32_t Address = Fragment.getOffset() + Fixup.Offset;
unsigned IsPCRel = 0;
unsigned Type = RIT_Vanilla;
@@ -420,11 +454,14 @@ public:
Value2 = SD->getFragment()->getAddress() + SD->getOffset();
}
- unsigned Log2Size = Log2_32(Fixup.Size);
- assert((1U << Log2Size) == Fixup.Size && "Invalid fixup size!");
+ unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
// The value which goes in the fixup is current value of the expression.
Fixup.FixedValue = Value - Value2 + Target.getConstant();
+ if (isFixupKindPCRel(Fixup.Kind)) {
+ Fixup.FixedValue -= Address + (1 << Log2Size);
+ IsPCRel = 1;
+ }
MachRelocationEntry MRE;
MRE.Word0 = ((Address << 0) |
@@ -449,8 +486,8 @@ public:
}
}
- void ComputeRelocationInfo(MCAssembler &Asm,
- MCSectionData::Fixup &Fixup,
+ void ComputeRelocationInfo(MCAssembler &Asm, MCDataFragment &Fragment,
+ MCAsmFixup &Fixup,
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
std::vector<MachRelocationEntry> &Relocs) {
MCValue Target;
@@ -462,11 +499,11 @@ public:
if (Target.getSymB() ||
(Target.getSymA() && !Target.getSymA()->isUndefined() &&
Target.getConstant()))
- return ComputeScatteredRelocationInfo(Asm, Fixup, Target,
+ return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target,
SymbolMap, Relocs);
// See <reloc.h>.
- uint32_t Address = Fixup.Fragment->getOffset() + Fixup.Offset;
+ uint32_t Address = Fragment.getOffset() + Fixup.Offset;
uint32_t Value = 0;
unsigned Index = 0;
unsigned IsPCRel = 0;
@@ -475,6 +512,8 @@ public:
if (Target.isAbsolute()) { // constant
// SymbolNum of 0 indicates the absolute section.
+ //
+ // FIXME: When is this generated?
Type = RIT_Vanilla;
Value = 0;
llvm_unreachable("FIXME: Not yet implemented!");
@@ -491,10 +530,11 @@ public:
//
// FIXME: O(N)
Index = 1;
- for (MCAssembler::iterator it = Asm.begin(),
- ie = Asm.end(); it != ie; ++it, ++Index)
+ MCAssembler::iterator it = Asm.begin(), ie = Asm.end();
+ for (; it != ie; ++it, ++Index)
if (&*it == SD->getFragment()->getParent())
break;
+ assert(it != ie && "Unable to find section index!");
Value = SD->getFragment()->getAddress() + SD->getOffset();
}
@@ -504,8 +544,12 @@ public:
// The value which goes in the fixup is current value of the expression.
Fixup.FixedValue = Value + Target.getConstant();
- unsigned Log2Size = Log2_32(Fixup.Size);
- assert((1U << Log2Size) == Fixup.Size && "Invalid fixup size!");
+ unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
+
+ if (isFixupKindPCRel(Fixup.Kind)) {
+ Fixup.FixedValue -= Address + (1<<Log2Size);
+ IsPCRel = 1;
+ }
// struct relocation_info (8 bytes)
MachRelocationEntry MRE;
@@ -742,7 +786,7 @@ public:
SD.getAddress() + SD.getFileSize());
}
- // The section data is passed to 4 bytes.
+ // The section data is padded to 4 bytes.
//
// FIXME: Is this machine dependent?
unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4);
@@ -757,22 +801,25 @@ public:
// ... and then the section headers.
//
// We also compute the section relocations while we do this. Note that
- // compute relocation info will also update the fixup to have the correct
- // value; this will be overwrite the appropriate data in the fragment when
- // it is written.
+ // computing relocation info will also update the fixup to have the correct
+ // value; this will overwrite the appropriate data in the fragment when it
+ // is written.
std::vector<MachRelocationEntry> RelocInfos;
uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
- for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie;
- ++it) {
+ for (MCAssembler::iterator it = Asm.begin(),
+ ie = Asm.end(); it != ie; ++it) {
MCSectionData &SD = *it;
// The assembler writes relocations in the reverse order they were seen.
//
// FIXME: It is probably more complicated than this.
unsigned NumRelocsStart = RelocInfos.size();
- for (unsigned i = 0, e = SD.fixup_size(); i != e; ++i)
- ComputeRelocationInfo(Asm, SD.getFixups()[e - i - 1], SymbolMap,
- RelocInfos);
+ for (MCSectionData::reverse_iterator it2 = SD.rbegin(),
+ ie2 = SD.rend(); it2 != ie2; ++it2)
+ if (MCDataFragment *DF = dyn_cast<MCDataFragment>(&*it2))
+ for (unsigned i = 0, e = DF->fixup_size(); i != e; ++i)
+ ComputeRelocationInfo(Asm, *DF, DF->getFixups()[e - i - 1],
+ SymbolMap, RelocInfos);
unsigned NumRelocs = RelocInfos.size() - NumRelocsStart;
uint64_t SectionStart = SectionDataStart + SD.getAddress();
@@ -867,6 +914,16 @@ public:
OS << StringTable.str();
}
}
+
+ void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF) {
+ unsigned Size = 1 << getFixupKindLog2Size(Fixup.Kind);
+
+ // FIXME: Endianness assumption.
+ assert(Fixup.Offset + Size <= DF.getContents().size() &&
+ "Invalid fixup offset!");
+ for (unsigned i = 0; i != Size; ++i)
+ DF.getContents()[Fixup.Offset + i] = uint8_t(Fixup.FixedValue >> (i * 8));
+ }
};
/* *** */
@@ -901,34 +958,12 @@ MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
Address(~UINT64_C(0)),
Size(~UINT64_C(0)),
FileSize(~UINT64_C(0)),
- LastFixupLookup(~0)
+ HasInstructions(false)
{
if (A)
A->getSectionList().push_back(this);
}
-const MCSectionData::Fixup *
-MCSectionData::LookupFixup(const MCFragment *Fragment, uint64_t Offset) const {
- // Use a one level cache to turn the common case of accessing the fixups in
- // order into O(1) instead of O(N).
- unsigned i = LastFixupLookup, Count = Fixups.size(), End = Fixups.size();
- if (i >= End)
- i = 0;
- while (Count--) {
- const Fixup &F = Fixups[i];
- if (F.Fragment == Fragment && F.Offset == Offset) {
- LastFixupLookup = i;
- return &F;
- }
-
- ++i;
- if (i == End)
- i = 0;
- }
-
- return 0;
-}
-
/* *** */
MCSymbolData::MCSymbolData() : Symbol(0) {}
@@ -975,31 +1010,10 @@ void MCAssembler::LayoutSection(MCSectionData &SD) {
}
case MCFragment::FT_Data:
+ case MCFragment::FT_Fill:
F.setFileSize(F.getMaxFileSize());
break;
- case MCFragment::FT_Fill: {
- MCFillFragment &FF = cast<MCFillFragment>(F);
-
- F.setFileSize(F.getMaxFileSize());
-
- MCValue Target;
- if (!FF.getValue().EvaluateAsRelocatable(Target))
- llvm_report_error("expected relocatable expression");
-
- // If the fill value is constant, thats it.
- if (Target.isAbsolute())
- break;
-
- // Otherwise, add fixups for the values.
- for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) {
- MCSectionData::Fixup Fix(F, i * FF.getValueSize(),
- FF.getValue(),FF.getValueSize());
- SD.getFixups().push_back(Fix);
- }
- break;
- }
-
case MCFragment::FT_Org: {
MCOrgFragment &OF = cast<MCOrgFragment>(F);
@@ -1082,39 +1096,30 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F,
break;
}
- case MCFragment::FT_Data:
+ case MCFragment::FT_Data: {
+ MCDataFragment &DF = cast<MCDataFragment>(F);
+
+ // Apply the fixups.
+ //
+ // FIXME: Move elsewhere.
+ for (MCDataFragment::const_fixup_iterator it = DF.fixup_begin(),
+ ie = DF.fixup_end(); it != ie; ++it)
+ MOW.ApplyFixup(*it, DF);
+
OS << cast<MCDataFragment>(F).getContents().str();
break;
+ }
case MCFragment::FT_Fill: {
MCFillFragment &FF = cast<MCFillFragment>(F);
-
- int64_t Value = 0;
-
- MCValue Target;
- if (!FF.getValue().EvaluateAsRelocatable(Target))
- llvm_report_error("expected relocatable expression");
-
- if (Target.isAbsolute())
- Value = Target.getConstant();
for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) {
- if (!Target.isAbsolute()) {
- // Find the fixup.
- //
- // FIXME: Find a better way to write in the fixes.
- const MCSectionData::Fixup *Fixup =
- F.getParent()->LookupFixup(&F, i * FF.getValueSize());
- assert(Fixup && "Missing fixup for fill value!");
- Value = Fixup->FixedValue;
- }
-
switch (FF.getValueSize()) {
default:
assert(0 && "Invalid size!");
- case 1: MOW.Write8 (uint8_t (Value)); break;
- case 2: MOW.Write16(uint16_t(Value)); break;
- case 4: MOW.Write32(uint32_t(Value)); break;
- case 8: MOW.Write64(uint64_t(Value)); break;
+ case 1: MOW.Write8 (uint8_t (FF.getValue())); break;
+ case 2: MOW.Write16(uint16_t(FF.getValue())); break;
+ case 4: MOW.Write32(uint32_t(FF.getValue())); break;
+ case 8: MOW.Write64(uint64_t(FF.getValue())); break;
}
}
break;
@@ -1162,6 +1167,10 @@ static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
}
void MCAssembler::Finish() {
+ DEBUG_WITH_TYPE("mc-dump", {
+ llvm::errs() << "assembler backend - pre-layout\n--\n";
+ dump(); });
+
// Layout the concrete sections and fragments.
uint64_t Address = 0;
MCSectionData *Prev = 0;
@@ -1200,9 +1209,149 @@ void MCAssembler::Finish() {
Address += SD.getSize();
}
+ DEBUG_WITH_TYPE("mc-dump", {
+ llvm::errs() << "assembler backend - post-layout\n--\n";
+ dump(); });
+
// Write the object file.
MachObjectWriter MOW(OS);
MOW.WriteObject(*this);
OS.flush();
}
+
+
+// Debugging methods
+
+namespace llvm {
+
+raw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) {
+ OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << *AF.Value
+ << " Kind:" << AF.Kind << ">";
+ return OS;
+}
+
+}
+
+void MCFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCFragment " << (void*) this << " Offset:" << Offset
+ << " FileSize:" << FileSize;
+
+ OS << ">";
+}
+
+void MCAlignFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCAlignFragment ";
+ this->MCFragment::dump();
+ OS << "\n ";
+ OS << " Alignment:" << getAlignment()
+ << " Value:" << getValue() << " ValueSize:" << getValueSize()
+ << " MaxBytesToEmit:" << getMaxBytesToEmit() << ">";
+}
+
+void MCDataFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCDataFragment ";
+ this->MCFragment::dump();
+ OS << "\n ";
+ OS << " Contents:[";
+ for (unsigned i = 0, e = getContents().size(); i != e; ++i) {
+ if (i) OS << ",";
+ OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
+ }
+ OS << "] (" << getContents().size() << " bytes)";
+
+ if (!getFixups().empty()) {
+ OS << ",\n ";
+ OS << " Fixups:[";
+ for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) {
+ if (it != fixup_begin()) OS << ",\n ";
+ OS << *it;
+ }
+ OS << "]";
+ }
+
+ OS << ">";
+}
+
+void MCFillFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCFillFragment ";
+ this->MCFragment::dump();
+ OS << "\n ";
+ OS << " Value:" << getValue() << " ValueSize:" << getValueSize()
+ << " Count:" << getCount() << ">";
+}
+
+void MCOrgFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCOrgFragment ";
+ this->MCFragment::dump();
+ OS << "\n ";
+ OS << " Offset:" << getOffset() << " Value:" << getValue() << ">";
+}
+
+void MCZeroFillFragment::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCZeroFillFragment ";
+ this->MCFragment::dump();
+ OS << "\n ";
+ OS << " Size:" << getSize() << " Alignment:" << getAlignment() << ">";
+}
+
+void MCSectionData::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCSectionData";
+ OS << " Alignment:" << getAlignment() << " Address:" << Address
+ << " Size:" << Size << " FileSize:" << FileSize
+ << " Fragments:[";
+ for (iterator it = begin(), ie = end(); it != ie; ++it) {
+ if (it != begin()) OS << ",\n ";
+ it->dump();
+ }
+ OS << "]>";
+}
+
+void MCSymbolData::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCSymbolData Symbol:" << getSymbol()
+ << " Fragment:" << getFragment() << " Offset:" << getOffset()
+ << " Flags:" << getFlags() << " Index:" << getIndex();
+ if (isCommon())
+ OS << " (common, size:" << getCommonSize()
+ << " align: " << getCommonAlignment() << ")";
+ if (isExternal())
+ OS << " (external)";
+ if (isPrivateExtern())
+ OS << " (private extern)";
+ OS << ">";
+}
+
+void MCAssembler::dump() {
+ raw_ostream &OS = llvm::errs();
+
+ OS << "<MCAssembler\n";
+ OS << " Sections:[";
+ for (iterator it = begin(), ie = end(); it != ie; ++it) {
+ if (it != begin()) OS << ",\n ";
+ it->dump();
+ }
+ OS << "],\n";
+ OS << " Symbols:[";
+
+ for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) {
+ if (it != symbol_begin()) OS << ",\n ";
+ it->dump();
+ }
+ OS << "]>\n";
+}
diff --git a/lib/MC/MCCodeEmitter.cpp b/lib/MC/MCCodeEmitter.cpp
index c122763..accb06c 100644
--- a/lib/MC/MCCodeEmitter.cpp
+++ b/lib/MC/MCCodeEmitter.cpp
@@ -16,3 +16,15 @@ MCCodeEmitter::MCCodeEmitter() {
MCCodeEmitter::~MCCodeEmitter() {
}
+
+const MCFixupKindInfo &MCCodeEmitter::getFixupKindInfo(MCFixupKind Kind) const {
+ static const MCFixupKindInfo Builtins[] = {
+ { "FK_Data_1", 0, 8 },
+ { "FK_Data_2", 0, 16 },
+ { "FK_Data_4", 0, 32 },
+ { "FK_Data_8", 0, 64 }
+ };
+
+ assert(Kind <= 3 && "Unknown fixup kind");
+ return Builtins[Kind];
+}
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index 1ee1b1b..e419043 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -17,6 +17,8 @@ using namespace llvm;
void MCExpr::print(raw_ostream &OS) const {
switch (getKind()) {
+ case MCExpr::Target:
+ return cast<MCTargetExpr>(this)->PrintImpl(OS);
case MCExpr::Constant:
OS << cast<MCConstantExpr>(*this).getValue();
return;
@@ -131,6 +133,7 @@ const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, MCContext &Ctx) {
return Create(Ctx.GetOrCreateSymbol(Name), Ctx);
}
+void MCTargetExpr::Anchor() {}
/* *** */
@@ -168,6 +171,9 @@ static bool EvaluateSymbolicAdd(const MCValue &LHS, const MCSymbol *RHS_A,
bool MCExpr::EvaluateAsRelocatable(MCValue &Res) const {
switch (getKind()) {
+ case Target:
+ return cast<MCTargetExpr>(this)->EvaluateAsRelocatableImpl(Res);
+
case Constant:
Res = MCValue::get(cast<MCConstantExpr>(this)->getValue());
return true;
@@ -246,8 +252,8 @@ bool MCExpr::EvaluateAsRelocatable(MCValue &Res) const {
}
// FIXME: We need target hooks for the evaluation. It may be limited in
- // width, and gas defines the result of comparisons differently from Apple
- // as (the result is sign extended).
+ // width, and gas defines the result of comparisons and right shifts
+ // differently from Apple as.
int64_t LHS = LHSValue.getConstant(), RHS = RHSValue.getConstant();
int64_t Result = 0;
switch (ABE->getOpcode()) {
diff --git a/lib/MC/MCInstPrinter.cpp b/lib/MC/MCInstPrinter.cpp
index e90c03c..92a7154 100644
--- a/lib/MC/MCInstPrinter.cpp
+++ b/lib/MC/MCInstPrinter.cpp
@@ -8,7 +8,14 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/ADT/StringRef.h"
using namespace llvm;
MCInstPrinter::~MCInstPrinter() {
}
+
+/// getOpcodeName - Return the name of the specified opcode enum (e.g.
+/// "MOV32ri") or empty if we can't resolve it.
+StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const {
+ return "";
+}
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index e559c65..0c9627d 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -46,13 +46,9 @@ class MCMachOStreamer : public MCStreamer {
private:
MCAssembler Assembler;
-
MCCodeEmitter *Emitter;
-
MCSectionData *CurSectionData;
-
DenseMap<const MCSection*, MCSectionData*> SectionMap;
-
DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
private:
@@ -91,6 +87,7 @@ public:
const MCExpr *AddValueSymbols(const MCExpr *Value) {
switch (Value->getKind()) {
+ case MCExpr::Target: assert(0 && "Can't handle target exprs yet!");
case MCExpr::Constant:
break;
@@ -124,6 +121,9 @@ public:
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
+ virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
+ assert(0 && "macho doesn't support this directive");
+ }
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
assert(0 && "macho doesn't support this directive");
}
@@ -131,11 +131,22 @@ public:
unsigned Size = 0, unsigned ByteAlignment = 0);
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
+ virtual void EmitGPRel32Value(const MCExpr *Value) {
+ assert(0 && "macho doesn't support this directive");
+ }
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0);
virtual void EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0);
+
+ virtual void EmitFileDirective(StringRef Filename) {
+ errs() << "FIXME: MCMachoStreamer:EmitFileDirective not implemented\n";
+ }
+ virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) {
+ errs() << "FIXME: MCMachoStreamer:EmitDwarfFileDirective not implemented\n";
+ }
+
virtual void EmitInstruction(const MCInst &Inst);
virtual void Finish();
@@ -220,6 +231,12 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
// defined.
switch (Attribute) {
case MCSA_Invalid:
+ case MCSA_ELF_TypeFunction:
+ case MCSA_ELF_TypeIndFunction:
+ case MCSA_ELF_TypeObject:
+ case MCSA_ELF_TypeTLS:
+ case MCSA_ELF_TypeCommon:
+ case MCSA_ELF_TypeNoType:
case MCSA_IndirectSymbol:
case MCSA_Hidden:
case MCSA_Internal:
@@ -316,7 +333,24 @@ void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size,
unsigned AddrSpace) {
- new MCFillFragment(*AddValueSymbols(Value), Size, 1, CurSectionData);
+ // Assume the front-end will have evaluate things absolute expressions, so
+ // just create data + fixup.
+ MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
+ if (!DF)
+ DF = new MCDataFragment(CurSectionData);
+
+ // Avoid fixups when possible.
+ int64_t AbsValue;
+ if (Value->EvaluateAsAbsolute(AbsValue)) {
+ // FIXME: Endianness assumption.
+ for (unsigned i = 0; i != Size; ++i)
+ DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
+ } else {
+ DF->getFixups().push_back(MCAsmFixup(DF->getContents().size(),
+ *AddValueSymbols(Value),
+ MCFixup::getKindForSize(Size)));
+ DF->getContents().resize(DF->getContents().size() + Size, 0);
+ }
}
void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
@@ -346,13 +380,25 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
if (!Emitter)
llvm_unreachable("no code emitter available!");
- // FIXME: Emitting an instruction should cause S_ATTR_SOME_INSTRUCTIONS to
- // be set for the current section.
- // FIXME: Relocations!
+ CurSectionData->setHasInstructions(true);
+
+ SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
- Emitter->EncodeInstruction(Inst, VecOS);
- EmitBytes(VecOS.str(), 0);
+ Emitter->EncodeInstruction(Inst, VecOS, Fixups);
+ VecOS.flush();
+
+ // Add the fixups and data.
+ MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
+ if (!DF)
+ DF = new MCDataFragment(CurSectionData);
+ for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+ MCFixup &F = Fixups[i];
+ DF->getFixups().push_back(MCAsmFixup(DF->getContents().size()+F.getOffset(),
+ *F.getValue(),
+ F.getKind()));
+ }
+ DF->getContents().append(Code.begin(), Code.end());
}
void MCMachOStreamer::Finish() {
diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index 7c219b3..46e9ebf 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/lib/MC/MCNullStreamer.cpp
@@ -38,7 +38,7 @@ namespace {
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute){}
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
-
+ virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {}
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {}
@@ -50,7 +50,7 @@ namespace {
virtual void EmitValue(const MCExpr *Value, unsigned Size,
unsigned AddrSpace) {}
-
+ virtual void EmitGPRel32Value(const MCExpr *Value) {}
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0) {}
@@ -58,6 +58,8 @@ namespace {
virtual void EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0) {}
+ virtual void EmitFileDirective(StringRef Filename) {}
+ virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) {}
virtual void EmitInstruction(const MCInst &Inst) {}
virtual void Finish() {}
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index dd438b7..51ad5d1 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -325,18 +325,25 @@ bool AsmParser::ParseExpression(const MCExpr *&Res) {
/// expr ::= primaryexpr
///
bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+ // Parse the expression.
Res = 0;
- return ParsePrimaryExpr(Res, EndLoc) ||
- ParseBinOpRHS(1, Res, EndLoc);
-}
-
-bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
- if (ParseParenExpr(Res, EndLoc))
+ if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
return true;
+ // Try to constant fold it up front, if possible.
+ int64_t Value;
+ if (Res->EvaluateAsAbsolute(Value))
+ Res = MCConstantExpr::Create(Value, getContext());
+
return false;
}
+bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+ Res = 0;
+ return ParseParenExpr(Res, EndLoc) ||
+ ParseBinOpRHS(1, Res, EndLoc);
+}
+
bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
const MCExpr *Expr;
@@ -1709,14 +1716,18 @@ bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
if (Lexer.isNot(AsmToken::String))
return TokError("unexpected token in '.file' directive");
- StringRef ATTRIBUTE_UNUSED FileName = getTok().getString();
+ StringRef Filename = getTok().getString();
+ Filename = Filename.substr(1, Filename.size()-2);
Lex();
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.file' directive");
- // FIXME: Do something with the .file.
-
+ if (FileNumber == -1)
+ Out.EmitFileDirective(Filename);
+ else
+ Out.EmitDwarfFileDirective(FileNumber, Filename);
+
return false;
}
diff --git a/lib/MC/MCParser/Makefile b/lib/MC/MCParser/Makefile
index e4eb483..4477757 100644
--- a/lib/MC/MCParser/Makefile
+++ b/lib/MC/MCParser/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMMCParser
BUILD_ARCHIVE := 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/MC/Makefile b/lib/MC/Makefile
index 371776f..a661fa6 100644
--- a/lib/MC/Makefile
+++ b/lib/MC/Makefile
@@ -11,7 +11,6 @@ LEVEL = ../..
LIBRARYNAME = LLVMMC
BUILD_ARCHIVE := 1
PARALLEL_DIRS := MCParser
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 9d14684..3bce3f3 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -273,7 +273,7 @@ APInt& APInt::operator-=(const APInt& RHS) {
return clearUnusedBits();
}
-/// Multiplies an integer array, x by a a uint64_t integer and places the result
+/// Multiplies an integer array, x, by a uint64_t integer and places the result
/// into dest.
/// @returns the carry out of the multiplication.
/// @brief Multiply a multi-digit APInt by a single digit (64-bit) integer.
@@ -767,8 +767,23 @@ bool APInt::isPowerOf2() const {
}
unsigned APInt::countLeadingZerosSlowCase() const {
- unsigned Count = 0;
- for (unsigned i = getNumWords(); i > 0u; --i) {
+ // Treat the most significand word differently because it might have
+ // meaningless bits set beyond the precision.
+ unsigned BitsInMSW = BitWidth % APINT_BITS_PER_WORD;
+ integerPart MSWMask;
+ if (BitsInMSW) MSWMask = (integerPart(1) << BitsInMSW) - 1;
+ else {
+ MSWMask = ~integerPart(0);
+ BitsInMSW = APINT_BITS_PER_WORD;
+ }
+
+ unsigned i = getNumWords();
+ integerPart MSW = pVal[i-1] & MSWMask;
+ if (MSW)
+ return CountLeadingZeros_64(MSW) - (APINT_BITS_PER_WORD - BitsInMSW);
+
+ unsigned Count = BitsInMSW;
+ for (--i; i > 0u; --i) {
if (pVal[i-1] == 0)
Count += APINT_BITS_PER_WORD;
else {
@@ -776,10 +791,7 @@ unsigned APInt::countLeadingZerosSlowCase() const {
break;
}
}
- unsigned remainder = BitWidth % APINT_BITS_PER_WORD;
- if (remainder)
- Count -= APINT_BITS_PER_WORD - remainder;
- return std::min(Count, BitWidth);
+ return Count;
}
static unsigned countLeadingOnes_64(uint64_t V, unsigned skip) {
@@ -1754,7 +1766,7 @@ void APInt::divide(const APInt LHS, unsigned lhsWords,
// First, compose the values into an array of 32-bit words instead of
// 64-bit words. This is a necessity of both the "short division" algorithm
- // and the the Knuth "classical algorithm" which requires there to be native
+ // and the Knuth "classical algorithm" which requires there to be native
// operations for +, -, and * on an m bit value with an m*2 bit result. We
// can't use 64-bit operands here because we don't have native results of
// 128-bits. Furthermore, casting the 64-bit values to 32-bit values won't
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index fa692be8..961dc1f 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -507,8 +507,9 @@ void cl::ParseCommandLineOptions(int argc, char **argv,
// Copy the program name into ProgName, making sure not to overflow it.
std::string ProgName = sys::Path(argv[0]).getLast();
- if (ProgName.size() > 79) ProgName.resize(79);
- strcpy(ProgramName, ProgName.c_str());
+ size_t Len = std::min(ProgName.size(), size_t(79));
+ memcpy(ProgramName, ProgName.data(), Len);
+ ProgramName[Len] = '\0';
ProgramOverview = Overview;
bool ErrorParsing = false;
diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp
index ddf14e3..2746f7a 100644
--- a/lib/Support/ConstantRange.cpp
+++ b/lib/Support/ConstantRange.cpp
@@ -540,6 +540,11 @@ ConstantRange::add(const ConstantRange &Other) const {
ConstantRange
ConstantRange::multiply(const ConstantRange &Other) const {
+ // TODO: If either operand is a single element and the multiply is known to
+ // be non-wrapping, round the result min and max value to the appropriate
+ // multiple of that element. If wrapping is possible, at least adjust the
+ // range according to the greatest power-of-two factor of the single element.
+
if (isEmptySet() || Other.isEmptySet())
return ConstantRange(getBitWidth(), /*isFullSet=*/false);
if (isFullSet() || Other.isFullSet())
@@ -650,7 +655,12 @@ ConstantRange::lshr(const ConstantRange &Amount) const {
/// print - Print out the bounds to a stream...
///
void ConstantRange::print(raw_ostream &OS) const {
- OS << "[" << Lower << "," << Upper << ")";
+ if (isFullSet())
+ OS << "full-set";
+ else if (isEmptySet())
+ OS << "empty-set";
+ else
+ OS << "[" << Lower << "," << Upper << ")";
}
/// dump - Allow printing from a debugger easily...
diff --git a/lib/Support/FileUtilities.cpp b/lib/Support/FileUtilities.cpp
index 21080b6..095395f 100644
--- a/lib/Support/FileUtilities.cpp
+++ b/lib/Support/FileUtilities.cpp
@@ -13,11 +13,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/FileUtilities.h"
-#include "llvm/System/Path.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
#include <cstdlib>
#include <cstring>
#include <cctype>
@@ -139,11 +139,11 @@ static bool CompareNumbers(const char *&F1P, const char *&F2P,
Diff = 0; // Both zero.
if (Diff > RelTolerance) {
if (ErrorMsg) {
- *ErrorMsg = "Compared: " + ftostr(V1) + " and " + ftostr(V2) + "\n";
- *ErrorMsg += "abs. diff = " + ftostr(std::abs(V1-V2)) +
- " rel.diff = " + ftostr(Diff) + "\n";
- *ErrorMsg += "Out of tolerance: rel/abs: " + ftostr(RelTolerance) +
- "/" + ftostr(AbsTolerance);
+ raw_string_ostream(*ErrorMsg)
+ << "Compared: " << V1 << " and " << V2 << '\n'
+ << "abs. diff = " << std::abs(V1-V2) << " rel.diff = " << Diff << '\n'
+ << "Out of tolerance: rel/abs: " << RelTolerance << '/'
+ << AbsTolerance;
}
return true;
}
diff --git a/lib/Support/FormattedStream.cpp b/lib/Support/FormattedStream.cpp
index 9ab3666..39b6cb3 100644
--- a/lib/Support/FormattedStream.cpp
+++ b/lib/Support/FormattedStream.cpp
@@ -59,12 +59,13 @@ void formatted_raw_ostream::ComputeColumn(const char *Ptr, size_t Size) {
/// \param MinPad - The minimum space to give after the most recent
/// I/O, even if the current column + minpad > newcol.
///
-void formatted_raw_ostream::PadToColumn(unsigned NewCol) {
+formatted_raw_ostream &formatted_raw_ostream::PadToColumn(unsigned NewCol) {
// Figure out what's in the buffer and add it to the column count.
ComputeColumn(getBufferStart(), GetNumBytesInBuffer());
// Output spaces until we reach the desired column.
indent(std::max(int(NewCol - ColumnScanned), 1));
+ return *this;
}
void formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) {
diff --git a/lib/Support/SourceMgr.cpp b/lib/Support/SourceMgr.cpp
index bdc637a..83c7964 100644
--- a/lib/Support/SourceMgr.cpp
+++ b/lib/Support/SourceMgr.cpp
@@ -35,7 +35,7 @@ SourceMgr::~SourceMgr() {
// Delete the line # cache if allocated.
if (LineNoCacheTy *Cache = getCache(LineNoCache))
delete Cache;
-
+
while (!Buffers.empty()) {
delete Buffers.back().Buffer;
Buffers.pop_back();
@@ -47,7 +47,7 @@ SourceMgr::~SourceMgr() {
/// ~0, otherwise it returns the buffer ID of the stacked file.
unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
SMLoc IncludeLoc) {
-
+
MemoryBuffer *NewBuf = MemoryBuffer::getFile(Filename.c_str());
// If the file didn't exist directly, see if it's in an include path.
@@ -55,7 +55,7 @@ unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
std::string IncFile = IncludeDirectories[i] + "/" + Filename;
NewBuf = MemoryBuffer::getFile(IncFile.c_str());
}
-
+
if (NewBuf == 0) return ~0U;
return AddNewSourceBuffer(NewBuf, IncludeLoc);
@@ -79,20 +79,20 @@ int SourceMgr::FindBufferContainingLoc(SMLoc Loc) const {
unsigned SourceMgr::FindLineNumber(SMLoc Loc, int BufferID) const {
if (BufferID == -1) BufferID = FindBufferContainingLoc(Loc);
assert(BufferID != -1 && "Invalid Location!");
-
+
MemoryBuffer *Buff = getBufferInfo(BufferID).Buffer;
-
+
// Count the number of \n's between the start of the file and the specified
// location.
unsigned LineNo = 1;
-
+
const char *Ptr = Buff->getBufferStart();
// If we have a line number cache, and if the query is to a later point in the
// same file, start searching from the last query location. This optimizes
// for the case when multiple diagnostics come out of one file in order.
if (LineNoCacheTy *Cache = getCache(LineNoCache))
- if (Cache->LastQueryBufferID == BufferID &&
+ if (Cache->LastQueryBufferID == BufferID &&
Cache->LastQuery <= Loc.getPointer()) {
Ptr = Cache->LastQuery;
LineNo = Cache->LineNoOfQuery;
@@ -102,12 +102,12 @@ unsigned SourceMgr::FindLineNumber(SMLoc Loc, int BufferID) const {
// we see.
for (; SMLoc::getFromPointer(Ptr) != Loc; ++Ptr)
if (*Ptr == '\n') ++LineNo;
-
-
+
+
// Allocate the line number cache if it doesn't exist.
if (LineNoCache == 0)
LineNoCache = new LineNoCacheTy();
-
+
// Update the line # cache.
LineNoCacheTy &Cache = *getCache(LineNoCache);
Cache.LastQueryBufferID = BufferID;
@@ -118,12 +118,12 @@ unsigned SourceMgr::FindLineNumber(SMLoc Loc, int BufferID) const {
void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const {
if (IncludeLoc == SMLoc()) return; // Top of stack.
-
+
int CurBuf = FindBufferContainingLoc(IncludeLoc);
assert(CurBuf != -1 && "Invalid or unspecified location!");
PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
-
+
OS << "Included from "
<< getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
<< ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n";
@@ -137,12 +137,12 @@ void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const {
/// prefixed to the message.
SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, const std::string &Msg,
const char *Type, bool ShowLine) const {
-
+
// First thing to do: find the current buffer containing the specified
// location.
int CurBuf = FindBufferContainingLoc(Loc);
assert(CurBuf != -1 && "Invalid or unspecified location!");
-
+
MemoryBuffer *CurMB = getBufferInfo(CurBuf).Buffer;
// Scan backward to find the start of the line.
@@ -160,7 +160,7 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, const std::string &Msg,
++LineEnd;
LineStr = std::string(LineStart, LineEnd);
}
-
+
std::string PrintedMsg;
if (Type) {
PrintedMsg = Type;
@@ -173,7 +173,7 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, const std::string &Msg,
LineStr, ShowLine);
}
-void SourceMgr::PrintMessage(SMLoc Loc, const std::string &Msg,
+void SourceMgr::PrintMessage(SMLoc Loc, const std::string &Msg,
const char *Type, bool ShowLine) const {
raw_ostream &OS = errs();
@@ -188,7 +188,7 @@ void SourceMgr::PrintMessage(SMLoc Loc, const std::string &Msg,
// SMDiagnostic Implementation
//===----------------------------------------------------------------------===//
-void SMDiagnostic::Print(const char *ProgName, raw_ostream &S) {
+void SMDiagnostic::Print(const char *ProgName, raw_ostream &S) const {
if (ProgName && ProgName[0])
S << ProgName << ": ";
@@ -197,7 +197,7 @@ void SMDiagnostic::Print(const char *ProgName, raw_ostream &S) {
S << "<stdin>";
else
S << Filename;
-
+
if (LineNo != -1) {
S << ':' << LineNo;
if (ColumnNo != -1)
@@ -205,12 +205,12 @@ void SMDiagnostic::Print(const char *ProgName, raw_ostream &S) {
}
S << ": ";
}
-
+
S << Message << '\n';
if (LineNo != -1 && ColumnNo != -1 && ShowLine) {
S << LineContents << '\n';
-
+
// Print out spaces/tabs before the caret.
for (unsigned i = 0; i != unsigned(ColumnNo); ++i)
S << (LineContents[i] == '\t' ? '\t' : ' ');
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index 2fec094..5a76184 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -33,6 +33,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case ppc64: return "powerpc64";
case ppc: return "powerpc";
case sparc: return "sparc";
+ case sparcv9: return "sparcv9";
case systemz: return "s390x";
case tce: return "tce";
case thumb: return "thumb";
@@ -61,6 +62,7 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case ppc64:
case ppc: return "ppc";
+ case sparcv9:
case sparc: return "sparc";
case x86:
@@ -127,6 +129,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
return ppc;
if (Name == "sparc")
return sparc;
+ if (Name == "sparcv9")
+ return sparcv9;
if (Name == "systemz")
return systemz;
if (Name == "tce")
@@ -250,6 +254,8 @@ void Triple::Parse() const {
Arch = mipsel;
else if (ArchName == "sparc")
Arch = sparc;
+ else if (ArchName == "sparcv9")
+ Arch = sparcv9;
else if (ArchName == "s390x")
Arch = systemz;
else if (ArchName == "tce")
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index 10d7ec0..25c3fbd 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -20,7 +20,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
+#include <cctype>
#include <sys/stat.h>
#include <sys/types.h>
@@ -209,7 +209,7 @@ raw_ostream &raw_ostream::operator<<(const void *P) {
}
raw_ostream &raw_ostream::operator<<(double N) {
- return this->operator<<(ftostr(N));
+ return this->operator<<(format("%e", N));
}
@@ -574,12 +574,18 @@ void raw_svector_ostream::resync() {
}
void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
- assert(Ptr == OS.end() && OS.size() + Size <= OS.capacity() &&
- "Invalid write_impl() call!");
-
- // We don't need to copy the bytes, just commit the bytes to the
- // SmallVector.
- OS.set_size(OS.size() + Size);
+ // If we're writing bytes from the end of the buffer into the smallvector, we
+ // don't need to copy the bytes, just commit the bytes because they are
+ // already in the right place.
+ if (Ptr == OS.end()) {
+ assert(OS.size() + Size <= OS.capacity() && "Invalid write_impl() call!");
+ OS.set_size(OS.size() + Size);
+ } else {
+ assert(GetNumBytesInBuffer() == 0 &&
+ "Should be writing from buffer if some bytes in it");
+ // Otherwise, do copy the bytes.
+ OS.append(Ptr, Ptr+Size);
+ }
// Grow the vector if necessary.
if (OS.capacity() - OS.size() < 64)
diff --git a/lib/System/Makefile b/lib/System/Makefile
index d4fd60e..bb013b9 100644
--- a/lib/System/Makefile
+++ b/lib/System/Makefile
@@ -10,7 +10,7 @@
LEVEL = ../..
LIBRARYNAME = LLVMSystem
BUILD_ARCHIVE = 1
-
+REQUIRES_RTTI = 1
include $(LEVEL)/Makefile.config
ifeq ($(HOST_OS),MingW)
diff --git a/lib/System/Unix/Program.inc b/lib/System/Unix/Program.inc
index 43c3606..c10498a 100644
--- a/lib/System/Unix/Program.inc
+++ b/lib/System/Unix/Program.inc
@@ -126,7 +126,7 @@ static void TimeOutHandler(int Sig) {
static void SetMemoryLimits (unsigned size)
{
-#if HAVE_SYS_RESOURCE_H
+#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
struct rlimit r;
__typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
@@ -323,4 +323,9 @@ bool Program::ChangeStdoutToBinary(){
return false;
}
+bool Program::ChangeStderrToBinary(){
+ // Do nothing, as Unix doesn't differentiate between text and binary.
+ return false;
+}
+
}
diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc
index 676e1e5..c8ec68a 100644
--- a/lib/System/Unix/Signals.inc
+++ b/lib/System/Unix/Signals.inc
@@ -52,7 +52,16 @@ static const int *const IntSigsEnd =
// KillSigs - Signals that are synchronous with the program that will cause it
// to die.
static const int KillSigs[] = {
- SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ
+ SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV
+#ifdef SIGSYS
+ , SIGSYS
+#endif
+#ifdef SIGXCPU
+ , SIGXCPU
+#endif
+#ifdef SIGXFSZ
+ , SIGXFSZ
+#endif
#ifdef SIGEMT
, SIGEMT
#endif
diff --git a/lib/System/Win32/Program.inc b/lib/System/Win32/Program.inc
index a69826f..a3b40d0 100644
--- a/lib/System/Win32/Program.inc
+++ b/lib/System/Win32/Program.inc
@@ -379,4 +379,9 @@ bool Program::ChangeStdoutToBinary(){
return result == -1;
}
+bool Program::ChangeStderrToBinary(){
+ int result = _setmode( _fileno(stderr), _O_BINARY );
+ return result == -1;
+}
+
}
diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h
index 21445ad..b08f942 100644
--- a/lib/Target/ARM/ARM.h
+++ b/lib/Target/ARM/ARM.h
@@ -23,9 +23,7 @@ namespace llvm {
class ARMBaseTargetMachine;
class FunctionPass;
-class MachineCodeEmitter;
class JITCodeEmitter;
-class ObjectCodeEmitter;
class formatted_raw_ostream;
// Enums corresponding to ARM condition codes
@@ -95,12 +93,8 @@ inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM,
CodeGenOpt::Level OptLevel);
-FunctionPass *createARMCodeEmitterPass(ARMBaseTargetMachine &TM,
- MachineCodeEmitter &MCE);
FunctionPass *createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
JITCodeEmitter &JCE);
-FunctionPass *createARMObjectCodeEmitterPass(ARMBaseTargetMachine &TM,
- ObjectCodeEmitter &OCE);
FunctionPass *createARMLoadStoreOptimizationPass(bool PreAlloc = false);
FunctionPass *createARMExpandPseudoPass();
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index fd46a4a..6fe7c2c 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -450,10 +450,10 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
switch (Opc) {
default:
llvm_unreachable("Unknown or unset size field for instr!");
- case TargetInstrInfo::IMPLICIT_DEF:
- case TargetInstrInfo::KILL:
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
+ case TargetOpcode::DBG_LABEL:
+ case TargetOpcode::EH_LABEL:
return 0;
}
break;
@@ -470,9 +470,9 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
case ARM::Int_eh_sjlj_setjmp:
return 24;
case ARM::tInt_eh_sjlj_setjmp:
- return 22;
+ return 14;
case ARM::t2Int_eh_sjlj_setjmp:
- return 22;
+ return 14;
case ARM::BR_JTr:
case ARM::BR_JTm:
case ARM::BR_JTadd:
@@ -490,6 +490,7 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2));
unsigned JTI = JTOP.getIndex();
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+ assert(MJTI != 0);
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
assert(JTI < JT.size());
// Thumb instructions are 2 byte aligned, but JT entries are 4 byte
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index ba9e044..91e3550 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -478,7 +478,7 @@ ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
///
bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
- return (NoFramePointerElim ||
+ return ((NoFramePointerElim && MFI->hasCalls())||
needsStackRealignment(MF) ||
MFI->hasVarSizedObjects() ||
MFI->isFrameAddressTaken());
@@ -583,14 +583,6 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
SmallVector<unsigned, 4> UnspilledCS2GPRs;
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
-
- // Calculate and set max stack object alignment early, so we can decide
- // whether we will need stack realignment (and thus FP).
- if (RealignStack) {
- MachineFrameInfo *MFI = MF.getFrameInfo();
- MFI->calculateMaxStackAlignment();
- }
-
// Spill R4 if Thumb2 function requires stack realignment - it will be used as
// scratch register.
// FIXME: It will be better just to find spare register here.
@@ -803,10 +795,10 @@ ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
}
int
-ARMBaseRegisterInfo::getFrameIndexReference(MachineFunction &MF, int FI,
+ARMBaseRegisterInfo::getFrameIndexReference(const MachineFunction &MF, int FI,
unsigned &FrameReg) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
- ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+ const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
int Offset = MFI->getObjectOffset(FI) + MFI->getStackSize();
bool isFixed = MFI->isFixedObjectIndex(FI);
@@ -845,7 +837,8 @@ ARMBaseRegisterInfo::getFrameIndexReference(MachineFunction &MF, int FI,
int
-ARMBaseRegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
+ARMBaseRegisterInfo::getFrameIndexOffset(const MachineFunction &MF,
+ int FI) const {
unsigned FrameReg;
return getFrameIndexReference(MF, FI, FrameReg);
}
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h
index f5ca25c..33ba21d 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -107,9 +107,9 @@ public:
// Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(const MachineFunction &MF) const;
- int getFrameIndexReference(MachineFunction &MF, int FI,
+ int getFrameIndexReference(const MachineFunction &MF, int FI,
unsigned &FrameReg) const;
- int getFrameIndexOffset(MachineFunction &MF, int FI) const;
+ int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
// Exception handling queries.
unsigned getEHExceptionRegister() const;
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 17e7d44..bd703f4 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -24,9 +24,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
-#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -46,42 +44,34 @@ STATISTIC(NumEmitted, "Number of machine instructions emitted");
namespace {
- class ARMCodeEmitter {
- public:
- /// getBinaryCodeForInstr - This function, generated by the
- /// CodeEmitterGenerator using TableGen, produces the binary encoding for
- /// machine instructions.
- unsigned getBinaryCodeForInstr(const MachineInstr &MI);
- };
-
- template<class CodeEmitter>
- class Emitter : public MachineFunctionPass, public ARMCodeEmitter {
+ class ARMCodeEmitter : public MachineFunctionPass {
ARMJITInfo *JTI;
const ARMInstrInfo *II;
const TargetData *TD;
const ARMSubtarget *Subtarget;
TargetMachine &TM;
- CodeEmitter &MCE;
+ JITCodeEmitter &MCE;
const std::vector<MachineConstantPoolEntry> *MCPEs;
const std::vector<MachineJumpTableEntry> *MJTEs;
bool IsPIC;
-
+
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineModuleInfo>();
MachineFunctionPass::getAnalysisUsage(AU);
}
-
- public:
+
static char ID;
- explicit Emitter(TargetMachine &tm, CodeEmitter &mce)
- : MachineFunctionPass(&ID), JTI(0), II(0), TD(0), TM(tm),
- MCE(mce), MCPEs(0), MJTEs(0),
- IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
- Emitter(TargetMachine &tm, CodeEmitter &mce,
- const ARMInstrInfo &ii, const TargetData &td)
- : MachineFunctionPass(&ID), JTI(0), II(&ii), TD(&td), TM(tm),
- MCE(mce), MCPEs(0), MJTEs(0),
- IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
+ public:
+ ARMCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
+ : MachineFunctionPass(&ID), JTI(0), II((ARMInstrInfo*)tm.getInstrInfo()),
+ TD(tm.getTargetData()), TM(tm),
+ MCE(mce), MCPEs(0), MJTEs(0),
+ IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
+
+ /// getBinaryCodeForInstr - This function, generated by the
+ /// CodeEmitterGenerator using TableGen, produces the binary encoding for
+ /// machine instructions.
+ unsigned getBinaryCodeForInstr(const MachineInstr &MI);
bool runOnMachineFunction(MachineFunction &MF);
@@ -94,21 +84,13 @@ namespace {
private:
void emitWordLE(unsigned Binary);
-
void emitDWordLE(uint64_t Binary);
-
void emitConstPoolInstruction(const MachineInstr &MI);
-
void emitMOVi2piecesInstruction(const MachineInstr &MI);
-
void emitLEApcrelJTInstruction(const MachineInstr &MI);
-
void emitPseudoMoveInstruction(const MachineInstr &MI);
-
void addPCLabel(unsigned LabelID);
-
void emitPseudoInstruction(const MachineInstr &MI);
-
unsigned getMachineSoRegOpValue(const MachineInstr &MI,
const TargetInstrDesc &TID,
const MachineOperand &MO,
@@ -176,28 +158,18 @@ namespace {
void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
intptr_t JTBase = 0);
};
- template <class CodeEmitter>
- char Emitter<CodeEmitter>::ID = 0;
}
-/// createARMCodeEmitterPass - Return a pass that emits the collected ARM code
-/// to the specified MCE object.
+char ARMCodeEmitter::ID = 0;
-FunctionPass *llvm::createARMCodeEmitterPass(ARMBaseTargetMachine &TM,
- MachineCodeEmitter &MCE) {
- return new Emitter<MachineCodeEmitter>(TM, MCE);
-}
+/// createARMJITCodeEmitterPass - Return a pass that emits the collected ARM
+/// code to the specified MCE object.
FunctionPass *llvm::createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
JITCodeEmitter &JCE) {
- return new Emitter<JITCodeEmitter>(TM, JCE);
-}
-FunctionPass *llvm::createARMObjectCodeEmitterPass(ARMBaseTargetMachine &TM,
- ObjectCodeEmitter &OCE) {
- return new Emitter<ObjectCodeEmitter>(TM, OCE);
+ return new ARMCodeEmitter(TM, JCE);
}
-template<class CodeEmitter>
-bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
+bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
MF.getTarget().getRelocationModel() != Reloc::Static) &&
"JIT relocation model must be set to static or default!");
@@ -206,7 +178,8 @@ bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
TD = ((ARMTargetMachine&)MF.getTarget()).getTargetData();
Subtarget = &TM.getSubtarget<ARMSubtarget>();
MCPEs = &MF.getConstantPool()->getConstants();
- MJTEs = &MF.getJumpTableInfo()->getJumpTables();
+ MJTEs = 0;
+ if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
IsPIC = TM.getRelocationModel() == Reloc::PIC_;
JTI->Initialize(MF, IsPIC);
MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>());
@@ -229,8 +202,7 @@ bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
///
-template<class CodeEmitter>
-unsigned Emitter<CodeEmitter>::getShiftOp(unsigned Imm) const {
+unsigned ARMCodeEmitter::getShiftOp(unsigned Imm) const {
switch (ARM_AM::getAM2ShiftOpc(Imm)) {
default: llvm_unreachable("Unknown shift opc!");
case ARM_AM::asr: return 2;
@@ -244,9 +216,8 @@ unsigned Emitter<CodeEmitter>::getShiftOp(unsigned Imm) const {
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
-template<class CodeEmitter>
-unsigned Emitter<CodeEmitter>::getMachineOpValue(const MachineInstr &MI,
- const MachineOperand &MO) {
+unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
+ const MachineOperand &MO) {
if (MO.isReg())
return ARMRegisterInfo::getRegisterNumbering(MO.getReg());
else if (MO.isImm())
@@ -276,10 +247,9 @@ unsigned Emitter<CodeEmitter>::getMachineOpValue(const MachineInstr &MI,
/// emitGlobalAddress - Emit the specified address to the code stream.
///
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
- bool MayNeedFarStub, bool Indirect,
- intptr_t ACPV) {
+void ARMCodeEmitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
+ bool MayNeedFarStub, bool Indirect,
+ intptr_t ACPV) {
MachineRelocation MR = Indirect
? MachineRelocation::getIndirectSymbol(MCE.getCurrentPCOffset(), Reloc,
GV, ACPV, MayNeedFarStub)
@@ -291,9 +261,7 @@ void Emitter<CodeEmitter>::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
/// emitExternalSymbolAddress - Arrange for the address of an external symbol to
/// be emitted to the current location in the function, and allow it to be PC
/// relative.
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitExternalSymbolAddress(const char *ES,
- unsigned Reloc) {
+void ARMCodeEmitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
Reloc, ES));
}
@@ -301,9 +269,7 @@ void Emitter<CodeEmitter>::emitExternalSymbolAddress(const char *ES,
/// emitConstPoolAddress - Arrange for the address of an constant pool
/// to be emitted to the current location in the function, and allow it to be PC
/// relative.
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitConstPoolAddress(unsigned CPI,
- unsigned Reloc) {
+void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) {
// Tell JIT emitter we'll resolve the address.
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
Reloc, CPI, 0, true));
@@ -312,37 +278,31 @@ void Emitter<CodeEmitter>::emitConstPoolAddress(unsigned CPI,
/// emitJumpTableAddress - Arrange for the address of a jump table to
/// be emitted to the current location in the function, and allow it to be PC
/// relative.
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitJumpTableAddress(unsigned JTIndex,
- unsigned Reloc) {
+void ARMCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) {
MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
Reloc, JTIndex, 0, true));
}
/// emitMachineBasicBlock - Emit the specified address basic block.
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMachineBasicBlock(MachineBasicBlock *BB,
- unsigned Reloc, intptr_t JTBase) {
+void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
+ unsigned Reloc, intptr_t JTBase) {
MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
Reloc, BB, JTBase));
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitWordLE(unsigned Binary) {
+void ARMCodeEmitter::emitWordLE(unsigned Binary) {
DEBUG(errs() << " 0x";
errs().write_hex(Binary) << "\n");
MCE.emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitDWordLE(uint64_t Binary) {
+void ARMCodeEmitter::emitDWordLE(uint64_t Binary) {
DEBUG(errs() << " 0x";
errs().write_hex(Binary) << "\n");
MCE.emitDWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);
MCE.processDebugLoc(MI.getDebugLoc(), true);
@@ -411,8 +371,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI) {
MCE.processDebugLoc(MI.getDebugLoc(), false);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitConstPoolInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
unsigned CPI = MI.getOperand(0).getImm(); // CP instruction index.
unsigned CPIndex = MI.getOperand(1).getIndex(); // Actual cp entry index.
const MachineConstantPoolEntry &MCPE = (*MCPEs)[CPIndex];
@@ -474,8 +433,7 @@ void Emitter<CodeEmitter>::emitConstPoolInstruction(const MachineInstr &MI) {
}
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMOVi2piecesInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
const MachineOperand &MO0 = MI.getOperand(0);
const MachineOperand &MO1 = MI.getOperand(1);
assert(MO1.isImm() && ARM_AM::getSOImmVal(MO1.isImm()) != -1 &&
@@ -517,8 +475,7 @@ void Emitter<CodeEmitter>::emitMOVi2piecesInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitLEApcrelJTInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitLEApcrelJTInstruction(const MachineInstr &MI) {
// It's basically add r, pc, (LJTI - $+8)
const TargetInstrDesc &TID = MI.getDesc();
@@ -545,8 +502,7 @@ void Emitter<CodeEmitter>::emitLEApcrelJTInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitPseudoMoveInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitPseudoMoveInstruction(const MachineInstr &MI) {
unsigned Opcode = MI.getDesc().Opcode;
// Part of binary is determined by TableGn.
@@ -585,21 +541,19 @@ void Emitter<CodeEmitter>::emitPseudoMoveInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::addPCLabel(unsigned LabelID) {
+void ARMCodeEmitter::addPCLabel(unsigned LabelID) {
DEBUG(errs() << " ** LPC" << LabelID << " @ "
<< (void*)MCE.getCurrentPCValue() << '\n');
JTI->addPCLabelAddr(LabelID, MCE.getCurrentPCValue());
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitPseudoInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
unsigned Opcode = MI.getDesc().Opcode;
switch (Opcode) {
default:
llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
// FIXME: Add support for MOVimm32.
- case TargetInstrInfo::INLINEASM: {
+ case TargetOpcode::INLINEASM: {
// We allow inline assembler nodes with empty bodies - they can
// implicitly define registers, which is ok for JIT.
if (MI.getOperand(0).getSymbolName()[0]) {
@@ -607,12 +561,12 @@ void Emitter<CodeEmitter>::emitPseudoInstruction(const MachineInstr &MI) {
}
break;
}
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
+ case TargetOpcode::DBG_LABEL:
+ case TargetOpcode::EH_LABEL:
MCE.emitLabel(MI.getOperand(0).getImm());
break;
- case TargetInstrInfo::IMPLICIT_DEF:
- case TargetInstrInfo::KILL:
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
// Do nothing.
break;
case ARM::CONSTPOOL_ENTRY:
@@ -661,8 +615,7 @@ void Emitter<CodeEmitter>::emitPseudoInstruction(const MachineInstr &MI) {
}
}
-template<class CodeEmitter>
-unsigned Emitter<CodeEmitter>::getMachineSoRegOpValue(
+unsigned ARMCodeEmitter::getMachineSoRegOpValue(
const MachineInstr &MI,
const TargetInstrDesc &TID,
const MachineOperand &MO,
@@ -721,8 +674,7 @@ unsigned Emitter<CodeEmitter>::getMachineSoRegOpValue(
return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
}
-template<class CodeEmitter>
-unsigned Emitter<CodeEmitter>::getMachineSoImmOpValue(unsigned SoImm) {
+unsigned ARMCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) {
int SoImmVal = ARM_AM::getSOImmVal(SoImm);
assert(SoImmVal != -1 && "Not a valid so_imm value!");
@@ -735,8 +687,7 @@ unsigned Emitter<CodeEmitter>::getMachineSoImmOpValue(unsigned SoImm) {
return Binary;
}
-template<class CodeEmitter>
-unsigned Emitter<CodeEmitter>::getAddrModeSBit(const MachineInstr &MI,
+unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI,
const TargetInstrDesc &TID) const {
for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){
const MachineOperand &MO = MI.getOperand(i-1);
@@ -746,8 +697,7 @@ unsigned Emitter<CodeEmitter>::getAddrModeSBit(const MachineInstr &MI,
return 0;
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitDataProcessingInstruction(
+void ARMCodeEmitter::emitDataProcessingInstruction(
const MachineInstr &MI,
unsigned ImplicitRd,
unsigned ImplicitRn) {
@@ -813,8 +763,7 @@ void Emitter<CodeEmitter>::emitDataProcessingInstruction(
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitLoadStoreInstruction(
+void ARMCodeEmitter::emitLoadStoreInstruction(
const MachineInstr &MI,
unsigned ImplicitRd,
unsigned ImplicitRn) {
@@ -889,8 +838,7 @@ void Emitter<CodeEmitter>::emitLoadStoreInstruction(
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMiscLoadStoreInstruction(const MachineInstr &MI,
+void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
unsigned ImplicitRn) {
const TargetInstrDesc &TID = MI.getDesc();
unsigned Form = TID.TSFlags & ARMII::FormMask;
@@ -977,8 +925,7 @@ static unsigned getAddrModeUPBits(unsigned Mode) {
return Binary;
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitLoadStoreMultipleInstruction(
+void ARMCodeEmitter::emitLoadStoreMultipleInstruction(
const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
@@ -1011,8 +958,7 @@ void Emitter<CodeEmitter>::emitLoadStoreMultipleInstruction(
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMulFrmInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitMulFrmInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
@@ -1049,8 +995,7 @@ void Emitter<CodeEmitter>::emitMulFrmInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitExtendInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitExtendInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
@@ -1087,8 +1032,7 @@ void Emitter<CodeEmitter>::emitExtendInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMiscArithInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitMiscArithInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
@@ -1126,8 +1070,7 @@ void Emitter<CodeEmitter>::emitMiscArithInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitBranchInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
if (TID.Opcode == ARM::TPsoft) {
@@ -1146,8 +1089,7 @@ void Emitter<CodeEmitter>::emitBranchInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitInlineJumpTable(unsigned JTIndex) {
+void ARMCodeEmitter::emitInlineJumpTable(unsigned JTIndex) {
// Remember the base address of the inline jump table.
uintptr_t JTBase = MCE.getCurrentPCValue();
JTI->addJumpTableBaseAddr(JTIndex, JTBase);
@@ -1167,8 +1109,7 @@ void Emitter<CodeEmitter>::emitInlineJumpTable(unsigned JTIndex) {
}
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMiscBranchInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Handle jump tables.
@@ -1249,8 +1190,7 @@ static unsigned encodeVFPRm(const MachineInstr &MI, unsigned OpIdx) {
return Binary;
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitVFPArithInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
@@ -1289,8 +1229,7 @@ void Emitter<CodeEmitter>::emitVFPArithInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitVFPConversionInstruction(
+void ARMCodeEmitter::emitVFPConversionInstruction(
const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
unsigned Form = TID.TSFlags & ARMII::FormMask;
@@ -1347,8 +1286,7 @@ void Emitter<CodeEmitter>::emitVFPConversionInstruction(
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
@@ -1382,8 +1320,7 @@ void Emitter<CodeEmitter>::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitVFPLoadStoreMultipleInstruction(
+void ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(
const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
@@ -1418,8 +1355,7 @@ void Emitter<CodeEmitter>::emitVFPLoadStoreMultipleInstruction(
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMiscInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitMiscInstruction(const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp
index acd30d2..8fa3c04 100644
--- a/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -302,9 +302,9 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {
// Thumb1 functions containing constant pools get 4-byte alignment.
// This is so we can keep exact track of where the alignment padding goes.
- // Set default. Thumb1 function is 2-byte aligned, ARM and Thumb2 are 4-byte
- // aligned.
- AFI->setAlign(isThumb1 ? 1U : 2U);
+ // ARM and Thumb2 functions need to be 4-byte aligned.
+ if (!isThumb1)
+ MF.EnsureAlignment(2); // 2 = log2(4)
// Perform the initial placement of the constant pool entries. To start with,
// we put them all at the end of the function.
@@ -312,7 +312,7 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {
if (!MCP.isEmpty()) {
DoInitialPlacement(MF, CPEMIs);
if (isThumb1)
- AFI->setAlign(2U);
+ MF.EnsureAlignment(2); // 2 = log2(4)
}
/// The next UID to take is the first unused one.
@@ -506,7 +506,7 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &MF,
case ARM::tBR_JTr:
// A Thumb1 table jump may involve padding; for the offsets to
// be right, functions containing these must be 4-byte aligned.
- AFI->setAlign(2U);
+ MF.EnsureAlignment(2U);
if ((Offset+MBBSize)%4 != 0 || HasInlineAsm)
// FIXME: Add a pseudo ALIGN instruction instead.
MBBSize += 2; // padding
@@ -732,7 +732,7 @@ MachineBasicBlock *ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) {
// This pass should be run after register allocation, so there should be no
// PHI nodes to update.
- assert((Succ->empty() || Succ->begin()->getOpcode() != TargetInstrInfo::PHI)
+ assert((Succ->empty() || !Succ->begin()->isPHI())
&& "PHI nodes should be eliminated by now!");
}
@@ -1624,6 +1624,8 @@ bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) {
// FIXME: After the tables are shrunk, can we get rid some of the
// constantpool tables?
MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
+ if (MJTI == 0) return false;
+
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
for (unsigned i = 0, e = T2JumpTables.size(); i != e; ++i) {
MachineInstr *MI = T2JumpTables[i];
@@ -1730,6 +1732,8 @@ bool ARMConstantIslands::ReorderThumb2JumpTables(MachineFunction &MF) {
bool MadeChange = false;
MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
+ if (MJTI == 0) return false;
+
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
for (unsigned i = 0, e = T2JumpTables.size(); i != e; ++i) {
MachineInstr *MI = T2JumpTables[i];
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index a260050..df4ae70 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -58,6 +58,8 @@ public:
return "ARM Instruction Selection";
}
+ virtual void InstructionSelect();
+
/// getI32Imm - Return a target constant of type i32 with the specified
/// value.
inline SDValue getI32Imm(unsigned Imm) {
@@ -65,7 +67,7 @@ public:
}
SDNode *Select(SDNode *N);
- virtual void InstructionSelect();
+
bool SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &A,
SDValue &B, SDValue &C);
bool SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base,
@@ -1007,12 +1009,12 @@ SDNode *ARMDAGToDAGISel::SelectDYN_ALLOC(SDNode *N) {
SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) {
DebugLoc dl = V0.getNode()->getDebugLoc();
SDValue Undef =
- SDValue(CurDAG->getMachineNode(TargetInstrInfo::IMPLICIT_DEF, dl, VT), 0);
+ SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0);
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::DSUBREG_0, MVT::i32);
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::DSUBREG_1, MVT::i32);
- SDNode *Pair = CurDAG->getMachineNode(TargetInstrInfo::INSERT_SUBREG, dl,
+ SDNode *Pair = CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
VT, Undef, V0, SubReg0);
- return CurDAG->getMachineNode(TargetInstrInfo::INSERT_SUBREG, dl,
+ return CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
VT, SDValue(Pair, 0), V1, SubReg1);
}
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 76c6a27..adf1644 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -863,7 +863,8 @@ ARMTargetLowering::LowerMemOpCallTo(SDValue Chain,
return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG, dl);
}
return DAG.getStore(Chain, dl, Arg, PtrOff,
- PseudoSourceValue::getStack(), LocMemOffset);
+ PseudoSourceValue::getStack(), LocMemOffset,
+ false, false, 0);
}
void ARMTargetLowering::PassF64ArgInRegs(DebugLoc dl, SelectionDAG &DAG,
@@ -897,11 +898,13 @@ void ARMTargetLowering::PassF64ArgInRegs(DebugLoc dl, SelectionDAG &DAG,
SDValue
ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // ARM target does not yet support tail call optimization.
+ isTailCall = false;
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -1029,7 +1032,8 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
Callee = DAG.getLoad(getPointerTy(), dl,
DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
Callee = DAG.getNode(ARMISD::PIC_ADD, dl,
getPointerTy(), Callee, PICLabel);
@@ -1050,7 +1054,8 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
Callee = DAG.getLoad(getPointerTy(), dl,
DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
Callee = DAG.getNode(ARMISD::PIC_ADD, dl,
getPointerTy(), Callee, PICLabel);
@@ -1236,7 +1241,8 @@ SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) {
}
CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr);
SDValue Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
if (RelocM == Reloc::Static)
return Result;
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
@@ -1259,7 +1265,8 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4);
Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument);
Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue Chain = Argument.getValue(1);
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
@@ -1306,21 +1313,24 @@ ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4);
Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
Chain = Offset.getValue(1);
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel);
Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
} else {
// local exec model
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, "tpoff");
Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4);
Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
Offset = DAG.getLoad(PtrVT, dl, Chain, Offset,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
}
// The address of the thread local variable is the add of the thread
@@ -1356,13 +1366,15 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue Chain = Result.getValue(1);
SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT);
Result = DAG.getNode(ISD::ADD, dl, PtrVT, Result, GOT);
if (!UseGOTOFF)
Result = DAG.getLoad(PtrVT, dl, Chain, Result,
- PseudoSourceValue::getGOT(), 0);
+ PseudoSourceValue::getGOT(), 0,
+ false, false, 0);
return Result;
} else {
// If we have T2 ops, we can materialize the address directly via movt/movw
@@ -1374,7 +1386,8 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 4);
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
}
}
}
@@ -1401,7 +1414,8 @@ SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue Chain = Result.getValue(1);
if (RelocM == Reloc::PIC_) {
@@ -1411,7 +1425,8 @@ SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
if (Subtarget->GVIsIndirectSymbol(GV, RelocM))
Result = DAG.getLoad(PtrVT, dl, Chain, Result,
- PseudoSourceValue::getGOT(), 0);
+ PseudoSourceValue::getGOT(), 0,
+ false, false, 0);
return Result;
}
@@ -1432,13 +1447,15 @@ SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op,
SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4);
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
}
SDValue
-ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
+ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
+ const ARMSubtarget *Subtarget) {
unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
DebugLoc dl = Op.getDebugLoc();
switch (IntNo) {
@@ -1464,7 +1481,8 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
SDValue Result =
DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr,
- PseudoSourceValue::getConstantPool(), 0);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 0);
SDValue Chain = Result.getValue(1);
if (RelocM == Reloc::PIC_) {
@@ -1474,7 +1492,11 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
return Result;
}
case Intrinsic::eh_sjlj_setjmp:
- return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, MVT::i32, Op.getOperand(1));
+ SDValue Val = Subtarget->isThumb() ?
+ DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::SP, MVT::i32) :
+ DAG.getConstant(0, MVT::i32);
+ return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, MVT::i32, Op.getOperand(1),
+ Val);
}
}
@@ -1508,7 +1530,8 @@ static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
- return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
SDValue
@@ -1585,7 +1608,8 @@ ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,
// Create load node to retrieve arguments from the stack.
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
ArgValue2 = DAG.getLoad(MVT::i32, dl, Root, FIN,
- PseudoSourceValue::getFixedStack(FI), 0);
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0);
} else {
Reg = MF.addLiveIn(NextVA.getLocReg(), RC);
ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
@@ -1700,7 +1724,8 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain,
// Create load nodes to retrieve arguments from the stack.
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
- PseudoSourceValue::getFixedStack(FI), 0));
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0));
}
}
@@ -1738,7 +1763,8 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain,
unsigned VReg = MF.addLiveIn(GPRArgRegs[NumGPRs], RC);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN,
- PseudoSourceValue::getFixedStack(VarArgsFrameIndex), 0);
+ PseudoSourceValue::getFixedStack(VarArgsFrameIndex), 0,
+ false, false, 0);
MemOps.push_back(Store);
FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(), FIN,
DAG.getConstant(4, getPointerTy()));
@@ -1932,13 +1958,14 @@ SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) {
}
if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
Addr = DAG.getLoad((EVT)MVT::i32, dl, Chain, Addr,
- PseudoSourceValue::getJumpTable(), 0);
+ PseudoSourceValue::getJumpTable(), 0,
+ false, false, 0);
Chain = Addr.getValue(1);
Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, Table);
return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId);
} else {
Addr = DAG.getLoad(PTy, dl, Chain, Addr,
- PseudoSourceValue::getJumpTable(), 0);
+ PseudoSourceValue::getJumpTable(), 0, false, false, 0);
Chain = Addr.getValue(1);
return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI, UId);
}
@@ -1986,7 +2013,8 @@ SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
? ARM::R7 : ARM::R11;
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
while (Depth--)
- FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0);
+ FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0,
+ false, false, 0);
return FrameAddr;
}
@@ -2031,7 +2059,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
Loads[i] = DAG.getLoad(VT, dl, Chain,
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
DAG.getConstant(SrcOff, MVT::i32)),
- SrcSV, SrcSVOff + SrcOff);
+ SrcSV, SrcSVOff + SrcOff, false, false, 0);
TFOps[i] = Loads[i].getValue(1);
SrcOff += VTSize;
}
@@ -2040,9 +2068,9 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
for (i = 0;
i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
- DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
- DAG.getConstant(DstOff, MVT::i32)),
- DstSV, DstSVOff + DstOff);
+ DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
+ DAG.getConstant(DstOff, MVT::i32)),
+ DstSV, DstSVOff + DstOff, false, false, 0);
DstOff += VTSize;
}
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
@@ -2068,7 +2096,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
Loads[i] = DAG.getLoad(VT, dl, Chain,
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
DAG.getConstant(SrcOff, MVT::i32)),
- SrcSV, SrcSVOff + SrcOff);
+ SrcSV, SrcSVOff + SrcOff, false, false, 0);
TFOps[i] = Loads[i].getValue(1);
++i;
SrcOff += VTSize;
@@ -2090,7 +2118,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
DAG.getConstant(DstOff, MVT::i32)),
- DstSV, DstSVOff + DstOff);
+ DstSV, DstSVOff + DstOff, false, false, 0);
++i;
DstOff += VTSize;
BytesLeft -= VTSize;
@@ -3023,7 +3051,8 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
case ISD::RETURNADDR: break;
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG);
- case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
+ case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG,
+ Subtarget);
case ISD::BIT_CONVERT: return ExpandBIT_CONVERT(Op.getNode(), DAG);
case ISD::SHL:
case ISD::SRL:
@@ -3852,8 +3881,11 @@ bool ARMTargetLowering::allowsUnalignedMemoryAccesses(EVT VT) const {
if (!Subtarget->hasV6Ops())
// Pre-v6 does not support unaligned mem access.
return false;
- else if (!Subtarget->hasV6Ops()) {
- // v6 may or may not support unaligned mem access.
+ else {
+ // v6+ may or may not support unaligned mem access depending on the system
+ // configuration.
+ // FIXME: This is pretty conservative. Should we provide cmdline option to
+ // control the behaviour?
if (!Subtarget->isTargetDarwin())
return false;
}
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index cd9c027..3c5df45 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -278,7 +278,8 @@ namespace llvm {
const CCValAssign &VA,
ISD::ArgFlagsTy Flags);
SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG);
- SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
+ const ARMSubtarget *Subtarget);
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG);
SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG);
@@ -319,7 +320,7 @@ namespace llvm {
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 28b2821..db60458 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -56,6 +56,9 @@ def NEONGetLnFrm : Format<25>;
def NEONSetLnFrm : Format<26>;
def NEONDupFrm : Format<27>;
+def MiscFrm : Format<29>;
+def ThumbMiscFrm : Format<30>;
+
// Misc flags.
// the instruction has a Rn register operand.
@@ -1246,75 +1249,99 @@ class AXSI5<dag oops, dag iops, InstrItinClass itin,
}
// Double precision, unary
-class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
- InstrItinClass itin, string opc, string asm, list<dag> pattern>
+class ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
+ bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
+ string asm, list<dag> pattern>
: VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
- let Inst{27-20} = opcod1;
- let Inst{19-16} = opcod2;
+ let Inst{27-23} = opcod1;
+ let Inst{21-20} = opcod2;
+ let Inst{19-16} = opcod3;
let Inst{11-8} = 0b1011;
- let Inst{7-4} = opcod3;
+ let Inst{7-6} = opcod4;
+ let Inst{4} = opcod5;
}
// Double precision, binary
-class ADbI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
- string opc, string asm, list<dag> pattern>
+class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
+ dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
: VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
- let Inst{27-20} = opcod;
+ let Inst{27-23} = opcod1;
+ let Inst{21-20} = opcod2;
let Inst{11-8} = 0b1011;
+ let Inst{6} = op6;
+ let Inst{4} = op4;
}
// Single precision, unary
-class ASuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
- InstrItinClass itin, string opc, string asm, list<dag> pattern>
+class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
+ bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
+ string asm, list<dag> pattern>
: VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
- // Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding.
- let Inst{27-20} = opcod1;
- let Inst{19-16} = opcod2;
+ let Inst{27-23} = opcod1;
+ let Inst{21-20} = opcod2;
+ let Inst{19-16} = opcod3;
let Inst{11-8} = 0b1010;
- let Inst{7-4} = opcod3;
+ let Inst{7-6} = opcod4;
+ let Inst{4} = opcod5;
}
// Single precision unary, if no NEON
// Same as ASuI except not available if NEON is enabled
-class ASuIn<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
- InstrItinClass itin, string opc, string asm, list<dag> pattern>
- : ASuI<opcod1, opcod2, opcod3, oops, iops, itin, opc, asm, pattern> {
+class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
+ bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
+ string asm, list<dag> pattern>
+ : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm,
+ pattern> {
list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
}
// Single precision, binary
-class ASbI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
- string opc, string asm, list<dag> pattern>
+class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
+ InstrItinClass itin, string opc, string asm, list<dag> pattern>
: VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
- // Bit 22 (D bit) can be changed during instruction encoding.
- let Inst{27-20} = opcod;
+ let Inst{27-23} = opcod1;
+ let Inst{21-20} = opcod2;
let Inst{11-8} = 0b1010;
+ let Inst{6} = op6;
+ let Inst{4} = op4;
}
// Single precision binary, if no NEON
// Same as ASbI except not available if NEON is enabled
-class ASbIn<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
- string opc, string asm, list<dag> pattern>
- : ASbI<opcod, oops, iops, itin, opc, asm, pattern> {
+class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
+ dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
+ : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
}
// VFP conversion instructions
-class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
- dag oops, dag iops, InstrItinClass itin,
- string opc, string asm, list<dag> pattern>
+class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
+ dag oops, dag iops, InstrItinClass itin, string opc, string asm,
+ list<dag> pattern>
: VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> {
- let Inst{27-20} = opcod1;
- let Inst{19-16} = opcod2;
- let Inst{11-8} = opcod3;
+ let Inst{27-23} = opcod1;
+ let Inst{21-20} = opcod2;
+ let Inst{19-16} = opcod3;
+ let Inst{11-8} = opcod4;
let Inst{6} = 1;
+ let Inst{4} = 0;
+}
+
+// VFP conversion between floating-point and fixed-point
+class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
+ dag oops, dag iops, InstrItinClass itin, string opc, string asm,
+ list<dag> pattern>
+ : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> {
+ // size (fixed-point number): sx == 0 ? 16 : 32
+ let Inst{7} = op5; // sx
}
// VFP conversion instructions, if no NEON
-class AVConv1In<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
+class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
dag oops, dag iops, InstrItinClass itin,
string opc, string asm, list<dag> pattern>
- : AVConv1I<opcod1, opcod2, opcod3, oops, iops, itin, opc, asm, pattern> {
+ : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
+ pattern> {
list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
}
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index af508ee..1c6f78a 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -44,7 +44,8 @@ def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
-def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
+def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>,
+ SDTCisInt<2>]>;
def SDT_ARMMEMBARRIERV7 : SDTypeProfile<0, 0, []>;
def SDT_ARMSYNCBARRIERV7 : SDTypeProfile<0, 0, []>;
@@ -604,6 +605,102 @@ PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
[(ARMcallseq_start timm:$amt)]>;
}
+def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-0} = 0b00000000;
+}
+
+def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-0} = 0b00000001;
+}
+
+def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-0} = 0b00000010;
+}
+
+def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-0} = 0b00000011;
+}
+
+def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-0} = 0b00000100;
+}
+
+// The i32imm operand $val can be used by a debugger to store more information
+// about the breakpoint.
+def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM]> {
+ let Inst{27-20} = 0b00010010;
+ let Inst{7-4} = 0b0111;
+}
+
+// Change Processor State is a system instruction -- for disassembly only.
+// The singleton $opt operand contains the following information:
+// opt{4-0} = mode from Inst{4-0}
+// opt{5} = changemode from Inst{17}
+// opt{8-6} = AIF from Inst{8-6}
+// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
+def CPS : AXI<(outs),(ins i32imm:$opt), MiscFrm, NoItinerary, "cps${opt:cps}",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{27-20} = 0b00010000;
+ let Inst{16} = 0;
+ let Inst{5} = 0;
+}
+
+def SETENDBE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tbe",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{27-20} = 0b00010000;
+ let Inst{16} = 1;
+ let Inst{9} = 1;
+ let Inst{7-4} = 0b0000;
+}
+
+def SETENDLE : AXI<(outs),(ins), MiscFrm, NoItinerary, "setend\tle",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{27-20} = 0b00010000;
+ let Inst{16} = 1;
+ let Inst{9} = 0;
+ let Inst{7-4} = 0b0000;
+}
+
+def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV7]> {
+ let Inst{27-16} = 0b001100100000;
+ let Inst{7-4} = 0b1111;
+}
+
+// A5.4 Permanently UNDEFINED instructions.
+def TRAP : AI<(outs), (ins), MiscFrm, NoItinerary, "trap", "",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM]> {
+ let Inst{27-25} = 0b011;
+ let Inst{24-20} = 0b11111;
+ let Inst{7-5} = 0b111;
+ let Inst{4} = 0b1;
+}
+
// Address computation and loads and stores in PIC mode.
let isNotDuplicable = 1 in {
def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
@@ -826,6 +923,20 @@ let isBranch = 1, isTerminator = 1 in {
[/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
}
+// Branch and Exchange Jazelle -- for disassembly only
+def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0010;
+ //let Inst{19-8} = 0xfff;
+ let Inst{7-4} = 0b0010;
+}
+
+// Supervisor call (software interrupt) -- for disassembly only
+let isCall = 1 in {
+def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc",
+ [/* For disassembly only; pattern left blank */]>;
+}
+
//===----------------------------------------------------------------------===//
// Load / store Instructions.
//
@@ -908,6 +1019,20 @@ def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
"ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
}
+// LDRT and LDRBT are for disassembly only.
+
+def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
+ (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
+ "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+ let Inst{21} = 1; // overwrite
+}
+
+def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
+ (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
+ "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+ let Inst{21} = 1; // overwrite
+}
+
// Store
def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
"str", "\t$src, $addr",
@@ -971,6 +1096,24 @@ def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
[(set GPR:$base_wb, (post_truncsti8 GPR:$src,
GPR:$base, am2offset:$offset))]>;
+// STRT and STRBT are for disassembly only.
+
+def STRT : AI2stwpo<(outs GPR:$base_wb),
+ (ins GPR:$src, GPR:$base,am2offset:$offset),
+ StFrm, IIC_iStoreru,
+ "strt", "\t$src, [$base], $offset", "$base = $base_wb",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{21} = 1; // overwrite
+}
+
+def STRBT : AI2stbpo<(outs GPR:$base_wb),
+ (ins GPR:$src, GPR:$base,am2offset:$offset),
+ StFrm, IIC_iStoreru,
+ "strbt", "\t$src, [$base], $offset", "$base = $base_wb",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{21} = 1; // overwrite
+}
+
//===----------------------------------------------------------------------===//
// Load / store multiple Instructions.
//
@@ -1015,7 +1158,7 @@ def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
DPFrm, IIC_iMOVi,
"movw", "\t$dst, $src",
[(set GPR:$dst, imm0_65535:$src)]>,
- Requires<[IsARM, HasV6T2]> {
+ Requires<[IsARM, HasV6T2]>, UnaryDP {
let Inst{20} = 0;
let Inst{25} = 1;
}
@@ -1215,6 +1358,33 @@ def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
// (mul X, 2^n+1) -> (add (X << n), X)
// (mul X, 2^n-1) -> (rsb X, (X << n))
+// Saturating adds/subtracts -- for disassembly only
+
+// GPR:$dst = GPR:$a op GPR:$b
+class AQI<bits<8> op27_20, bits<4> op7_4, string opc>
+ : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
+ opc, "\t$dst, $a, $b",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-20} = op27_20;
+ let Inst{7-4} = op7_4;
+}
+
+def QADD : AQI<0b00010000, 0b0101, "qadd">;
+def QADD16 : AQI<0b01100010, 0b0001, "qadd16">;
+def QADD8 : AQI<0b01100010, 0b1001, "qadd8">;
+def QASX : AQI<0b01100010, 0b0011, "qasx">;
+def QDADD : AQI<0b00010100, 0b0101, "qdadd">;
+def QDSUB : AQI<0b00010110, 0b0101, "qdsub">;
+def QSAX : AQI<0b01100010, 0b0101, "qsax">;
+def QSUB : AQI<0b00010010, 0b0101, "qsub">;
+def QSUB16 : AQI<0b01100010, 0b0111, "qsub16">;
+def QSUB8 : AQI<0b01100010, 0b1111, "qsub8">;
+def UQADD16 : AQI<0b01100110, 0b0001, "uqadd16">;
+def UQADD8 : AQI<0b01100110, 0b1001, "uqadd8">;
+def UQASX : AQI<0b01100110, 0b0011, "uqasx">;
+def UQSAX : AQI<0b01100110, 0b0101, "uqsax">;
+def UQSUB16 : AQI<0b01100110, 0b0111, "uqsub16">;
+def UQSUB8 : AQI<0b01100110, 0b1111, "uqsub8">;
//===----------------------------------------------------------------------===//
// Bitwise Instructions.
@@ -1241,11 +1411,14 @@ def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
"mvn", "\t$dst, $src",
[(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
+ let Inst{25} = 0;
let Inst{11-4} = 0b00000000;
}
def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
IIC_iMOVsr, "mvn", "\t$dst, $src",
- [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP;
+ [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
+ let Inst{25} = 0;
+}
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
IIC_iMOVi, "mvn", "\t$dst, $imm",
@@ -1442,7 +1615,39 @@ multiclass AI_smla<string opc, PatFrag opnode> {
defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
-// TODO: Halfword multiple accumulate long: SMLAL<x><y>
+// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
+def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
+ IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV5TE]> {
+ let Inst{5} = 0;
+ let Inst{6} = 0;
+}
+
+def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
+ IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV5TE]> {
+ let Inst{5} = 0;
+ let Inst{6} = 1;
+}
+
+def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
+ IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV5TE]> {
+ let Inst{5} = 1;
+ let Inst{6} = 0;
+}
+
+def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
+ IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
+ [/* For disassembly only; pattern left blank */]>,
+ Requires<[IsARM, HasV5TE]> {
+ let Inst{5} = 1;
+ let Inst{6} = 1;
+}
+
// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
//===----------------------------------------------------------------------===//
@@ -1773,6 +1978,27 @@ def STREXD : AIstrex<0b01, (outs GPR:$success),
[]>;
}
+// SWP/SWPB are deprecated in V6/V7 and for disassembly only.
+let mayLoad = 1 in {
+def SWP : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
+ "swp", "\t$dst, $src, [$ptr]",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-23} = 0b00010;
+ let Inst{22} = 0; // B = 0
+ let Inst{21-20} = 0b00;
+ let Inst{7-4} = 0b1001;
+}
+
+def SWPB : AI<(outs GPR:$dst), (ins GPR:$src, GPR:$ptr), LdStExFrm, NoItinerary,
+ "swpb", "\t$dst, $src, [$ptr]",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-23} = 0b00010;
+ let Inst{22} = 1; // B = 1
+ let Inst{21-20} = 0b00;
+ let Inst{7-4} = 0b1001;
+}
+}
+
//===----------------------------------------------------------------------===//
// TLS Instructions
//
@@ -1797,21 +2023,22 @@ let isCall = 1,
// except for our own input by listing the relevant registers in Defs. By
// doing so, we also cause the prologue/epilogue code to actively preserve
// all of the callee-saved resgisters, which is exactly what we want.
-let Defs =
+// A constant value is passed in $val, and we use the location as a scratch.
+let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
D31 ] in {
- def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
+ def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val),
AddrModeNone, SizeSpecial, IndexModeNone,
Pseudo, NoItinerary,
"str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
- "add\tr12, pc, #8\n\t"
- "str\tr12, [$src, #+4]\n\t"
+ "add\t$val, pc, #8\n\t"
+ "str\t$val, [$src, #+4]\n\t"
"mov\tr0, #0\n\t"
"add\tpc, pc, #0\n\t"
"mov\tr0, #1 @ eh_setjmp end", "",
- [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
+ [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>;
}
//===----------------------------------------------------------------------===//
@@ -1954,3 +2181,116 @@ include "ARMInstrVFP.td"
//
include "ARMInstrNEON.td"
+
+//===----------------------------------------------------------------------===//
+// Coprocessor Instructions. For disassembly only.
+//
+
+def CDP : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "cdp", "\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{4} = 0;
+}
+
+def CDP2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ nohash_imm:$CRd, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "cdp2\tp$cop, $opc1, cr$CRd, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{4} = 0;
+}
+
+def MCR : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "mcr", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{20} = 0;
+ let Inst{4} = 1;
+}
+
+def MCR2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "mcr2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{20} = 0;
+ let Inst{4} = 1;
+}
+
+def MRC : ABI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "mrc", "\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{20} = 1;
+ let Inst{4} = 1;
+}
+
+def MRC2 : ABXI<0b1110, (outs), (ins nohash_imm:$cop, i32imm:$opc1,
+ GPR:$Rt, nohash_imm:$CRn, nohash_imm:$CRm, i32imm:$opc2),
+ NoItinerary, "mrc2\tp$cop, $opc1, $Rt, cr$CRn, cr$CRm, $opc2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{20} = 1;
+ let Inst{4} = 1;
+}
+
+def MCRR : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
+ GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
+ NoItinerary, "mcrr", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0100;
+}
+
+def MCRR2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
+ GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
+ NoItinerary, "mcrr2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{23-20} = 0b0100;
+}
+
+def MRRC : ABI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
+ GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
+ NoItinerary, "mrrc", "\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0101;
+}
+
+def MRRC2 : ABXI<0b1100, (outs), (ins nohash_imm:$cop, i32imm:$opc,
+ GPR:$Rt, GPR:$Rt2, nohash_imm:$CRm),
+ NoItinerary, "mrrc2\tp$cop, $opc, $Rt, $Rt2, cr$CRm",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{31-28} = 0b1111;
+ let Inst{23-20} = 0b0101;
+}
+
+//===----------------------------------------------------------------------===//
+// Move between special register and ARM core register -- for disassembly only
+//
+
+def MRS : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary, "mrs", "\t$dst, cpsr",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0000;
+ let Inst{7-4} = 0b0000;
+}
+
+def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0100;
+ let Inst{7-4} = 0b0000;
+}
+
+// FIXME: mask is ignored for the time being.
+def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "mrs", "\tcpsr, $src",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0010;
+ let Inst{7-4} = 0b0000;
+}
+
+// FIXME: mask is ignored for the time being.
+def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"mrs","\tspsr, $src",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{23-20} = 0b0110;
+ let Inst{7-4} = 0b0000;
+}
diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td
index cd063bf..e2be7ba 100644
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -2192,9 +2192,27 @@ def VBSLq : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$dst),
// VBIF : Vector Bitwise Insert if False
// like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst",
+def VBIFd : N3VX<1, 0, 0b11, 0b0001, 0, 1,
+ (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3),
+ IIC_VBINiD, "vbif", "$dst, $src2, $src3", "$src1 = $dst",
+ [/* For disassembly only; pattern left blank */]>;
+def VBIFq : N3VX<1, 0, 0b11, 0b0001, 1, 1,
+ (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3),
+ IIC_VBINiQ, "vbif", "$dst, $src2, $src3", "$src1 = $dst",
+ [/* For disassembly only; pattern left blank */]>;
+
// VBIT : Vector Bitwise Insert if True
// like VBSL but with: "vbit $dst, $src2, $src1", "$src3 = $dst",
-// These are not yet implemented. The TwoAddress pass will not go looking
+def VBITd : N3VX<1, 0, 0b10, 0b0001, 0, 1,
+ (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3),
+ IIC_VBINiD, "vbit", "$dst, $src2, $src3", "$src1 = $dst",
+ [/* For disassembly only; pattern left blank */]>;
+def VBITq : N3VX<1, 0, 0b10, 0b0001, 1, 1,
+ (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3),
+ IIC_VBINiQ, "vbit", "$dst, $src2, $src3", "$src1 = $dst",
+ [/* For disassembly only; pattern left blank */]>;
+
+// VBIT/VBIF are not yet implemented. The TwoAddress pass will not go looking
// for equivalent operations with different register constraints; it just
// inserts copies.
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index 746caff..64142ad 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -132,6 +132,14 @@ PseudoInst<(outs), (ins i32imm:$amt), NoItinerary,
[(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>;
}
+// The i32imm operand $val can be used by a debugger to store more information
+// about the breakpoint.
+def tBKPT : T1I<(outs), (ins i32imm:$val), NoItinerary, "bkpt\t$val",
+ [/* For disassembly only; pattern left blank */]>,
+ T1Encoding<0b101111> {
+ let Inst{9-8} = 0b10;
+}
+
// For both thumb1 and thumb2.
let isNotDuplicable = 1 in
def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr,
@@ -775,7 +783,7 @@ def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr,
"mov", "\t$dst, $rhs", []>,
T1Special<{1,0,?,?}>;
-def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi,
+def tMOVCCi : T1pIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMOVi,
"mov", "\t$dst, $rhs", []>,
T1General<{1,0,0,?,?}>;
@@ -813,23 +821,20 @@ let isCall = 1,
// except for our own input by listing the relevant registers in Defs. By
// doing so, we also cause the prologue/epilogue code to actively preserve
// all of the callee-saved resgisters, which is exactly what we want.
+// The current SP is passed in $val, and we reuse the reg as a scratch.
let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R12 ] in {
- def tInt_eh_sjlj_setjmp : ThumbXI<(outs), (ins GPR:$src),
+ def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val),
AddrModeNone, SizeSpecial, NoItinerary,
- "mov\tr12, r1\t@ begin eh.setjmp\n"
- "\tmov\tr1, sp\n"
- "\tstr\tr1, [$src, #8]\n"
- "\tadr\tr1, 0f\n"
- "\tadds\tr1, #1\n"
- "\tstr\tr1, [$src, #4]\n"
- "\tmov\tr1, r12\n"
+ "str\t$val, [$src, #8]\t@ begin eh.setjmp\n"
+ "\tmov\t$val, pc\n"
+ "\tadds\t$val, #9\n"
+ "\tstr\t$val, [$src, #4]\n"
"\tmovs\tr0, #0\n"
"\tb\t1f\n"
- ".align 2\n"
- "0:\tmovs\tr0, #1\t@ end eh.setjmp\n"
+ "\tmovs\tr0, #1\t@ end eh.setjmp\n"
"1:", "",
- [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
+ [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>;
}
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index c7591d2..55c7aa2 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -1232,7 +1232,16 @@ def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
let Inst{15} = 0;
}
-// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
+// A8.6.18 BFI - Bitfield insert (Encoding T1)
+// Added for disassembler with the pattern field purposely left blank.
+// FIXME: Utilize this instruction in codgen.
+def t2BFI : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
+ IIC_iALUi, "bfi", "\t$dst, $src, $lsb, $width", []> {
+ let Inst{31-27} = 0b11110;
+ let Inst{25} = 1;
+ let Inst{24-20} = 0b10110;
+ let Inst{15} = 0;
+}
defm t2ORN : T2I_bin_irs<0b0011, "orn", BinOpFrag<(or node:$LHS,
(not node:$RHS))>>;
@@ -1808,22 +1817,23 @@ let isCall = 1,
// except for our own input by listing the relevant registers in Defs. By
// doing so, we also cause the prologue/epilogue code to actively preserve
// all of the callee-saved resgisters, which is exactly what we want.
-let Defs =
+// The current SP is passed in $val, and we reuse the reg as a scratch.
+let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
D31 ] in {
- def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src),
+ def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val),
AddrModeNone, SizeSpecial, NoItinerary,
- "str.w\tsp, [$src, #+8] @ eh_setjmp begin\n"
- "\tadr\tr12, 0f\n"
- "\torr.w\tr12, r12, #1\n"
- "\tstr.w\tr12, [$src, #+4]\n"
+ "str\t$val, [$src, #8]\t@ begin eh.setjmp\n"
+ "\tmov\t$val, pc\n"
+ "\tadds\t$val, #9\n"
+ "\tstr\t$val, [$src, #4]\n"
"\tmovs\tr0, #0\n"
"\tb\t1f\n"
- "0:\tmovs\tr0, #1 @ eh_setjmp end\n"
+ "\tmovs\tr0, #1\t@ end eh.setjmp\n"
"1:", "",
- [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
+ [(set R0, (ARMeh_sjlj_setjmp GPR:$src, tGPR:$val))]>;
}
diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td
index 5bfe89d..e516593 100644
--- a/lib/Target/ARM/ARMInstrVFP.td
+++ b/lib/Target/ARM/ARMInstrVFP.td
@@ -114,52 +114,56 @@ def VSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
// FP Binary Operations.
//
-def VADDD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
+def VADDD : ADbI<0b11100, 0b11, 0, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
IIC_fpALU64, "vadd", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fadd DPR:$a, DPR:$b))]>;
-def VADDS : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
+def VADDS : ASbIn<0b11100, 0b11, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
IIC_fpALU32, "vadd", ".f32\t$dst, $a, $b",
[(set SPR:$dst, (fadd SPR:$a, SPR:$b))]>;
// These are encoded as unary instructions.
let Defs = [FPSCR] in {
-def VCMPED : ADuI<0b11101011, 0b0100, 0b1100, (outs), (ins DPR:$a, DPR:$b),
+def VCMPED : ADuI<0b11101, 0b11, 0b0100, 0b11, 0, (outs), (ins DPR:$a, DPR:$b),
IIC_fpCMP64, "vcmpe", ".f64\t$a, $b",
[(arm_cmpfp DPR:$a, DPR:$b)]>;
-def VCMPES : ASuI<0b11101011, 0b0100, 0b1100, (outs), (ins SPR:$a, SPR:$b),
+def VCMPD : ADuI<0b11101, 0b11, 0b0100, 0b01, 0, (outs), (ins DPR:$a, DPR:$b),
+ IIC_fpCMP64, "vcmp", ".f64\t$a, $b",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VCMPES : ASuI<0b11101, 0b11, 0b0100, 0b11, 0, (outs), (ins SPR:$a, SPR:$b),
IIC_fpCMP32, "vcmpe", ".f32\t$a, $b",
[(arm_cmpfp SPR:$a, SPR:$b)]>;
+
+def VCMPS : ASuI<0b11101, 0b11, 0b0100, 0b01, 0, (outs), (ins SPR:$a, SPR:$b),
+ IIC_fpCMP32, "vcmp", ".f32\t$a, $b",
+ [/* For disassembly only; pattern left blank */]>;
}
-def VDIVD : ADbI<0b11101000, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
+def VDIVD : ADbI<0b11101, 0b00, 0, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
IIC_fpDIV64, "vdiv", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fdiv DPR:$a, DPR:$b))]>;
-def VDIVS : ASbI<0b11101000, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
+def VDIVS : ASbI<0b11101, 0b00, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
IIC_fpDIV32, "vdiv", ".f32\t$dst, $a, $b",
[(set SPR:$dst, (fdiv SPR:$a, SPR:$b))]>;
-def VMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
+def VMULD : ADbI<0b11100, 0b10, 0, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
IIC_fpMUL64, "vmul", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fmul DPR:$a, DPR:$b))]>;
-def VMULS : ASbIn<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
+def VMULS : ASbIn<0b11100, 0b10, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
IIC_fpMUL32, "vmul", ".f32\t$dst, $a, $b",
[(set SPR:$dst, (fmul SPR:$a, SPR:$b))]>;
-def VNMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
+def VNMULD : ADbI<0b11100, 0b10, 1, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
IIC_fpMUL64, "vnmul", ".f64\t$dst, $a, $b",
- [(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]> {
- let Inst{6} = 1;
-}
+ [(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]>;
-def VNMULS : ASbI<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
+def VNMULS : ASbI<0b11100, 0b10, 1, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
IIC_fpMUL32, "vnmul", ".f32\t$dst, $a, $b",
- [(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]> {
- let Inst{6} = 1;
-}
+ [(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]>;
// Match reassociated forms only if not sign dependent rounding.
def : Pat<(fmul (fneg DPR:$a), DPR:$b),
@@ -168,41 +172,45 @@ def : Pat<(fmul (fneg SPR:$a), SPR:$b),
(VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
-def VSUBD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
+def VSUBD : ADbI<0b11100, 0b11, 1, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
IIC_fpALU64, "vsub", ".f64\t$dst, $a, $b",
- [(set DPR:$dst, (fsub DPR:$a, DPR:$b))]> {
- let Inst{6} = 1;
-}
+ [(set DPR:$dst, (fsub DPR:$a, DPR:$b))]>;
-def VSUBS : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
+def VSUBS : ASbIn<0b11100, 0b11, 1, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
IIC_fpALU32, "vsub", ".f32\t$dst, $a, $b",
- [(set SPR:$dst, (fsub SPR:$a, SPR:$b))]> {
- let Inst{6} = 1;
-}
+ [(set SPR:$dst, (fsub SPR:$a, SPR:$b))]>;
//===----------------------------------------------------------------------===//
// FP Unary Operations.
//
-def VABSD : ADuI<0b11101011, 0b0000, 0b1100, (outs DPR:$dst), (ins DPR:$a),
+def VABSD : ADuI<0b11101, 0b11, 0b0000, 0b11, 0, (outs DPR:$dst), (ins DPR:$a),
IIC_fpUNA64, "vabs", ".f64\t$dst, $a",
[(set DPR:$dst, (fabs DPR:$a))]>;
-def VABSS : ASuIn<0b11101011, 0b0000, 0b1100, (outs SPR:$dst), (ins SPR:$a),
+def VABSS : ASuIn<0b11101, 0b11, 0b0000, 0b11, 0,(outs SPR:$dst), (ins SPR:$a),
IIC_fpUNA32, "vabs", ".f32\t$dst, $a",
[(set SPR:$dst, (fabs SPR:$a))]>;
let Defs = [FPSCR] in {
-def VCMPEZD : ADuI<0b11101011, 0b0101, 0b1100, (outs), (ins DPR:$a),
+def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0, (outs), (ins DPR:$a),
IIC_fpCMP64, "vcmpe", ".f64\t$a, #0",
[(arm_cmpfp0 DPR:$a)]>;
-def VCMPEZS : ASuI<0b11101011, 0b0101, 0b1100, (outs), (ins SPR:$a),
+def VCMPZD : ADuI<0b11101, 0b11, 0b0101, 0b01, 0, (outs), (ins DPR:$a),
+ IIC_fpCMP64, "vcmp", ".f64\t$a, #0",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VCMPEZS : ASuI<0b11101, 0b11, 0b0101, 0b11, 0, (outs), (ins SPR:$a),
IIC_fpCMP32, "vcmpe", ".f32\t$a, #0",
[(arm_cmpfp0 SPR:$a)]>;
+
+def VCMPZS : ASuI<0b11101, 0b11, 0b0101, 0b01, 0, (outs), (ins SPR:$a),
+ IIC_fpCMP32, "vcmp", ".f32\t$a, #0",
+ [/* For disassembly only; pattern left blank */]>;
}
-def VCVTDS : ASuI<0b11101011, 0b0111, 0b1100, (outs DPR:$dst), (ins SPR:$a),
+def VCVTDS : ASuI<0b11101, 0b11, 0b0111, 0b11, 0, (outs DPR:$dst), (ins SPR:$a),
IIC_fpCVTDS, "vcvt", ".f64.f32\t$dst, $a",
[(set DPR:$dst, (fextend SPR:$a))]>;
@@ -213,30 +221,49 @@ def VCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm,
let Inst{27-23} = 0b11101;
let Inst{21-16} = 0b110111;
let Inst{11-8} = 0b1011;
- let Inst{7-4} = 0b1100;
+ let Inst{7-6} = 0b11;
+ let Inst{4} = 0;
}
+// Between half-precision and single-precision. For disassembly only.
+
+def VCVTBSH : ASuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
+ /* FIXME */ IIC_fpCVTDS, "vcvtb", ".f32.f16\t$dst, $a",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VCVTBHS : ASuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
+ /* FIXME */ IIC_fpCVTDS, "vcvtb", ".f16.f32\t$dst, $a",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VCVTTSH : ASuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
+ /* FIXME */ IIC_fpCVTDS, "vcvtt", ".f32.f16\t$dst, $a",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VCVTTHS : ASuI<0b11101, 0b11, 0b0011, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
+ /* FIXME */ IIC_fpCVTDS, "vcvtt", ".f16.f32\t$dst, $a",
+ [/* For disassembly only; pattern left blank */]>;
+
let neverHasSideEffects = 1 in {
-def VMOVD: ADuI<0b11101011, 0b0000, 0b0100, (outs DPR:$dst), (ins DPR:$a),
+def VMOVD: ADuI<0b11101, 0b11, 0b0000, 0b01, 0, (outs DPR:$dst), (ins DPR:$a),
IIC_fpUNA64, "vmov", ".f64\t$dst, $a", []>;
-def VMOVS: ASuI<0b11101011, 0b0000, 0b0100, (outs SPR:$dst), (ins SPR:$a),
+def VMOVS: ASuI<0b11101, 0b11, 0b0000, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
IIC_fpUNA32, "vmov", ".f32\t$dst, $a", []>;
} // neverHasSideEffects
-def VNEGD : ADuI<0b11101011, 0b0001, 0b0100, (outs DPR:$dst), (ins DPR:$a),
+def VNEGD : ADuI<0b11101, 0b11, 0b0001, 0b01, 0, (outs DPR:$dst), (ins DPR:$a),
IIC_fpUNA64, "vneg", ".f64\t$dst, $a",
[(set DPR:$dst, (fneg DPR:$a))]>;
-def VNEGS : ASuIn<0b11101011, 0b0001, 0b0100, (outs SPR:$dst), (ins SPR:$a),
+def VNEGS : ASuIn<0b11101, 0b11, 0b0001, 0b01, 0,(outs SPR:$dst), (ins SPR:$a),
IIC_fpUNA32, "vneg", ".f32\t$dst, $a",
[(set SPR:$dst, (fneg SPR:$a))]>;
-def VSQRTD : ADuI<0b11101011, 0b0001, 0b1100, (outs DPR:$dst), (ins DPR:$a),
+def VSQRTD : ADuI<0b11101, 0b11, 0b0001, 0b11, 0, (outs DPR:$dst), (ins DPR:$a),
IIC_fpSQRT64, "vsqrt", ".f64\t$dst, $a",
[(set DPR:$dst, (fsqrt DPR:$a))]>;
-def VSQRTS : ASuI<0b11101011, 0b0001, 0b1100, (outs SPR:$dst), (ins SPR:$a),
+def VSQRTS : ASuI<0b11101, 0b11, 0b0001, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
IIC_fpSQRT32, "vsqrt", ".f32\t$dst, $a",
[(set SPR:$dst, (fsqrt SPR:$a))]>;
@@ -255,7 +282,16 @@ def VMOVSR : AVConv4I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src),
def VMOVRRD : AVConv3I<0b11000101, 0b1011,
(outs GPR:$wb, GPR:$dst2), (ins DPR:$src),
IIC_VMOVDI, "vmov", "\t$wb, $dst2, $src",
- [/* FIXME: Can't write pattern for multiple result instr*/]>;
+ [/* FIXME: Can't write pattern for multiple result instr*/]> {
+ let Inst{7-6} = 0b00;
+}
+
+def VMOVRRS : AVConv3I<0b11000101, 0b1010,
+ (outs GPR:$wb, GPR:$dst2), (ins SPR:$src1, SPR:$src2),
+ IIC_VMOVDI, "vmov", "\t$wb, $dst2, $src1, $src2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{7-6} = 0b00;
+}
// FMDHR: GPR -> SPR
// FMDLR: GPR -> SPR
@@ -263,7 +299,16 @@ def VMOVRRD : AVConv3I<0b11000101, 0b1011,
def VMOVDRR : AVConv5I<0b11000100, 0b1011,
(outs DPR:$dst), (ins GPR:$src1, GPR:$src2),
IIC_VMOVID, "vmov", "\t$dst, $src1, $src2",
- [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>;
+ [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]> {
+ let Inst{7-6} = 0b00;
+}
+
+def VMOVSRR : AVConv5I<0b11000100, 0b1010,
+ (outs SPR:$dst1, SPR:$dst2), (ins GPR:$src1, GPR:$src2),
+ IIC_VMOVID, "vmov", "\t$dst1, $dst2, $src1, $src2",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{7-6} = 0b00;
+}
// FMRDH: SPR -> GPR
// FMRDL: SPR -> GPR
@@ -277,137 +322,271 @@ def VMOVDRR : AVConv5I<0b11000100, 0b1011,
// Int to FP:
-def VSITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
+def VSITOD : AVConv1I<0b11101, 0b11, 0b1000, 0b1011,
+ (outs DPR:$dst), (ins SPR:$a),
IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a",
[(set DPR:$dst, (arm_sitof SPR:$a))]> {
- let Inst{7} = 1;
+ let Inst{7} = 1; // s32
}
-def VSITOS : AVConv1In<0b11101011, 0b1000, 0b1010, (outs SPR:$dst),(ins SPR:$a),
+def VSITOS : AVConv1In<0b11101, 0b11, 0b1000, 0b1010,
+ (outs SPR:$dst),(ins SPR:$a),
IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a",
[(set SPR:$dst, (arm_sitof SPR:$a))]> {
- let Inst{7} = 1;
+ let Inst{7} = 1; // s32
}
-def VUITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
+def VUITOD : AVConv1I<0b11101, 0b11, 0b1000, 0b1011,
+ (outs DPR:$dst), (ins SPR:$a),
IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a",
- [(set DPR:$dst, (arm_uitof SPR:$a))]>;
+ [(set DPR:$dst, (arm_uitof SPR:$a))]> {
+ let Inst{7} = 0; // u32
+}
-def VUITOS : AVConv1In<0b11101011, 0b1000, 0b1010, (outs SPR:$dst),(ins SPR:$a),
+def VUITOS : AVConv1In<0b11101, 0b11, 0b1000, 0b1010,
+ (outs SPR:$dst), (ins SPR:$a),
IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a",
- [(set SPR:$dst, (arm_uitof SPR:$a))]>;
+ [(set SPR:$dst, (arm_uitof SPR:$a))]> {
+ let Inst{7} = 0; // u32
+}
// FP to Int:
// Always set Z bit in the instruction, i.e. "round towards zero" variants.
-def VTOSIZD : AVConv1I<0b11101011, 0b1101, 0b1011,
+def VTOSIZD : AVConv1I<0b11101, 0b11, 0b1101, 0b1011,
(outs SPR:$dst), (ins DPR:$a),
IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a",
[(set SPR:$dst, (arm_ftosi DPR:$a))]> {
let Inst{7} = 1; // Z bit
}
-def VTOSIZS : AVConv1In<0b11101011, 0b1101, 0b1010,
+def VTOSIZS : AVConv1In<0b11101, 0b11, 0b1101, 0b1010,
(outs SPR:$dst), (ins SPR:$a),
IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a",
[(set SPR:$dst, (arm_ftosi SPR:$a))]> {
let Inst{7} = 1; // Z bit
}
-def VTOUIZD : AVConv1I<0b11101011, 0b1100, 0b1011,
+def VTOUIZD : AVConv1I<0b11101, 0b11, 0b1100, 0b1011,
(outs SPR:$dst), (ins DPR:$a),
IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a",
[(set SPR:$dst, (arm_ftoui DPR:$a))]> {
let Inst{7} = 1; // Z bit
}
-def VTOUIZS : AVConv1In<0b11101011, 0b1100, 0b1010,
+def VTOUIZS : AVConv1In<0b11101, 0b11, 0b1100, 0b1010,
(outs SPR:$dst), (ins SPR:$a),
IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a",
[(set SPR:$dst, (arm_ftoui SPR:$a))]> {
let Inst{7} = 1; // Z bit
}
+// And the Z bit '0' variants, i.e. use the rounding mode specified by FPSCR.
+// For disassembly only.
+
+def VTOSIRD : AVConv1I<0b11101, 0b11, 0b1101, 0b1011,
+ (outs SPR:$dst), (ins DPR:$a),
+ IIC_fpCVTDI, "vcvtr", ".s32.f64\t$dst, $a",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{7} = 0; // Z bit
+}
+
+def VTOSIRS : AVConv1In<0b11101, 0b11, 0b1101, 0b1010,
+ (outs SPR:$dst), (ins SPR:$a),
+ IIC_fpCVTSI, "vcvtr", ".s32.f32\t$dst, $a",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{7} = 0; // Z bit
+}
+
+def VTOUIRD : AVConv1I<0b11101, 0b11, 0b1100, 0b1011,
+ (outs SPR:$dst), (ins DPR:$a),
+ IIC_fpCVTDI, "vcvtr", ".u32.f64\t$dst, $a",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{7} = 0; // Z bit
+}
+
+def VTOUIRS : AVConv1In<0b11101, 0b11, 0b1100, 0b1010,
+ (outs SPR:$dst), (ins SPR:$a),
+ IIC_fpCVTSI, "vcvtr", ".u32.f32\t$dst, $a",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{7} = 0; // Z bit
+}
+
+// Convert between floating-point and fixed-point
+// Data type for fixed-point naming convention:
+// S16 (U=0, sx=0) -> SH
+// U16 (U=1, sx=0) -> UH
+// S32 (U=0, sx=1) -> SL
+// U32 (U=1, sx=1) -> UL
+
+let Constraints = "$a = $dst" in {
+
+// FP to Fixed-Point:
+
+def VTOSHS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 0,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOUHS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 0,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOSLS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 1,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOULS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 1,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOSHD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 0,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOUHD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 0,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOSLD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 1,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VTOULD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 1,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+// Fixed-Point to FP:
+
+def VSHTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 0,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VUHTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 0,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VSLTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 1,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VULTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 1,
+ (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
+ IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VSHTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 0,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VUHTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 0,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VSLTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 1,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+def VULTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 1,
+ (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
+ IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits",
+ [/* For disassembly only; pattern left blank */]>;
+
+} // End of 'let Constraints = "$src = $dst" in'
+
//===----------------------------------------------------------------------===//
// FP FMA Operations.
//
-def VMLAD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
+def VMLAD : ADbI<0b11100, 0b00, 0, 0,
+ (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
IIC_fpMAC64, "vmla", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
RegConstraint<"$dstin = $dst">;
-def VMLAS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
+def VMLAS : ASbIn<0b11100, 0b00, 0, 0,
+ (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
IIC_fpMAC32, "vmla", ".f32\t$dst, $a, $b",
[(set SPR:$dst, (fadd (fmul SPR:$a, SPR:$b), SPR:$dstin))]>,
RegConstraint<"$dstin = $dst">;
-def VNMLSD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
+def VNMLSD : ADbI<0b11100, 0b01, 0, 0,
+ (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
IIC_fpMAC64, "vnmls", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
RegConstraint<"$dstin = $dst">;
-def VNMLSS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
+def VNMLSS : ASbI<0b11100, 0b01, 0, 0,
+ (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
IIC_fpMAC32, "vnmls", ".f32\t$dst, $a, $b",
[(set SPR:$dst, (fsub (fmul SPR:$a, SPR:$b), SPR:$dstin))]>,
RegConstraint<"$dstin = $dst">;
-def VMLSD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
+def VMLSD : ADbI<0b11100, 0b00, 1, 0,
+ (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
IIC_fpMAC64, "vmls", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
- RegConstraint<"$dstin = $dst"> {
- let Inst{6} = 1;
-}
+ RegConstraint<"$dstin = $dst">;
-def VMLSS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
+def VMLSS : ASbIn<0b11100, 0b00, 1, 0,
+ (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
IIC_fpMAC32, "vmls", ".f32\t$dst, $a, $b",
[(set SPR:$dst, (fadd (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
- RegConstraint<"$dstin = $dst"> {
- let Inst{6} = 1;
-}
+ RegConstraint<"$dstin = $dst">;
def : Pat<(fsub DPR:$dstin, (fmul DPR:$a, DPR:$b)),
(VMLSD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
def : Pat<(fsub SPR:$dstin, (fmul SPR:$a, SPR:$b)),
(VMLSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
-def VNMLAD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
+def VNMLAD : ADbI<0b11100, 0b01, 1, 0,
+ (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
IIC_fpMAC64, "vnmla", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
- RegConstraint<"$dstin = $dst"> {
- let Inst{6} = 1;
-}
+ RegConstraint<"$dstin = $dst">;
-def VNMLAS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
+def VNMLAS : ASbI<0b11100, 0b01, 1, 0,
+ (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
IIC_fpMAC32, "vnmla", ".f32\t$dst, $a, $b",
[(set SPR:$dst, (fsub (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
- RegConstraint<"$dstin = $dst"> {
- let Inst{6} = 1;
-}
+ RegConstraint<"$dstin = $dst">;
//===----------------------------------------------------------------------===//
// FP Conditional moves.
//
-def VMOVDcc : ADuI<0b11101011, 0b0000, 0b0100,
+def VMOVDcc : ADuI<0b11101, 0b11, 0b0000, 0b01, 0,
(outs DPR:$dst), (ins DPR:$false, DPR:$true),
IIC_fpUNA64, "vmov", ".f64\t$dst, $true",
[/*(set DPR:$dst, (ARMcmov DPR:$false, DPR:$true, imm:$cc))*/]>,
RegConstraint<"$false = $dst">;
-def VMOVScc : ASuI<0b11101011, 0b0000, 0b0100,
+def VMOVScc : ASuI<0b11101, 0b11, 0b0000, 0b01, 0,
(outs SPR:$dst), (ins SPR:$false, SPR:$true),
IIC_fpUNA32, "vmov", ".f32\t$dst, $true",
[/*(set SPR:$dst, (ARMcmov SPR:$false, SPR:$true, imm:$cc))*/]>,
RegConstraint<"$false = $dst">;
-def VNEGDcc : ADuI<0b11101011, 0b0001, 0b0100,
+def VNEGDcc : ADuI<0b11101, 0b11, 0b0001, 0b01, 0,
(outs DPR:$dst), (ins DPR:$false, DPR:$true),
IIC_fpUNA64, "vneg", ".f64\t$dst, $true",
[/*(set DPR:$dst, (ARMcneg DPR:$false, DPR:$true, imm:$cc))*/]>,
RegConstraint<"$false = $dst">;
-def VNEGScc : ASuI<0b11101011, 0b0001, 0b0100,
+def VNEGScc : ASuI<0b11101, 0b11, 0b0001, 0b01, 0,
(outs SPR:$dst), (ins SPR:$false, SPR:$true),
IIC_fpUNA32, "vneg", ".f32\t$dst, $true",
[/*(set SPR:$dst, (ARMcneg SPR:$false, SPR:$true, imm:$cc))*/]>,
@@ -432,6 +611,31 @@ def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs",
let Inst{4} = 1;
}
+// FPSCR <-> GPR (for disassembly only)
+
+let Uses = [FPSCR] in {
+def VMRS : VFPAI<(outs GPR:$dst), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs",
+ "\t$dst, fpscr",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-20} = 0b11101111;
+ let Inst{19-16} = 0b0001;
+ let Inst{11-8} = 0b1010;
+ let Inst{7} = 0;
+ let Inst{4} = 1;
+}
+}
+
+let Defs = [FPSCR] in {
+def VMSR : VFPAI<(outs), (ins GPR:$src), VFPMiscFrm, IIC_fpSTAT, "vmsr",
+ "\tfpscr, $src",
+ [/* For disassembly only; pattern left blank */]> {
+ let Inst{27-20} = 0b11101110;
+ let Inst{19-16} = 0b0001;
+ let Inst{11-8} = 0b1010;
+ let Inst{7} = 0;
+ let Inst{4} = 1;
+}
+}
// Materialize FP immediates. VFP3 only.
let isReMaterializable = 1 in {
diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index b78b95b..4e2d181 100644
--- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -350,7 +350,8 @@ ARMLoadStoreOpt::MergeLDR_STR(MachineBasicBlock &MBB, unsigned SIndex,
: ARMRegisterInfo::getRegisterNumbering(Reg);
// AM4 - register numbers in ascending order.
// AM5 - consecutive register numbers in ascending order.
- if (NewOffset == Offset + (int)Size &&
+ if (Reg != ARM::SP &&
+ NewOffset == Offset + (int)Size &&
((isAM4 && RegNum > PRegNum) || RegNum == PRegNum+1)) {
Offset += Size;
PRegNum = RegNum;
diff --git a/lib/Target/ARM/ARMMCAsmInfo.cpp b/lib/Target/ARM/ARMMCAsmInfo.cpp
index 3dd87c0..ccd6add 100644
--- a/lib/Target/ARM/ARMMCAsmInfo.cpp
+++ b/lib/Target/ARM/ARMMCAsmInfo.cpp
@@ -44,7 +44,6 @@ ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin() {
AsmTransCBE = arm_asm_table;
Data64bitsDirective = 0;
CommentString = "@";
- COMMDirectiveTakesAlignment = false;
SupportsDebugInformation = true;
// Exceptions handling
@@ -53,17 +52,16 @@ ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin() {
}
ARMELFMCAsmInfo::ARMELFMCAsmInfo() {
+ // ".comm align is in bytes but .align is pow-2."
AlignmentIsInBytes = false;
+
Data64bitsDirective = 0;
CommentString = "@";
- COMMDirectiveTakesAlignment = false;
-
- NeedsSet = false;
+
HasLEB128 = true;
AbsoluteDebugSectionOffsets = true;
PrivateGlobalPrefix = ".L";
WeakRefDirective = "\t.weak\t";
- SetDirective = "\t.set\t";
HasLCOMMDirective = true;
DwarfRequiresFrameSection = false;
diff --git a/lib/Target/ARM/ARMMachineFunctionInfo.h b/lib/Target/ARM/ARMMachineFunctionInfo.h
index 2176b27..c998ede 100644
--- a/lib/Target/ARM/ARMMachineFunctionInfo.h
+++ b/lib/Target/ARM/ARMMachineFunctionInfo.h
@@ -35,11 +35,6 @@ class ARMFunctionInfo : public MachineFunctionInfo {
/// 'isThumb'.
bool hasThumb2;
- /// Align - required alignment. ARM functions and Thumb functions with
- /// constant pools require 4-byte alignment; other Thumb functions
- /// require only 2-byte alignment.
- unsigned Align;
-
/// VarArgsRegSaveSize - Size of the register save area for vararg functions.
///
unsigned VarArgsRegSaveSize;
@@ -94,7 +89,6 @@ public:
ARMFunctionInfo() :
isThumb(false),
hasThumb2(false),
- Align(2U),
VarArgsRegSaveSize(0), HasStackFrame(false),
LRSpilledForFarJump(false),
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
@@ -105,7 +99,6 @@ public:
explicit ARMFunctionInfo(MachineFunction &MF) :
isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
- Align(isThumb ? 1U : 2U),
VarArgsRegSaveSize(0), HasStackFrame(false),
LRSpilledForFarJump(false),
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
@@ -118,9 +111,6 @@ public:
bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
bool isThumb2Function() const { return isThumb && hasThumb2; }
- unsigned getAlign() const { return Align; }
- void setAlign(unsigned a) { Align = a; }
-
unsigned getVarArgsRegSaveSize() const { return VarArgsRegSaveSize; }
void setVarArgsRegSaveSize(unsigned s) { VarArgsRegSaveSize = s; }
diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td
index d393e8d..0d4200c 100644
--- a/lib/Target/ARM/ARMRegisterInfo.td
+++ b/lib/Target/ARM/ARMRegisterInfo.td
@@ -123,8 +123,8 @@ def FPSCR : ARMReg<1, "fpscr">;
// r10 == Stack Limit
//
def GPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
- R7, R8, R9, R10, R12, R11,
- LR, SP, PC]> {
+ R7, R8, R9, R10, R11, R12,
+ SP, LR, PC]> {
let MethodProtos = [{
iterator allocation_order_begin(const MachineFunction &MF) const;
iterator allocation_order_end(const MachineFunction &MF) const;
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index 71f3883..426862c 100644
--- a/lib/Target/ARM/ARMSubtarget.cpp
+++ b/lib/Target/ARM/ARMSubtarget.cpp
@@ -122,9 +122,9 @@ ARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const {
if (RelocM == Reloc::Static)
return false;
- // GV with ghost linkage (in JIT lazy compilation mode) do not require an
- // extra load from stub.
- bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
+ // Materializable GVs (in JIT lazy compilation mode) do not require an extra
+ // load from stub.
+ bool isDecl = GV->isDeclaration() && !GV->isMaterializable();
if (!isTargetDarwin()) {
// Extra load is needed for all externally visible.
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
index 4d20a5c..7233f5c 100644
--- a/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -133,18 +133,6 @@ bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE) {
- // FIXME: Move this to TargetJITInfo!
- if (DefRelocModel == Reloc::Default)
- setRelocationModel(Reloc::Static);
-
- // Machine code emitter pass for ARM.
- PM.add(createARMCodeEmitterPass(*this, MCE));
- return false;
-}
-
-bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
JITCodeEmitter &JCE) {
// FIXME: Move this to TargetJITInfo!
if (DefRelocModel == Reloc::Default)
@@ -154,40 +142,3 @@ bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
PM.add(createARMJITCodeEmitterPass(*this, JCE));
return false;
}
-
-bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE) {
- // FIXME: Move this to TargetJITInfo!
- if (DefRelocModel == Reloc::Default)
- setRelocationModel(Reloc::Static);
-
- // Machine code emitter pass for ARM.
- PM.add(createARMObjectCodeEmitterPass(*this, OCE));
- return false;
-}
-
-bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE) {
- // Machine code emitter pass for ARM.
- PM.add(createARMCodeEmitterPass(*this, MCE));
- return false;
-}
-
-bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- JITCodeEmitter &JCE) {
- // Machine code emitter pass for ARM.
- PM.add(createARMJITCodeEmitterPass(*this, JCE));
- return false;
-}
-
-bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE) {
- // Machine code emitter pass for ARM.
- PM.add(createARMObjectCodeEmitterPass(*this, OCE));
- return false;
-}
-
diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h
index dd9542e..88e67e3 100644
--- a/lib/Target/ARM/ARMTargetMachine.h
+++ b/lib/Target/ARM/ARMTargetMachine.h
@@ -53,20 +53,7 @@ public:
virtual bool addPreSched2(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE);
- virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
JITCodeEmitter &MCE);
- virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- JITCodeEmitter &MCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE);
};
/// ARMTargetMachine - ARM target machine.
diff --git a/lib/Target/ARM/ARMTargetObjectFile.h b/lib/Target/ARM/ARMTargetObjectFile.h
index 9703403..a488c0a 100644
--- a/lib/Target/ARM/ARMTargetObjectFile.h
+++ b/lib/Target/ARM/ARMTargetObjectFile.h
@@ -10,7 +10,7 @@
#ifndef LLVM_TARGET_ARM_TARGETOBJECTFILE_H
#define LLVM_TARGET_ARM_TARGETOBJECTFILE_H
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/MC/MCSectionELF.h"
namespace llvm {
@@ -24,7 +24,7 @@ namespace llvm {
if (TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI()) {
StaticCtorSection =
- getELFSection(".init_array", MCSectionELF::SHT_INIT_ARRAY,
+ getELFSection(".init_array", MCSectionELF::SHT_INIT_ARRAY,
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
SectionKind::getDataRel());
StaticDtorSection =
diff --git a/lib/Target/ARM/AsmParser/Makefile b/lib/Target/ARM/AsmParser/Makefile
index 4fb8564..97e5612 100644
--- a/lib/Target/ARM/AsmParser/Makefile
+++ b/lib/Target/ARM/AsmParser/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMARMAsmParser
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' ARM target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index e1f386e..f60cc33 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -30,6 +30,7 @@
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
@@ -37,13 +38,11 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/CommandLine.h"
@@ -53,8 +52,6 @@
#include <cctype>
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
static cl::opt<bool>
EnableMCInst("enable-arm-mcinst-printer", cl::Hidden,
cl::desc("enable experimental asmprinter gunk in the arm backend"));
@@ -76,8 +73,9 @@ namespace {
public:
explicit ARMAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V)
- : AsmPrinter(O, TM, T, V), AFI(NULL), MCP(NULL) {
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+ : AsmPrinter(O, TM, Ctx, Streamer, T), AFI(NULL), MCP(NULL) {
Subtarget = &TM.getSubtarget<ARMSubtarget>();
}
@@ -85,10 +83,6 @@ namespace {
return "ARM Assembly Printer";
}
- void printMCInst(const MCInst *MI) {
- ARMInstPrinter(O, *MAI, VerboseAsm).printInstruction(MI);
- }
-
void printInstructionThroughMCStreamer(const MachineInstr *MI);
@@ -162,11 +156,18 @@ namespace {
void printInstruction(const MachineInstr *MI); // autogenerated.
static const char *getRegisterName(unsigned RegNo);
- void printMachineInstruction(const MachineInstr *MI);
+ virtual void EmitInstruction(const MachineInstr *MI);
bool runOnMachineFunction(MachineFunction &F);
+
+ virtual void EmitConstantPool() {} // we emit constant pools customly!
+ virtual void EmitFunctionEntryLabel();
void EmitStartOfAsmFile(Module &M);
void EmitEndOfAsmFile(Module &M);
+ MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
+ const MachineBasicBlock *MBB) const;
+ MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
+
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
/// the .s file.
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
@@ -199,7 +200,7 @@ namespace {
MachineModuleInfoMachO &MMIMachO =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
- const MCSymbol *&StubSym =
+ MCSymbol *&StubSym =
GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
MMIMachO.getGVStubEntry(Sym);
if (StubSym == 0)
@@ -219,7 +220,7 @@ namespace {
O << "-.";
O << ')';
}
- O << '\n';
+ OutStreamer.AddBlankLine();
}
void getAnalysisUsage(AnalysisUsage &AU) const {
@@ -233,97 +234,26 @@ namespace {
#include "ARMGenAsmWriter.inc"
-/// runOnMachineFunction - This uses the printInstruction()
-/// method to print assembly for each instruction.
-///
-bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
- this->MF = &MF;
-
- AFI = MF.getInfo<ARMFunctionInfo>();
- MCP = MF.getConstantPool();
-
- SetupMachineFunction(MF);
- O << "\n";
-
- // NOTE: we don't print out constant pools here, they are handled as
- // instructions.
-
- O << '\n';
-
- // Print out labels for the function.
- const Function *F = MF.getFunction();
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-
- switch (F->getLinkage()) {
- default: llvm_unreachable("Unknown linkage type!");
- case Function::PrivateLinkage:
- case Function::InternalLinkage:
- break;
- case Function::ExternalLinkage:
- O << "\t.globl\t" << *CurrentFnSym << "\n";
- break;
- case Function::LinkerPrivateLinkage:
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- if (Subtarget->isTargetDarwin()) {
- O << "\t.globl\t" << *CurrentFnSym << "\n";
- O << "\t.weak_definition\t" << *CurrentFnSym << "\n";
- } else {
- O << MAI->getWeakRefDirective() << *CurrentFnSym << "\n";
- }
- break;
- }
-
- printVisibility(CurrentFnSym, F->getVisibility());
-
- unsigned FnAlign = 1 << MF.getAlignment(); // MF alignment is log2.
+void ARMAsmPrinter::EmitFunctionEntryLabel() {
if (AFI->isThumbFunction()) {
- EmitAlignment(FnAlign, F, AFI->getAlign());
O << "\t.code\t16\n";
O << "\t.thumb_func";
if (Subtarget->isTargetDarwin())
- O << "\t" << *CurrentFnSym;
- O << "\n";
- } else {
- EmitAlignment(FnAlign, F);
- }
-
- O << *CurrentFnSym << ":\n";
- // Emit pre-function debug information.
- DW->BeginFunction(&MF);
-
- if (Subtarget->isTargetDarwin()) {
- // 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.
- MachineFunction::iterator I = MF.begin();
-
- if (++I == MF.end() && MF.front().empty())
- O << "\tnop\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())
- EmitBasicBlockStart(I);
-
- // Print the assembly for the instruction.
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II)
- printMachineInstruction(II);
+ O << '\t' << *CurrentFnSym;
+ O << '\n';
}
+
+ OutStreamer.EmitLabel(CurrentFnSym);
+}
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size " << *CurrentFnSym << ", .-" << *CurrentFnSym << "\n";
-
- // Emit post-function debug information.
- DW->EndFunction(&MF);
+/// runOnMachineFunction - This uses the printInstruction()
+/// method to print assembly for each instruction.
+///
+bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
+ AFI = MF.getInfo<ARMFunctionInfo>();
+ MCP = MF.getConstantPool();
- return false;
+ return AsmPrinter::runOnMachineFunction(MF);
}
void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
@@ -367,7 +297,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
break;
}
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_GlobalAddress: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
@@ -889,7 +819,7 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
// data itself.
if (!strcmp(Modifier, "label")) {
unsigned ID = MI->getOperand(OpNum).getImm();
- O << *GetCPISymbol(ID) << ":\n";
+ OutStreamer.EmitLabel(GetCPISymbol(ID));
} else {
assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
unsigned CPI = MI->getOperand(OpNum).getIndex();
@@ -904,6 +834,24 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
}
}
+MCSymbol *ARMAsmPrinter::
+GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
+ const MachineBasicBlock *MBB) const {
+ SmallString<60> Name;
+ raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
+ << getFunctionNumber() << '_' << uid << '_' << uid2
+ << "_set_" << MBB->getNumber();
+ return OutContext.GetOrCreateSymbol(Name.str());
+}
+
+MCSymbol *ARMAsmPrinter::
+GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
+ SmallString<60> Name;
+ raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
+ << getFunctionNumber() << '_' << uid << '_' << uid2;
+ return OutContext.GetOrCreateSymbol(Name.str());
+}
+
void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
@@ -911,36 +859,34 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
unsigned JTI = MO1.getIndex();
- O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << JTI << '_' << MO2.getImm() << ":\n";
+ MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
+ OutStreamer.EmitLabel(JTISymbol);
const char *JTEntryDirective = MAI->getData32bitsDirective();
- const MachineFunction *MF = MI->getParent()->getParent();
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
- bool UseSet= MAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
+ bool UseSet= MAI->hasSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
SmallPtrSet<MachineBasicBlock*, 8> JTSets;
for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
MachineBasicBlock *MBB = JTBBs[i];
bool isNew = JTSets.insert(MBB);
- if (UseSet && isNew)
- printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB);
+ if (UseSet && isNew) {
+ O << "\t.set\t"
+ << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB) << ','
+ << *MBB->getSymbol(OutContext) << '-' << *JTISymbol << '\n';
+ }
O << JTEntryDirective << ' ';
if (UseSet)
- O << MAI->getPrivateGlobalPrefix() << getFunctionNumber()
- << '_' << JTI << '_' << MO2.getImm()
- << "_set_" << MBB->getNumber();
- else if (TM.getRelocationModel() == Reloc::PIC_) {
- O << *GetMBBSymbol(MBB->getNumber())
- << '-' << MAI->getPrivateGlobalPrefix() << "JTI"
- << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
- } else {
- O << *GetMBBSymbol(MBB->getNumber());
- }
+ O << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB);
+ else if (TM.getRelocationModel() == Reloc::PIC_)
+ O << *MBB->getSymbol(OutContext) << '-' << *JTISymbol;
+ else
+ O << *MBB->getSymbol(OutContext);
+
if (i != e-1)
O << '\n';
}
@@ -950,10 +896,10 @@ void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
unsigned JTI = MO1.getIndex();
- O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << JTI << '_' << MO2.getImm() << ":\n";
+
+ MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
+ OutStreamer.EmitLabel(JTISymbol);
- const MachineFunction *MF = MI->getParent()->getParent();
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
@@ -969,13 +915,12 @@ void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum) {
O << MAI->getData8bitsDirective();
else if (HalfWordOffset)
O << MAI->getData16bitsDirective();
- if (ByteOffset || HalfWordOffset) {
- O << '(' << *GetMBBSymbol(MBB->getNumber());
- O << "-" << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << JTI << '_' << MO2.getImm() << ")/2";
- } else {
- O << "\tb.w " << *GetMBBSymbol(MBB->getNumber());
- }
+
+ if (ByteOffset || HalfWordOffset)
+ O << '(' << *MBB->getSymbol(OutContext) << "-" << *JTISymbol << ")/2";
+ else
+ O << "\tb.w " << *MBB->getSymbol(OutContext);
+
if (i != e-1)
O << '\n';
}
@@ -1076,12 +1021,7 @@ bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
return false;
}
-void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
- ++EmittedInsts;
-
- // Call the autogenerated instruction printer routines.
- processDebugLoc(MI, true);
-
+void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
if (EnableMCInst) {
printInstructionThroughMCStreamer(MI);
} else {
@@ -1090,12 +1030,8 @@ void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
EmitAlignment(2);
printInstruction(MI);
+ OutStreamer.AddBlankLine();
}
-
- if (VerboseAsm)
- EmitComments(*MI);
- O << '\n';
- processDebugLoc(MI, false);
}
void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
@@ -1215,20 +1151,6 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
case ARM::t2MOVi32imm:
assert(0 && "Should be lowered by thumb2it pass");
default: break;
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
- case TargetInstrInfo::GC_LABEL:
- printLabel(MI);
- return;
- case TargetInstrInfo::KILL:
- printKill(MI);
- return;
- case TargetInstrInfo::INLINEASM:
- printInlineAsm(MI);
- return;
- case TargetInstrInfo::IMPLICIT_DEF:
- printImplicitDef(MI);
- return;
case ARM::PICADD: { // FIXME: Remove asm string from td file.
// This is a pseudo op for a label + instruction sequence, which looks like:
// LPC0:
@@ -1250,7 +1172,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
- printMCInst(&AddInst);
+ OutStreamer.EmitInstruction(AddInst);
return;
}
case ARM::CONSTPOOL_ENTRY: { // FIXME: Remove asm string from td file.
@@ -1291,8 +1213,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
TmpInst.addOperand(MCOperand::CreateReg(0)); // cc_out
- printMCInst(&TmpInst);
- O << '\n';
+ OutStreamer.EmitInstruction(TmpInst);
}
{
@@ -1306,7 +1227,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
TmpInst.addOperand(MCOperand::CreateReg(0)); // cc_out
- printMCInst(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
}
return;
}
@@ -1325,8 +1246,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
- printMCInst(&TmpInst);
- O << '\n';
+ OutStreamer.EmitInstruction(TmpInst);
}
{
@@ -1340,7 +1260,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
- printMCInst(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
}
return;
@@ -1349,8 +1269,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
MCInst TmpInst;
MCInstLowering.Lower(MI, TmpInst);
-
- printMCInst(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
index 6885ecb..d7d8e09 100644
--- a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
@@ -24,7 +24,6 @@ using namespace llvm;
// Include the auto-generated portion of the assembly writer.
#define MachineInstr MCInst
#define ARMAsmPrinter ARMInstPrinter // FIXME: REMOVE.
-#define NO_ASM_WRITER_BOILERPLATE
#include "ARMGenAsmWriter.inc"
#undef MachineInstr
#undef ARMAsmPrinter
@@ -353,6 +352,5 @@ void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum) {
}
void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum) {
- // FIXME: remove this.
- abort();
+ O << "#" << MI->getOperand(OpNum).getImm() * 4;
}
diff --git a/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp b/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
index f843ee2..1b2dd48 100644
--- a/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
@@ -135,7 +135,7 @@ void ARMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
- Printer.GetMBBSymbol(MO.getMBB()->getNumber()), Ctx));
+ MO.getMBB()->getSymbol(Ctx), Ctx));
break;
case MachineOperand::MO_GlobalAddress:
MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
diff --git a/lib/Target/ARM/AsmPrinter/Makefile b/lib/Target/ARM/AsmPrinter/Makefile
index 93b8fc9..208becc 100644
--- a/lib/Target/ARM/AsmPrinter/Makefile
+++ b/lib/Target/ARM/AsmPrinter/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMARMAsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' arm target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/ARM/Makefile b/lib/Target/ARM/Makefile
index b766a86..a8dd38c 100644
--- a/lib/Target/ARM/Makefile
+++ b/lib/Target/ARM/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMARMCodeGen
TARGET = ARM
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = ARMGenRegisterInfo.h.inc ARMGenRegisterNames.inc \
diff --git a/lib/Target/ARM/README.txt b/lib/Target/ARM/README.txt
index a6f26a5..9efb5a1 100644
--- a/lib/Target/ARM/README.txt
+++ b/lib/Target/ARM/README.txt
@@ -71,26 +71,6 @@ were disabled due to badness with the ARM carry flag on subtracts.
//===---------------------------------------------------------------------===//
-We currently compile abs:
-int foo(int p) { return p < 0 ? -p : p; }
-
-into:
-
-_foo:
- rsb r1, r0, #0
- cmn r0, #1
- movgt r1, r0
- mov r0, r1
- bx lr
-
-This is very, uh, literal. This could be a 3 operation sequence:
- t = (p sra 31);
- res = (p xor t)-t
-
-Which would be better. This occurs in png decode.
-
-//===---------------------------------------------------------------------===//
-
More load / store optimizations:
1) Better representation for block transfer? This is from Olden/power:
diff --git a/lib/Target/ARM/TargetInfo/Makefile b/lib/Target/ARM/TargetInfo/Makefile
index 589dbe5..6292ab1 100644
--- a/lib/Target/ARM/TargetInfo/Makefile
+++ b/lib/Target/ARM/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMARMInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/ARM/Thumb2InstrInfo.cpp b/lib/Target/ARM/Thumb2InstrInfo.cpp
index 387edaf..20f13f1 100644
--- a/lib/Target/ARM/Thumb2InstrInfo.cpp
+++ b/lib/Target/ARM/Thumb2InstrInfo.cpp
@@ -382,8 +382,8 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
} else {
- // AddrMode4 cannot handle any offset.
- if (AddrMode == ARMII::AddrMode4)
+ // AddrMode4 and AddrMode6 cannot handle any offset.
+ if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
return false;
// AddrModeT2_so cannot handle any offset. If there is no offset
@@ -418,15 +418,12 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
NewOpc = positiveOffsetOpcode(Opcode);
NumBits = 12;
}
- } else {
- // VFP and NEON address modes.
- int InstrOffs = 0;
- if (AddrMode == ARMII::AddrMode5) {
- const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
- InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
- if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
- InstrOffs *= -1;
- }
+ } else if (AddrMode == ARMII::AddrMode5) {
+ // VFP address mode.
+ const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
+ int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
+ if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
+ InstrOffs *= -1;
NumBits = 8;
Scale = 4;
Offset += InstrOffs * 4;
@@ -435,6 +432,8 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
Offset = -Offset;
isSub = true;
}
+ } else {
+ llvm_unreachable("Unsupported addressing mode!");
}
if (NewOpc != Opcode)
diff --git a/lib/Target/ARM/Thumb2SizeReduction.cpp b/lib/Target/ARM/Thumb2SizeReduction.cpp
index 95288bf..5086eff 100644
--- a/lib/Target/ARM/Thumb2SizeReduction.cpp
+++ b/lib/Target/ARM/Thumb2SizeReduction.cpp
@@ -83,7 +83,7 @@ namespace {
// FIXME: Do we need the 16-bit 'S' variant?
{ ARM::t2MOVr,ARM::tMOVgpr2gpr,0, 0, 0, 0, 0, 1,0, 0 },
{ ARM::t2MOVCCr,0, ARM::tMOVCCr, 0, 0, 0, 0, 0,1, 0 },
- { ARM::t2MOVCCi,0, ARM::tMOVCCi, 0, 8, 0, 0, 0,1, 0 },
+ { ARM::t2MOVCCi,0, ARM::tMOVCCi, 0, 8, 0, 1, 0,1, 0 },
{ ARM::t2MUL, 0, ARM::tMUL, 0, 0, 0, 1, 0,0, 0 },
{ ARM::t2MVNr, ARM::tMVN, 0, 0, 0, 1, 0, 0,0, 0 },
{ ARM::t2ORRrr, 0, ARM::tORR, 0, 0, 0, 1, 0,0, 0 },
diff --git a/lib/Target/Alpha/Alpha.h b/lib/Target/Alpha/Alpha.h
index b8a0645..5cf4866 100644
--- a/lib/Target/Alpha/Alpha.h
+++ b/lib/Target/Alpha/Alpha.h
@@ -21,18 +21,12 @@ namespace llvm {
class AlphaTargetMachine;
class FunctionPass;
- class MachineCodeEmitter;
- class ObjectCodeEmitter;
class formatted_raw_ostream;
FunctionPass *createAlphaISelDag(AlphaTargetMachine &TM);
FunctionPass *createAlphaPatternInstructionSelector(TargetMachine &TM);
- FunctionPass *createAlphaCodeEmitterPass(AlphaTargetMachine &TM,
- MachineCodeEmitter &MCE);
FunctionPass *createAlphaJITCodeEmitterPass(AlphaTargetMachine &TM,
JITCodeEmitter &JCE);
- FunctionPass *createAlphaObjectCodeEmitterPass(AlphaTargetMachine &TM,
- ObjectCodeEmitter &OCE);
FunctionPass *createAlphaLLRPPass(AlphaTargetMachine &tm);
FunctionPass *createAlphaBranchSelectionPass();
diff --git a/lib/Target/Alpha/AlphaCodeEmitter.cpp b/lib/Target/Alpha/AlphaCodeEmitter.cpp
index b090f0d..eb5e429 100644
--- a/lib/Target/Alpha/AlphaCodeEmitter.cpp
+++ b/lib/Target/Alpha/AlphaCodeEmitter.cpp
@@ -17,9 +17,7 @@
#include "AlphaRelocations.h"
#include "Alpha.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
-#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/Passes.h"
@@ -30,11 +28,14 @@
using namespace llvm;
namespace {
-
- class AlphaCodeEmitter {
- MachineCodeEmitter &MCE;
+ class AlphaCodeEmitter : public MachineFunctionPass {
+ JITCodeEmitter &MCE;
+ const AlphaInstrInfo *II;
public:
- AlphaCodeEmitter(MachineCodeEmitter &mce) : MCE(mce) {}
+ static char ID;
+
+ AlphaCodeEmitter(JITCodeEmitter &mce) : MachineFunctionPass(&ID),
+ MCE(mce) {}
/// getBinaryCodeForInstr - This function, generated by the
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
@@ -46,57 +47,30 @@ namespace {
unsigned getMachineOpValue(const MachineInstr &MI,
const MachineOperand &MO);
- };
-
- template <class CodeEmitter>
- class Emitter : public MachineFunctionPass, public AlphaCodeEmitter
- {
- const AlphaInstrInfo *II;
- TargetMachine &TM;
- CodeEmitter &MCE;
-
- public:
- static char ID;
- explicit Emitter(TargetMachine &tm, CodeEmitter &mce)
- : MachineFunctionPass(&ID), AlphaCodeEmitter(mce),
- II(0), TM(tm), MCE(mce) {}
- Emitter(TargetMachine &tm, CodeEmitter &mce, const AlphaInstrInfo& ii)
- : MachineFunctionPass(&ID), AlphaCodeEmitter(mce),
- II(&ii), TM(tm), MCE(mce) {}
-
+
bool runOnMachineFunction(MachineFunction &MF);
-
+
virtual const char *getPassName() const {
return "Alpha Machine Code Emitter";
}
-
+
private:
void emitBasicBlock(MachineBasicBlock &MBB);
};
-
- template <class CodeEmitter>
- char Emitter<CodeEmitter>::ID = 0;
}
+char AlphaCodeEmitter::ID = 0;
+
+
/// createAlphaCodeEmitterPass - Return a pass that emits the collected Alpha
/// code to the specified MCE object.
-FunctionPass *llvm::createAlphaCodeEmitterPass(AlphaTargetMachine &TM,
- MachineCodeEmitter &MCE) {
- return new Emitter<MachineCodeEmitter>(TM, MCE);
-}
-
FunctionPass *llvm::createAlphaJITCodeEmitterPass(AlphaTargetMachine &TM,
JITCodeEmitter &JCE) {
- return new Emitter<JITCodeEmitter>(TM, JCE);
-}
-FunctionPass *llvm::createAlphaObjectCodeEmitterPass(AlphaTargetMachine &TM,
- ObjectCodeEmitter &OCE) {
- return new Emitter<ObjectCodeEmitter>(TM, OCE);
+ return new AlphaCodeEmitter(JCE);
}
-template <class CodeEmitter>
-bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
+bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
II = ((AlphaTargetMachine&)MF.getTarget()).getInstrInfo();
do {
@@ -108,8 +82,7 @@ bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
return false;
}
-template <class CodeEmitter>
-void Emitter<CodeEmitter>::emitBasicBlock(MachineBasicBlock &MBB) {
+void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
MCE.StartMachineBasicBlock(&MBB);
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
I != E; ++I) {
@@ -122,8 +95,8 @@ void Emitter<CodeEmitter>::emitBasicBlock(MachineBasicBlock &MBB) {
case Alpha::ALTENT:
case Alpha::PCLABEL:
case Alpha::MEMLABEL:
- case TargetInstrInfo::IMPLICIT_DEF:
- case TargetInstrInfo::KILL:
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
break; //skip these
}
MCE.processDebugLoc(MI.getDebugLoc(), false);
diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
index eaefef9..d6b17c2 100644
--- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
+++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
@@ -64,7 +64,7 @@ namespace {
/// that the bits 1-7 of LHS are already zero. If LHS is non-null, we are
/// in checking mode. If LHS is null, we assume that the mask has already
/// been validated before.
- uint64_t get_zapImm(SDValue LHS, uint64_t Constant) {
+ uint64_t get_zapImm(SDValue LHS, uint64_t Constant) const {
uint64_t BitsToCheck = 0;
unsigned Result = 0;
for (unsigned i = 0; i != 8; ++i) {
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index 471de7f..5d8310e 100644
--- a/lib/Target/Alpha/AlphaISelLowering.cpp
+++ b/lib/Target/Alpha/AlphaISelLowering.cpp
@@ -21,7 +21,7 @@
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
@@ -49,8 +49,6 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM)
setShiftAmountType(MVT::i64);
setBooleanContents(ZeroOrOneBooleanContent);
- setUsesGlobalOffsetTable(true);
-
addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
addRegisterClass(MVT::f64, Alpha::F8RCRegisterClass);
addRegisterClass(MVT::f32, Alpha::F4RCRegisterClass);
@@ -223,11 +221,13 @@ static SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) {
SDValue
AlphaTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // Alpha target does not yet support tail call optimization.
+ isTailCall = false;
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -282,7 +282,8 @@ AlphaTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
DAG.getIntPtrConstant(VA.getLocMemOffset()));
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
- PseudoSourceValue::getStack(), 0));
+ PseudoSourceValue::getStack(), 0,
+ false, false, 0));
}
}
@@ -426,7 +427,8 @@ AlphaTargetLowering::LowerFormalArguments(SDValue Chain,
// Create the SelectionDAG nodes corresponding to a load
//from this parameter
SDValue FIN = DAG.getFrameIndex(FI, MVT::i64);
- ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0);
+ ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0,
+ false, false, 0);
}
InVals.push_back(ArgVal);
}
@@ -442,14 +444,16 @@ AlphaTargetLowering::LowerFormalArguments(SDValue Chain,
int FI = MFI->CreateFixedObject(8, -8 * (6 - i), true, false);
if (i == 0) VarArgsBase = FI;
SDValue SDFI = DAG.getFrameIndex(FI, MVT::i64);
- LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0));
+ LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0,
+ false, false, 0));
if (TargetRegisterInfo::isPhysicalRegister(args_float[i]))
args_float[i] = AddLiveIn(MF, args_float[i], &Alpha::F8RCRegClass);
argt = DAG.getCopyFromReg(Chain, dl, args_float[i], MVT::f64);
FI = MFI->CreateFixedObject(8, - 8 * (12 - i), true, false);
SDFI = DAG.getFrameIndex(FI, MVT::i64);
- LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0));
+ LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0,
+ false, false, 0));
}
//Set up a token factor with all the stack traffic
@@ -528,11 +532,12 @@ void AlphaTargetLowering::LowerVAARG(SDNode *N, SDValue &Chain,
const Value *VAListS = cast<SrcValueSDNode>(N->getOperand(2))->getValue();
DebugLoc dl = N->getDebugLoc();
- SDValue Base = DAG.getLoad(MVT::i64, dl, Chain, VAListP, VAListS, 0);
+ SDValue Base = DAG.getLoad(MVT::i64, dl, Chain, VAListP, VAListS, 0,
+ false, false, 0);
SDValue Tmp = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP,
DAG.getConstant(8, MVT::i64));
SDValue Offset = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Base.getValue(1),
- Tmp, NULL, 0, MVT::i32);
+ Tmp, NULL, 0, MVT::i32, false, false, 0);
DataPtr = DAG.getNode(ISD::ADD, dl, MVT::i64, Base, Offset);
if (N->getValueType(0).isFloatingPoint())
{
@@ -547,7 +552,7 @@ void AlphaTargetLowering::LowerVAARG(SDNode *N, SDValue &Chain,
SDValue NewOffset = DAG.getNode(ISD::ADD, dl, MVT::i64, Offset,
DAG.getConstant(8, MVT::i64));
Chain = DAG.getTruncStore(Offset.getValue(1), dl, NewOffset, Tmp, NULL, 0,
- MVT::i32);
+ MVT::i32, false, false, 0);
}
/// LowerOperation - Provide custom lowering hooks for some operations.
@@ -694,9 +699,10 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
SDValue Result;
if (Op.getValueType() == MVT::i32)
Result = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Chain, DataPtr,
- NULL, 0, MVT::i32);
+ NULL, 0, MVT::i32, false, false, 0);
else
- Result = DAG.getLoad(Op.getValueType(), dl, Chain, DataPtr, NULL, 0);
+ Result = DAG.getLoad(Op.getValueType(), dl, Chain, DataPtr, NULL, 0,
+ false, false, 0);
return Result;
}
case ISD::VACOPY: {
@@ -706,15 +712,18 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
const Value *DestS = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
const Value *SrcS = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
- SDValue Val = DAG.getLoad(getPointerTy(), dl, Chain, SrcP, SrcS, 0);
- SDValue Result = DAG.getStore(Val.getValue(1), dl, Val, DestP, DestS, 0);
+ SDValue Val = DAG.getLoad(getPointerTy(), dl, Chain, SrcP, SrcS, 0,
+ false, false, 0);
+ SDValue Result = DAG.getStore(Val.getValue(1), dl, Val, DestP, DestS, 0,
+ false, false, 0);
SDValue NP = DAG.getNode(ISD::ADD, dl, MVT::i64, SrcP,
DAG.getConstant(8, MVT::i64));
Val = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Result,
- NP, NULL,0, MVT::i32);
+ NP, NULL,0, MVT::i32, false, false, 0);
SDValue NPD = DAG.getNode(ISD::ADD, dl, MVT::i64, DestP,
DAG.getConstant(8, MVT::i64));
- return DAG.getTruncStore(Val.getValue(1), dl, Val, NPD, NULL, 0, MVT::i32);
+ return DAG.getTruncStore(Val.getValue(1), dl, Val, NPD, NULL, 0, MVT::i32,
+ false, false, 0);
}
case ISD::VASTART: {
SDValue Chain = Op.getOperand(0);
@@ -723,11 +732,12 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
// vastart stores the address of the VarArgsBase and VarArgsOffset
SDValue FR = DAG.getFrameIndex(VarArgsBase, MVT::i64);
- SDValue S1 = DAG.getStore(Chain, dl, FR, VAListP, VAListS, 0);
+ SDValue S1 = DAG.getStore(Chain, dl, FR, VAListP, VAListS, 0,
+ false, false, 0);
SDValue SA2 = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP,
DAG.getConstant(8, MVT::i64));
return DAG.getTruncStore(S1, dl, DAG.getConstant(VarArgsOffset, MVT::i64),
- SA2, NULL, 0, MVT::i32);
+ SA2, NULL, 0, MVT::i32, false, false, 0);
}
case ISD::RETURNADDR:
return DAG.getNode(AlphaISD::GlobalRetAddr, DebugLoc::getUnknownLoc(),
@@ -749,7 +759,8 @@ void AlphaTargetLowering::ReplaceNodeResults(SDNode *N,
SDValue Chain, DataPtr;
LowerVAARG(N, Chain, DataPtr, DAG);
- SDValue Res = DAG.getLoad(N->getValueType(0), dl, Chain, DataPtr, NULL, 0);
+ SDValue Res = DAG.getLoad(N->getValueType(0), dl, Chain, DataPtr, NULL, 0,
+ false, false, 0);
Results.push_back(Res);
Results.push_back(SDValue(Res.getNode(), 1));
}
diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h
index b204faf..0f17025 100644
--- a/lib/Target/Alpha/AlphaISelLowering.h
+++ b/lib/Target/Alpha/AlphaISelLowering.h
@@ -121,7 +121,7 @@ namespace llvm {
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
- CallingConv::ID CallConv, bool isVarArg, bool isTailCall,
+ CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/Alpha/AlphaMCAsmInfo.cpp b/lib/Target/Alpha/AlphaMCAsmInfo.cpp
index b652a53..c67c6a2 100644
--- a/lib/Target/Alpha/AlphaMCAsmInfo.cpp
+++ b/lib/Target/Alpha/AlphaMCAsmInfo.cpp
@@ -17,6 +17,7 @@ using namespace llvm;
AlphaMCAsmInfo::AlphaMCAsmInfo(const Target &T, const StringRef &TT) {
AlignmentIsInBytes = false;
PrivateGlobalPrefix = "$";
- PICJumpTableDirective = ".gprel32";
+ GPRel32Directive = ".gprel32";
WeakRefDirective = "\t.weak\t";
+ HasSetDirective = false;
}
diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp
index 64bdd62..ba662fb 100644
--- a/lib/Target/Alpha/AlphaRegisterInfo.cpp
+++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp
@@ -251,7 +251,7 @@ void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const {
} else {
std::string msg;
raw_string_ostream Msg(msg);
- Msg << "Too big a stack frame at " + NumBytes;
+ Msg << "Too big a stack frame at " << NumBytes;
llvm_report_error(Msg.str());
}
@@ -303,15 +303,14 @@ void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF,
} else {
std::string msg;
raw_string_ostream Msg(msg);
- Msg << "Too big a stack frame at " + NumBytes;
+ Msg << "Too big a stack frame at " << NumBytes;
llvm_report_error(Msg.str());
}
}
}
unsigned AlphaRegisterInfo::getRARegister() const {
- llvm_unreachable("What is the return address register");
- return 0;
+ return Alpha::R26;
}
unsigned AlphaRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
diff --git a/lib/Target/Alpha/AlphaTargetMachine.cpp b/lib/Target/Alpha/AlphaTargetMachine.cpp
index d0d5a43..5169a01 100644
--- a/lib/Target/Alpha/AlphaTargetMachine.cpp
+++ b/lib/Target/Alpha/AlphaTargetMachine.cpp
@@ -55,35 +55,7 @@ bool AlphaTargetMachine::addPreEmitPass(PassManagerBase &PM,
}
bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM,
CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE) {
- PM.add(createAlphaCodeEmitterPass(*this, MCE));
- return false;
-}
-bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
JITCodeEmitter &JCE) {
PM.add(createAlphaJITCodeEmitterPass(*this, JCE));
return false;
}
-bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE) {
- PM.add(createAlphaObjectCodeEmitterPass(*this, OCE));
- return false;
-}
-bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE) {
- return addCodeEmitter(PM, OptLevel, MCE);
-}
-bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- JITCodeEmitter &JCE) {
- return addCodeEmitter(PM, OptLevel, JCE);
-}
-bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE) {
- return addCodeEmitter(PM, OptLevel, OCE);
-}
-
diff --git a/lib/Target/Alpha/AlphaTargetMachine.h b/lib/Target/Alpha/AlphaTargetMachine.h
index f03e938..6f3a774 100644
--- a/lib/Target/Alpha/AlphaTargetMachine.h
+++ b/lib/Target/Alpha/AlphaTargetMachine.h
@@ -56,20 +56,7 @@ public:
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE);
- virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
JITCodeEmitter &JCE);
- virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &JCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- JITCodeEmitter &JCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE);
};
} // end namespace llvm
diff --git a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
index b13f544..733a46c 100644
--- a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
+++ b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
@@ -29,30 +29,33 @@
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/ADT/Statistic.h"
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
namespace {
struct AlphaAsmPrinter : public AsmPrinter {
/// Unique incrementer for label values for referencing Global values.
///
explicit AlphaAsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
- const MCAsmInfo *T, bool V)
- : AsmPrinter(o, tm, T, V) {}
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+ : AsmPrinter(o, tm, Ctx, Streamer, T) {}
virtual const char *getPassName() const {
return "Alpha Assembly Printer";
}
void printInstruction(const MachineInstr *MI);
+ void EmitInstruction(const MachineInstr *MI) {
+ printInstruction(MI);
+ OutStreamer.AddBlankLine();
+ }
static const char *getRegisterName(unsigned RegNo);
void printOp(const MachineOperand &MO, bool IsCallOp = false);
void printOperand(const MachineInstr *MI, int opNum);
void printBaseOffsetPair(const MachineInstr *MI, int i, bool brackets=true);
- bool runOnMachineFunction(MachineFunction &F);
+ virtual void EmitFunctionBodyStart();
+ virtual void EmitFunctionBodyEnd();
void EmitStartOfAsmFile(Module &M);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
@@ -93,7 +96,7 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_ConstantPoolIndex:
@@ -120,73 +123,16 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
}
}
-/// runOnMachineFunction - This uses the printMachineInstruction()
-/// method to print assembly for each instruction.
-///
-bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
- this->MF = &MF;
-
- SetupMachineFunction(MF);
- O << "\n\n";
-
- // Print out constants referenced by the function
- EmitConstantPool(MF.getConstantPool());
-
- // Print out jump tables referenced by the function
- EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
-
- // Print out labels for the function.
- const Function *F = MF.getFunction();
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-
- EmitAlignment(MF.getAlignment(), F);
- switch (F->getLinkage()) {
- default: llvm_unreachable("Unknown linkage type!");
- case Function::InternalLinkage: // Symbols default to internal.
- case Function::PrivateLinkage:
- case Function::LinkerPrivateLinkage:
- break;
- case Function::ExternalLinkage:
- O << "\t.globl " << *CurrentFnSym << '\n';
- break;
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- O << MAI->getWeakRefDirective() << *CurrentFnSym << '\n';
- break;
- }
-
- printVisibility(CurrentFnSym, F->getVisibility());
-
+/// EmitFunctionBodyStart - Targets can override this to emit stuff before
+/// the first basic block in the function.
+void AlphaAsmPrinter::EmitFunctionBodyStart() {
O << "\t.ent " << *CurrentFnSym << "\n";
+}
- O << *CurrentFnSym << ":\n";
-
- // Print out code for the function.
- for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
- I != E; ++I) {
- if (I != MF.begin())
- EmitBasicBlockStart(I);
-
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II) {
- // Print the assembly for the instruction.
- ++EmittedInsts;
- processDebugLoc(II, true);
- printInstruction(II);
-
- if (VerboseAsm)
- EmitComments(*II);
- O << '\n';
- processDebugLoc(II, false);
- }
- }
-
+/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
+/// the last basic block in the function.
+void AlphaAsmPrinter::EmitFunctionBodyEnd() {
O << "\t.end " << *CurrentFnSym << "\n";
-
- // We didn't modify anything.
- return false;
}
void AlphaAsmPrinter::EmitStartOfAsmFile(Module &M) {
diff --git a/lib/Target/Alpha/AsmPrinter/Makefile b/lib/Target/Alpha/AsmPrinter/Makefile
index 3f64aac..3c64a3c 100644
--- a/lib/Target/Alpha/AsmPrinter/Makefile
+++ b/lib/Target/Alpha/AsmPrinter/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMAlphaAsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' alpha target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Alpha/Makefile b/lib/Target/Alpha/Makefile
index 14cbc6c..54d53ab 100644
--- a/lib/Target/Alpha/Makefile
+++ b/lib/Target/Alpha/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMAlphaCodeGen
TARGET = Alpha
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = AlphaGenRegisterInfo.h.inc AlphaGenRegisterNames.inc \
diff --git a/lib/Target/Alpha/TargetInfo/Makefile b/lib/Target/Alpha/TargetInfo/Makefile
index 6f7b898..de01d7f 100644
--- a/lib/Target/Alpha/TargetInfo/Makefile
+++ b/lib/Target/Alpha/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMAlphaInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
index 749f735..fe13e14 100644
--- a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
+++ b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
@@ -30,20 +30,18 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
namespace {
class BlackfinAsmPrinter : public AsmPrinter {
public:
BlackfinAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *MAI, bool V)
- : AsmPrinter(O, TM, MAI, V) {}
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *MAI)
+ : AsmPrinter(O, TM, Ctx, Streamer, MAI) {}
virtual const char *getPassName() const {
return "Blackfin Assembly Printer";
@@ -54,8 +52,10 @@ namespace {
void printInstruction(const MachineInstr *MI); // autogenerated.
static const char *getRegisterName(unsigned RegNo);
- void emitLinkage(const MCSymbol *GVSym, GlobalValue::LinkageTypes l);
- bool runOnMachineFunction(MachineFunction &F);
+ void EmitInstruction(const MachineInstr *MI) {
+ printInstruction(MI);
+ OutStreamer.AddBlankLine();
+ }
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
@@ -69,76 +69,6 @@ extern "C" void LLVMInitializeBlackfinAsmPrinter() {
RegisterAsmPrinter<BlackfinAsmPrinter> X(TheBlackfinTarget);
}
-void BlackfinAsmPrinter::emitLinkage(const MCSymbol *GVSym,
- GlobalValue::LinkageTypes L) {
- switch (L) {
- default: llvm_unreachable("Unknown linkage type!");
- case GlobalValue::InternalLinkage: // Symbols default to internal.
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- break;
- case GlobalValue::ExternalLinkage:
- O << MAI->getGlobalDirective() << *GVSym << "\n";
- break;
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- O << MAI->getGlobalDirective() << *GVSym << "\n";
- O << MAI->getWeakDefDirective() << *GVSym << "\n";
- break;
- }
-}
-
-/// runOnMachineFunction - This uses the printInstruction()
-/// method to print assembly for each instruction.
-///
-bool BlackfinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
- SetupMachineFunction(MF);
- EmitConstantPool(MF.getConstantPool());
- EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
-
- const Function *F = MF.getFunction();
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
- EmitAlignment(2, F);
- emitLinkage(CurrentFnSym, F->getLinkage());
- printVisibility(CurrentFnSym, F->getVisibility());
-
- O << "\t.type\t" << *CurrentFnSym << ", STT_FUNC\n";
- O << *CurrentFnSym << ":\n";
-
- if (DW)
- 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.
- EmitBasicBlockStart(I);
-
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II) {
- // Print the assembly for the instruction.
- processDebugLoc(II, true);
-
- printInstruction(II);
- if (VerboseAsm)
- EmitComments(*II);
- O << '\n';
-
- processDebugLoc(II, false);
- ++EmittedInsts;
- }
- }
-
- O << "\t.size " << *CurrentFnSym << ", .-" << *CurrentFnSym << "\n";
-
- if (DW)
- DW->EndFunction(&MF);
-
- return false;
-}
-
void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
const MachineOperand &MO = MI->getOperand (opNum);
switch (MO.getType()) {
@@ -152,7 +82,7 @@ void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_GlobalAddress:
O << *GetGlobalValueSymbol(MO.getGlobal());
diff --git a/lib/Target/Blackfin/AsmPrinter/Makefile b/lib/Target/Blackfin/AsmPrinter/Makefile
index 30e8285..091d4df 100644
--- a/lib/Target/Blackfin/AsmPrinter/Makefile
+++ b/lib/Target/Blackfin/AsmPrinter/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMBlackfinAsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' Blackfin target directory to grab private
# headers
diff --git a/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp b/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp
index e1b6008..2c9cc60 100644
--- a/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp
+++ b/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp
@@ -175,7 +175,7 @@ void BlackfinDAGToDAGISel::FixRegisterClasses(SelectionDAG &DAG) {
// We cannot copy CC <-> !(CC/D)
if ((isCC(DefRC) && !isDCC(UseRC)) || (isCC(UseRC) && !isDCC(DefRC))) {
SDNode *Copy =
- DAG.getMachineNode(TargetInstrInfo::COPY_TO_REGCLASS,
+ DAG.getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
NI->getDebugLoc(),
MVT::i32,
UI.getUse().get(),
diff --git a/lib/Target/Blackfin/BlackfinISelLowering.cpp b/lib/Target/Blackfin/BlackfinISelLowering.cpp
index ad2510a..5ce2013 100644
--- a/lib/Target/Blackfin/BlackfinISelLowering.cpp
+++ b/lib/Target/Blackfin/BlackfinISelLowering.cpp
@@ -22,7 +22,7 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -206,7 +206,8 @@ BlackfinTargetLowering::LowerFormalArguments(SDValue Chain,
int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(),
true, false);
SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
- InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0));
+ InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0,
+ false, false, 0));
}
}
@@ -273,11 +274,13 @@ BlackfinTargetLowering::LowerReturn(SDValue Chain,
SDValue
BlackfinTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // Blackfin target does not yet support tail call optimization.
+ isTailCall = false;
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -327,7 +330,7 @@ BlackfinTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
OffsetN = DAG.getNode(ISD::ADD, dl, MVT::i32, SPN, OffsetN);
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, OffsetN,
PseudoSourceValue::getStack(),
- Offset));
+ Offset, false, false, 0));
}
}
diff --git a/lib/Target/Blackfin/BlackfinISelLowering.h b/lib/Target/Blackfin/BlackfinISelLowering.h
index cdbc7d2..5f39910 100644
--- a/lib/Target/Blackfin/BlackfinISelLowering.h
+++ b/lib/Target/Blackfin/BlackfinISelLowering.h
@@ -64,7 +64,7 @@ namespace llvm {
SmallVectorImpl<SDValue> &InVals);
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
- CallingConv::ID CallConv, bool isVarArg, bool isTailCall,
+ CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/Blackfin/BlackfinMCAsmInfo.cpp b/lib/Target/Blackfin/BlackfinMCAsmInfo.cpp
index 6d0f66c..31470fb 100644
--- a/lib/Target/Blackfin/BlackfinMCAsmInfo.cpp
+++ b/lib/Target/Blackfin/BlackfinMCAsmInfo.cpp
@@ -18,4 +18,5 @@ using namespace llvm;
BlackfinMCAsmInfo::BlackfinMCAsmInfo(const Target &T, const StringRef &TT) {
GlobalPrefix = "_";
CommentString = "//";
+ HasSetDirective = false;
}
diff --git a/lib/Target/Blackfin/Makefile b/lib/Target/Blackfin/Makefile
index 4fdaf27..339bef9 100644
--- a/lib/Target/Blackfin/Makefile
+++ b/lib/Target/Blackfin/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMBlackfinCodeGen
TARGET = Blackfin
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = BlackfinGenRegisterInfo.h.inc BlackfinGenRegisterNames.inc \
diff --git a/lib/Target/Blackfin/TargetInfo/Makefile b/lib/Target/Blackfin/TargetInfo/Makefile
index 5c770cf..c49cfbe 100644
--- a/lib/Target/Blackfin/TargetInfo/Makefile
+++ b/lib/Target/Blackfin/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMBlackfinInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index e765655..c1c1d80 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -493,7 +493,7 @@ raw_ostream &
CWriter::printSimpleType(formatted_raw_ostream &Out, const Type *Ty,
bool isSigned,
const std::string &NameSoFar) {
- assert((Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) &&
+ assert((Ty->isPrimitiveType() || Ty->isIntegerTy() || isa<VectorType>(Ty)) &&
"Invalid type for printSimpleType");
switch (Ty->getTypeID()) {
case Type::VoidTyID: return Out << "void " << NameSoFar;
@@ -540,7 +540,7 @@ CWriter::printSimpleType(formatted_raw_ostream &Out, const Type *Ty,
std::ostream &
CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned,
const std::string &NameSoFar) {
- assert((Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) &&
+ assert((Ty->isPrimitiveType() || Ty->isIntegerTy() || isa<VectorType>(Ty)) &&
"Invalid type for printSimpleType");
switch (Ty->getTypeID()) {
case Type::VoidTyID: return Out << "void " << NameSoFar;
@@ -591,7 +591,7 @@ raw_ostream &CWriter::printType(formatted_raw_ostream &Out,
const Type *Ty,
bool isSigned, const std::string &NameSoFar,
bool IgnoreName, const AttrListPtr &PAL) {
- if (Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) {
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy() || isa<VectorType>(Ty)) {
printSimpleType(Out, Ty, isSigned, NameSoFar);
return Out;
}
@@ -694,7 +694,7 @@ raw_ostream &CWriter::printType(formatted_raw_ostream &Out,
std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
bool isSigned, const std::string &NameSoFar,
bool IgnoreName, const AttrListPtr &PAL) {
- if (Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) {
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy() || isa<VectorType>(Ty)) {
printSimpleType(Out, Ty, isSigned, NameSoFar);
return Out;
}
@@ -1396,7 +1396,7 @@ bool CWriter::printConstExprCast(const ConstantExpr* CE, bool Static) {
}
if (NeedsExplicitCast) {
Out << "((";
- if (Ty->isInteger() && Ty != Type::getInt1Ty(Ty->getContext()))
+ if (Ty->isIntegerTy() && Ty != Type::getInt1Ty(Ty->getContext()))
printSimpleType(Out, Ty, TypeIsSigned);
else
printType(Out, Ty); // not integer, sign doesn't matter
@@ -1497,7 +1497,7 @@ void CWriter::writeInstComputationInline(Instruction &I) {
// We can't currently support integer types other than 1, 8, 16, 32, 64.
// Validate this.
const Type *Ty = I.getType();
- if (Ty->isInteger() && (Ty!=Type::getInt1Ty(I.getContext()) &&
+ if (Ty->isIntegerTy() && (Ty!=Type::getInt1Ty(I.getContext()) &&
Ty!=Type::getInt8Ty(I.getContext()) &&
Ty!=Type::getInt16Ty(I.getContext()) &&
Ty!=Type::getInt32Ty(I.getContext()) &&
@@ -1841,7 +1841,7 @@ static SpecialGlobalClass getGlobalVariableClass(const GlobalVariable *GV) {
return GlobalDtors;
}
- // Otherwise, it it is other metadata, don't print it. This catches things
+ // Otherwise, if it is other metadata, don't print it. This catches things
// like debug information.
if (GV->getSection() == "llvm.metadata")
return NotPrinted;
@@ -2287,7 +2287,8 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
void CWriter::printContainedStructs(const Type *Ty,
std::set<const Type*> &StructPrinted) {
// Don't walk through pointers.
- if (isa<PointerType>(Ty) || Ty->isPrimitiveType() || Ty->isInteger()) return;
+ if (isa<PointerType>(Ty) || Ty->isPrimitiveType() || Ty->isIntegerTy())
+ return;
// Print all contained types first.
for (Type::subtype_iterator I = Ty->subtype_begin(),
@@ -2423,8 +2424,8 @@ static inline bool isFPIntBitCast(const Instruction &I) {
return false;
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DstTy = I.getType();
- return (SrcTy->isFloatingPoint() && DstTy->isInteger()) ||
- (DstTy->isFloatingPoint() && SrcTy->isInteger());
+ return (SrcTy->isFloatingPointTy() && DstTy->isIntegerTy()) ||
+ (DstTy->isFloatingPointTy() && SrcTy->isIntegerTy());
}
void CWriter::printFunction(Function &F) {
@@ -3113,7 +3114,7 @@ void CWriter::visitCallInst(CallInst &I) {
}
/// visitBuiltinCall - Handle the call to the specified builtin. Returns true
-/// if the entire call is handled, return false it it wasn't handled, and
+/// if the entire call is handled, return false if it wasn't handled, and
/// optionally set 'WroteCallee' if the callee has already been printed out.
bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID,
bool &WroteCallee) {
@@ -3706,7 +3707,7 @@ bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
formatted_raw_ostream &o,
CodeGenFileType FileType,
CodeGenOpt::Level OptLevel) {
- if (FileType != TargetMachine::AssemblyFile) return true;
+ if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
PM.add(createGCLoweringPass());
PM.add(createLowerInvokePass());
diff --git a/lib/Target/CBackend/Makefile b/lib/Target/CBackend/Makefile
index f82d277..621948a 100644
--- a/lib/Target/CBackend/Makefile
+++ b/lib/Target/CBackend/Makefile
@@ -9,8 +9,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMCBackend
-CXXFLAGS = -fno-rtti
-
DIRS = TargetInfo
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/CBackend/TargetInfo/Makefile b/lib/Target/CBackend/TargetInfo/Makefile
index 6407904..d4d5e15 100644
--- a/lib/Target/CBackend/TargetInfo/Makefile
+++ b/lib/Target/CBackend/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMCBackendInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/CMakeLists.txt b/lib/Target/CMakeLists.txt
index 10478b4..43ebdac 100644
--- a/lib/Target/CMakeLists.txt
+++ b/lib/Target/CMakeLists.txt
@@ -9,7 +9,6 @@ add_llvm_library(LLVMTarget
TargetInstrInfo.cpp
TargetIntrinsicInfo.cpp
TargetLoweringObjectFile.cpp
- TargetMachOWriterInfo.cpp
TargetMachine.cpp
TargetRegisterInfo.cpp
TargetSubtarget.cpp
diff --git a/lib/Target/CellSPU/AsmPrinter/Makefile b/lib/Target/CellSPU/AsmPrinter/Makefile
index aa0db52..69639ef 100644
--- a/lib/Target/CellSPU/AsmPrinter/Makefile
+++ b/lib/Target/CellSPU/AsmPrinter/Makefile
@@ -9,7 +9,6 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMCellSPUAsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' CellSPU target directory to grab
# private headers
diff --git a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
index 59d6ddd..2ca05c2 100644
--- a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
+++ b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
@@ -19,12 +19,8 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
-#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
@@ -33,25 +29,18 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/MathExtras.h"
using namespace llvm;
namespace {
- STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
- const std::string bss_section(".bss");
-
class SPUAsmPrinter : public AsmPrinter {
public:
explicit SPUAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V) :
- AsmPrinter(O, TM, T, V) {}
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T) :
+ AsmPrinter(O, TM, Ctx, Streamer, T) {}
virtual const char *getPassName() const {
return "STI CBEA SPU Assembly Printer";
@@ -67,7 +56,10 @@ namespace {
static const char *getRegisterName(unsigned RegNo);
- void printMachineInstruction(const MachineInstr *MI);
+ void EmitInstruction(const MachineInstr *MI) {
+ printInstruction(MI);
+ OutStreamer.AddBlankLine();
+ }
void printOp(const MachineOperand &MO);
/// printRegister - Print register according to target requirements.
@@ -276,29 +268,6 @@ namespace {
llvm_unreachable("Invalid/non-immediate rotate amount in printRotateNeg7Imm");
}
}
-
- virtual bool runOnMachineFunction(MachineFunction &F) = 0;
- };
-
- /// LinuxAsmPrinter - SPU assembly printer, customized for Linux
- class LinuxAsmPrinter : public SPUAsmPrinter {
- public:
- explicit LinuxAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V)
- : SPUAsmPrinter(O, TM, T, V) {}
-
- virtual const char *getPassName() const {
- return "STI CBEA SPU Assembly Printer";
- }
-
- bool runOnMachineFunction(MachineFunction &F);
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<MachineModuleInfo>();
- AU.addRequired<DwarfWriter>();
- SPUAsmPrinter::getAnalysisUsage(AU);
- }
};
} // end of anonymous namespace
@@ -312,7 +281,7 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
@@ -386,88 +355,7 @@ bool SPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
return false;
}
-/// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax
-/// to the current output stream.
-///
-void SPUAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
- ++EmittedInsts;
- processDebugLoc(MI, true);
- printInstruction(MI);
- if (VerboseAsm)
- EmitComments(*MI);
- processDebugLoc(MI, false);
- O << '\n';
-}
-
-/// runOnMachineFunction - This uses the printMachineInstruction()
-/// method to print assembly for each instruction.
-///
-bool LinuxAsmPrinter::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();
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
- EmitAlignment(MF.getAlignment(), F);
-
- switch (F->getLinkage()) {
- default: llvm_unreachable("Unknown linkage type!");
- case Function::PrivateLinkage:
- case Function::LinkerPrivateLinkage:
- case Function::InternalLinkage: // Symbols default to internal.
- break;
- case Function::ExternalLinkage:
- O << "\t.global\t" << *CurrentFnSym << "\n" << "\t.type\t";
- O << *CurrentFnSym << ", @function\n";
- break;
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- O << "\t.global\t" << *CurrentFnSym << "\n";
- O << "\t.weak_definition\t" << *CurrentFnSym << "\n";
- break;
- }
-
- O << *CurrentFnSym << ":\n";
-
- // 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()) {
- EmitBasicBlockStart(I);
- }
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II) {
- // Print the assembly for the instruction.
- printMachineInstruction(II);
- }
- }
-
- O << "\t.size\t" << *CurrentFnSym << ",.-" << *CurrentFnSym << "\n";
-
- // Print out jump tables referenced by the function.
- EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
-
- // Emit post-function debug information.
- DW->EndFunction(&MF);
-
- // We didn't modify anything.
- return false;
-}
-
// Force static initialization.
extern "C" void LLVMInitializeCellSPUAsmPrinter() {
- RegisterAsmPrinter<LinuxAsmPrinter> X(TheCellSPUTarget);
+ RegisterAsmPrinter<SPUAsmPrinter> X(TheCellSPUTarget);
}
diff --git a/lib/Target/CellSPU/Makefile b/lib/Target/CellSPU/Makefile
index 9f3ff74..cbdbd3c 100644
--- a/lib/Target/CellSPU/Makefile
+++ b/lib/Target/CellSPU/Makefile
@@ -10,8 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMCellSPUCodeGen
TARGET = SPU
-CXXFLAGS = -fno-rtti
-
BUILT_SOURCES = SPUGenInstrNames.inc SPUGenRegisterNames.inc \
SPUGenAsmWriter.inc SPUGenCodeEmitter.inc \
SPUGenRegisterInfo.h.inc SPUGenRegisterInfo.inc \
diff --git a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
index 80693e1..1ed06e3 100644
--- a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
+++ b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
@@ -314,7 +314,7 @@ namespace {
return SelectCode(CurDAG->getLoad(vecVT, dl,
CurDAG->getEntryNode(), CGPoolOffset,
PseudoSourceValue::getConstantPool(), 0,
- false, Alignment).getNode());
+ false, false, Alignment).getNode());
}
/// Select - Convert the specified operand from a target-independent to a
diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp
index aa7f910..b21eb37 100644
--- a/lib/Target/CellSPU/SPUISelLowering.cpp
+++ b/lib/Target/CellSPU/SPUISelLowering.cpp
@@ -25,7 +25,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/Debug.h"
@@ -669,7 +669,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
// Re-emit as a v16i8 vector load
result = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
LN->getSrcValue(), LN->getSrcValueOffset(),
- LN->isVolatile(), 16);
+ LN->isVolatile(), LN->isNonTemporal(), 16);
// Update the chain
the_chain = result.getValue(1);
@@ -820,7 +820,7 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
// Re-emit as a v16i8 vector load
alignLoadVec = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
SN->getSrcValue(), SN->getSrcValueOffset(),
- SN->isVolatile(), 16);
+ SN->isVolatile(), SN->isNonTemporal(), 16);
// Update the chain
the_chain = alignLoadVec.getValue(1);
@@ -861,7 +861,8 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
result = DAG.getStore(the_chain, dl, result, basePtr,
LN->getSrcValue(), LN->getSrcValueOffset(),
- LN->isVolatile(), LN->getAlignment());
+ LN->isVolatile(), LN->isNonTemporal(),
+ LN->getAlignment());
#if 0 && !defined(NDEBUG)
if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
@@ -1086,7 +1087,7 @@ SPUTargetLowering::LowerFormalArguments(SDValue Chain,
// or we're forced to do vararg
int FI = MFI->CreateFixedObject(ObjSize, ArgOffset, true, false);
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
- ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0);
+ ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0, false, false, 0);
ArgOffset += StackSlotSize;
}
@@ -1108,7 +1109,8 @@ SPUTargetLowering::LowerFormalArguments(SDValue Chain,
true, false);
SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
- SDValue Store = DAG.getStore(Chain, dl, ArgVal, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Chain, dl, ArgVal, FIN, NULL, 0,
+ false, false, 0);
Chain = Store.getOperand(0);
MemOps.push_back(Store);
@@ -1140,11 +1142,13 @@ static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
SDValue
SPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // CellSPU target does not yet support tail call optimization.
+ isTailCall = false;
const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
unsigned NumOps = Outs.size();
@@ -1188,7 +1192,8 @@ SPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (ArgRegIdx != NumArgRegs) {
RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
} else {
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
ArgOffset += StackSlotSize;
}
break;
@@ -1197,7 +1202,8 @@ SPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (ArgRegIdx != NumArgRegs) {
RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
} else {
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
ArgOffset += StackSlotSize;
}
break;
@@ -1210,7 +1216,8 @@ SPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (ArgRegIdx != NumArgRegs) {
RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
} else {
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
ArgOffset += StackSlotSize;
}
break;
diff --git a/lib/Target/CellSPU/SPUISelLowering.h b/lib/Target/CellSPU/SPUISelLowering.h
index ab349bb..3c51177 100644
--- a/lib/Target/CellSPU/SPUISelLowering.h
+++ b/lib/Target/CellSPU/SPUISelLowering.h
@@ -158,7 +158,7 @@ namespace llvm {
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/CellSPU/SPUMCAsmInfo.cpp b/lib/Target/CellSPU/SPUMCAsmInfo.cpp
index 03cdb29..5ef3c6b 100644
--- a/lib/Target/CellSPU/SPUMCAsmInfo.cpp
+++ b/lib/Target/CellSPU/SPUMCAsmInfo.cpp
@@ -16,7 +16,6 @@ using namespace llvm;
SPULinuxMCAsmInfo::SPULinuxMCAsmInfo(const Target &T, const StringRef &TT) {
ZeroDirective = "\t.space\t";
- SetDirective = "\t.set";
Data64bitsDirective = "\t.quad\t";
AlignmentIsInBytes = false;
HasLCOMMDirective = true;
@@ -31,7 +30,6 @@ SPULinuxMCAsmInfo::SPULinuxMCAsmInfo(const Target &T, const StringRef &TT) {
HasDotLocAndDotFile = true;
SupportsDebugInformation = true;
- NeedsSet = true;
// Exception handling is not supported on CellSPU (think about it: you only
// have 256K for code+data. Would you support exception handling?)
diff --git a/lib/Target/CellSPU/TargetInfo/Makefile b/lib/Target/CellSPU/TargetInfo/Makefile
index 30ca5cf..9cb6827 100644
--- a/lib/Target/CellSPU/TargetInfo/Makefile
+++ b/lib/Target/CellSPU/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMCellSPUInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index 73272bc..e3f2e9f 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -307,8 +307,6 @@ namespace {
Out << "GlobalValue::DLLExportLinkage"; break;
case GlobalValue::ExternalWeakLinkage:
Out << "GlobalValue::ExternalWeakLinkage"; break;
- case GlobalValue::GhostLinkage:
- Out << "GlobalValue::GhostLinkage"; break;
case GlobalValue::CommonLinkage:
Out << "GlobalValue::CommonLinkage"; break;
}
@@ -346,7 +344,7 @@ namespace {
std::string CppWriter::getCppName(const Type* Ty) {
// First, handle the primitive types .. easy
- if (Ty->isPrimitiveType() || Ty->isInteger()) {
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy()) {
switch (Ty->getTypeID()) {
case Type::VoidTyID: return "Type::getVoidTy(getGlobalContext())";
case Type::IntegerTyID: {
@@ -472,6 +470,7 @@ namespace {
HANDLE_ATTR(Nest);
HANDLE_ATTR(ReadNone);
HANDLE_ATTR(ReadOnly);
+ HANDLE_ATTR(InlineHint);
HANDLE_ATTR(NoInline);
HANDLE_ATTR(AlwaysInline);
HANDLE_ATTR(OptimizeForSize);
@@ -494,7 +493,7 @@ namespace {
bool CppWriter::printTypeInternal(const Type* Ty) {
// We don't print definitions for primitive types
- if (Ty->isPrimitiveType() || Ty->isInteger())
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy())
return false;
// If we already defined this type, we don't need to define it again.
@@ -687,7 +686,7 @@ namespace {
// For primitive types and types already defined, just add a name
TypeMap::const_iterator TNI = TypeNames.find(TI->second);
- if (TI->second->isInteger() || TI->second->isPrimitiveType() ||
+ if (TI->second->isIntegerTy() || TI->second->isPrimitiveType() ||
TNI != TypeNames.end()) {
Out << "mod->addTypeName(\"";
printEscapedString(TI->first);
@@ -2011,7 +2010,7 @@ bool CPPTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
formatted_raw_ostream &o,
CodeGenFileType FileType,
CodeGenOpt::Level OptLevel) {
- if (FileType != TargetMachine::AssemblyFile) return true;
+ if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
PM.add(new CppWriter(o));
return false;
}
diff --git a/lib/Target/CppBackend/Makefile b/lib/Target/CppBackend/Makefile
index 52f2aad..d75f4e8 100644
--- a/lib/Target/CppBackend/Makefile
+++ b/lib/Target/CppBackend/Makefile
@@ -9,8 +9,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMCppBackend
-CXXFLAGS = -fno-rtti
-
DIRS = TargetInfo
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/CppBackend/TargetInfo/Makefile b/lib/Target/CppBackend/TargetInfo/Makefile
index 7e44aab..6e68283 100644
--- a/lib/Target/CppBackend/TargetInfo/Makefile
+++ b/lib/Target/CppBackend/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMCppBackendInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp
index 1bc708e..3330d09 100644
--- a/lib/Target/MSIL/MSILWriter.cpp
+++ b/lib/Target/MSIL/MSILWriter.cpp
@@ -187,7 +187,7 @@ void MSILWriter::printModuleStartup() {
break;
case 1:
Arg1 = F->arg_begin();
- if (Arg1->getType()->isInteger()) {
+ if (Arg1->getType()->isIntegerTy()) {
Out << "\tldloc\targc\n";
Args = getTypeName(Arg1->getType());
BadSig = false;
@@ -195,7 +195,7 @@ void MSILWriter::printModuleStartup() {
break;
case 2:
Arg1 = Arg2 = F->arg_begin(); ++Arg2;
- if (Arg1->getType()->isInteger() &&
+ if (Arg1->getType()->isIntegerTy() &&
Arg2->getType()->getTypeID() == Type::PointerTyID) {
Out << "\tldloc\targc\n\tldloc\targv\n";
Args = getTypeName(Arg1->getType())+","+getTypeName(Arg2->getType());
@@ -207,7 +207,7 @@ void MSILWriter::printModuleStartup() {
}
bool RetVoid = (F->getReturnType()->getTypeID() == Type::VoidTyID);
- if (BadSig || (!F->getReturnType()->isInteger() && !RetVoid)) {
+ if (BadSig || (!F->getReturnType()->isIntegerTy() && !RetVoid)) {
Out << "\tldc.i4.0\n";
} else {
Out << "\tcall\t" << getTypeName(F->getReturnType()) <<
@@ -334,7 +334,7 @@ std::string MSILWriter::getPrimitiveTypeName(const Type* Ty, bool isSigned) {
std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned,
bool isNested) {
- if (Ty->isPrimitiveType() || Ty->isInteger())
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy())
return getPrimitiveTypeName(Ty,isSigned);
// FIXME: "OpaqueType" support
switch (Ty->getTypeID()) {
@@ -1690,7 +1690,7 @@ bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM,
CodeGenFileType FileType,
CodeGenOpt::Level OptLevel)
{
- if (FileType != TargetMachine::AssemblyFile) return true;
+ if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
MSILWriter* Writer = new MSILWriter(o);
PM.add(createGCLoweringPass());
// FIXME: Handle switch through native IL instruction "switch"
diff --git a/lib/Target/MSIL/Makefile b/lib/Target/MSIL/Makefile
index 9fecba5..70eadb3 100644
--- a/lib/Target/MSIL/Makefile
+++ b/lib/Target/MSIL/Makefile
@@ -9,8 +9,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMMSIL
-CXXFLAGS = -fno-rtti
-
DIRS = TargetInfo
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/MSIL/TargetInfo/Makefile b/lib/Target/MSIL/TargetInfo/Makefile
index 710f5a1..30b0950 100644
--- a/lib/Target/MSIL/TargetInfo/Makefile
+++ b/lib/Target/MSIL/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMSILInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
index 6033197..def5fc6 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
@@ -35,24 +35,16 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
-static cl::opt<bool>
-EnableMCInst("enable-msp430-mcinst-printer", cl::Hidden,
- cl::desc("enable experimental mcinst gunk in the msp430 backend"));
-
namespace {
class MSP430AsmPrinter : public AsmPrinter {
public:
MSP430AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *MAI, bool V)
- : AsmPrinter(O, TM, MAI, V) {}
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *MAI)
+ : AsmPrinter(O, TM, Ctx, Streamer, MAI) {}
virtual const char *getPassName() const {
return "MSP430 Assembly Printer";
@@ -76,10 +68,7 @@ namespace {
bool PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNo, unsigned AsmVariant,
const char *ExtraCode);
- void printInstructionThroughMCStreamer(const MachineInstr *MI);
-
- void emitFunctionHeader(const MachineFunction &MF);
- bool runOnMachineFunction(MachineFunction &F);
+ void EmitInstruction(const MachineInstr *MI);
void getAnalysisUsage(AnalysisUsage &AU) const {
AsmPrinter::getAnalysisUsage(AU);
@@ -89,81 +78,11 @@ namespace {
} // end of anonymous namespace
-void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
- const Function *F = MF.getFunction();
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-
- unsigned FnAlign = MF.getAlignment();
- EmitAlignment(FnAlign, F);
-
- switch (F->getLinkage()) {
- default: llvm_unreachable("Unknown linkage type!");
- case Function::InternalLinkage: // Symbols default to internal.
- case Function::PrivateLinkage:
- case Function::LinkerPrivateLinkage:
- break;
- case Function::ExternalLinkage:
- O << "\t.globl\t" << *CurrentFnSym << '\n';
- break;
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- O << "\t.weak\t" << *CurrentFnSym << '\n';
- break;
- }
-
- printVisibility(CurrentFnSym, F->getVisibility());
-
- O << "\t.type\t" << *CurrentFnSym << ",@function\n";
- O << *CurrentFnSym << ":\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.
- EmitBasicBlockStart(I);
-
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II)
- // Print the assembly for the instruction.
- printMachineInstruction(II);
- }
-
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
-
- // We didn't modify anything
- return false;
-}
-
-void MSP430AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
- ++EmittedInsts;
-
- processDebugLoc(MI, true);
-
- printInstructionThroughMCStreamer(MI);
-
- if (VerboseAsm)
- EmitComments(*MI);
- O << '\n';
-
- processDebugLoc(MI, false);
-}
-
void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
const char* Modifier) {
const MachineOperand &MO = MI->getOperand(OpNum);
switch (MO.getType()) {
+ default: assert(0 && "Not implemented yet!");
case MachineOperand::MO_Register:
O << MSP430InstPrinter::getRegisterName(MO.getReg());
return;
@@ -173,7 +92,7 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_GlobalAddress: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
@@ -196,8 +115,6 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << MAI->getGlobalPrefix() << MO.getSymbolName();
return;
}
- default:
- llvm_unreachable("Not implemented yet!");
}
}
@@ -226,30 +143,14 @@ void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
}
void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) {
- unsigned CC = MI->getOperand(OpNum).getImm();
-
- switch (CC) {
- default:
- llvm_unreachable("Unsupported CC code");
- break;
- case MSP430CC::COND_E:
- O << "eq";
- break;
- case MSP430CC::COND_NE:
- O << "ne";
- break;
- case MSP430CC::COND_HS:
- O << "hs";
- break;
- case MSP430CC::COND_LO:
- O << "lo";
- break;
- case MSP430CC::COND_GE:
- O << "ge";
- break;
- case MSP430CC::COND_L:
- O << 'l';
- break;
+ switch (MI->getOperand(OpNum).getImm()) {
+ default: assert(0 && "Unknown cond");
+ case MSP430CC::COND_E: O << "eq"; break;
+ case MSP430CC::COND_NE: O << "ne"; break;
+ case MSP430CC::COND_HS: O << "hs"; break;
+ case MSP430CC::COND_LO: O << "lo"; break;
+ case MSP430CC::COND_GE: O << "ge"; break;
+ case MSP430CC::COND_L: O << 'l'; break;
}
}
@@ -277,32 +178,12 @@ bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
}
//===----------------------------------------------------------------------===//
-void MSP430AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI){
-
+void MSP430AsmPrinter::EmitInstruction(const MachineInstr *MI) {
MSP430MCInstLower MCInstLowering(OutContext, *Mang, *this);
- switch (MI->getOpcode()) {
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
- case TargetInstrInfo::GC_LABEL:
- printLabel(MI);
- return;
- case TargetInstrInfo::KILL:
- printKill(MI);
- return;
- case TargetInstrInfo::INLINEASM:
- printInlineAsm(MI);
- return;
- case TargetInstrInfo::IMPLICIT_DEF:
- printImplicitDef(MI);
- return;
- default: break;
- }
-
MCInst TmpInst;
MCInstLowering.Lower(MI, TmpInst);
-
- printMCInst(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
}
static MCInstPrinter *createMSP430MCInstPrinter(const Target &T,
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
index a480307..f6565bd 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
@@ -25,7 +25,6 @@ using namespace llvm;
// Include the auto-generated portion of the assembly writer.
#define MachineInstr MCInst
-#define NO_ASM_WRITER_BOILERPLATE
#include "MSP430GenAsmWriter.inc"
#undef MachineInstr
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp b/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
index e1f80b7..4eb7f3d 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
@@ -116,7 +116,7 @@ void MSP430MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
- Printer.GetMBBSymbol(MO.getMBB()->getNumber()), Ctx));
+ MO.getMBB()->getSymbol(Printer.OutContext), Ctx));
break;
case MachineOperand::MO_GlobalAddress:
MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
diff --git a/lib/Target/MSP430/AsmPrinter/Makefile b/lib/Target/MSP430/AsmPrinter/Makefile
index c8a44a1..4f340c6 100644
--- a/lib/Target/MSP430/AsmPrinter/Makefile
+++ b/lib/Target/MSP430/AsmPrinter/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMSP430AsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' MSP430 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
index 4eec757..a8c5e0a 100644
--- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
+++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
@@ -133,8 +133,7 @@ namespace {
bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM);
bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM);
- bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const;
+ bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const;
virtual bool
SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
@@ -336,8 +335,8 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
return false;
}
-bool MSP430DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const {
+bool MSP430DAGToDAGISel::IsLegalToFold(SDValue N, SDNode *U,
+ SDNode *Root) const {
if (OptLevel == CodeGenOpt::None) return false;
/// RMW preprocessing creates the following code:
@@ -364,11 +363,11 @@ bool MSP430DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
/// during preprocessing) to determine whether it's legal to introduce such
/// "cycle" for a moment.
DenseMap<SDNode*, SDNode*>::const_iterator I = RMWStores.find(Root);
- if (I != RMWStores.end() && I->second == N)
+ if (I != RMWStores.end() && I->second == N.getNode())
return true;
// Proceed to 'generic' cycle finder code
- return SelectionDAGISel::IsLegalAndProfitableToFold(N, U, Root);
+ return SelectionDAGISel::IsLegalToFold(N, U, Root);
}
@@ -656,7 +655,7 @@ SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op,
unsigned Opc8, unsigned Opc16) {
if (N1.getOpcode() == ISD::LOAD &&
N1.hasOneUse() &&
- IsLegalAndProfitableToFold(N1.getNode(), Op, Op)) {
+ IsLegalToFold(N1, Op, Op)) {
LoadSDNode *LD = cast<LoadSDNode>(N1);
if (!isValidIndexedLoad(LD))
return NULL;
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index b794911..7281b37 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -31,8 +31,8 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -273,11 +273,13 @@ MSP430TargetLowering::LowerFormalArguments(SDValue Chain,
SDValue
MSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // MSP430 target does not yet support tail call optimization.
+ isTailCall = false;
switch (CallConv) {
default:
@@ -369,7 +371,8 @@ MSP430TargetLowering::LowerCCCArguments(SDValue Chain,
//from this parameter
SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
- PseudoSourceValue::getFixedStack(FI), 0));
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0));
}
}
@@ -498,7 +501,7 @@ MSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
PseudoSourceValue::getStack(),
- VA.getLocMemOffset()));
+ VA.getLocMemOffset(), false, false, 0));
}
}
@@ -891,13 +894,13 @@ SDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
DAG.getNode(ISD::ADD, dl, getPointerTy(),
FrameAddr, Offset),
- NULL, 0);
+ NULL, 0, false, false, 0);
}
// Just load the return address.
SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
- RetAddrFI, NULL, 0);
+ RetAddrFI, NULL, 0, false, false, 0);
}
SDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
@@ -909,7 +912,8 @@ SDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
MSP430::FPW, VT);
while (Depth--)
- FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0);
+ FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0,
+ false, false, 0);
return FrameAddr;
}
@@ -969,7 +973,7 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
bool MSP430TargetLowering::isTruncateFree(const Type *Ty1,
const Type *Ty2) const {
- if (!Ty1->isInteger() || !Ty2->isInteger())
+ if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
return false;
return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
@@ -984,7 +988,7 @@ bool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
bool MSP430TargetLowering::isZExtFree(const Type *Ty1, const Type *Ty2) const {
// MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
- return 0 && Ty1->isInteger(8) && Ty2->isInteger(16);
+ return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
}
bool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h
index 6152a05..87a790b 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.h
+++ b/lib/Target/MSP430/MSP430ISelLowering.h
@@ -154,7 +154,7 @@ namespace llvm {
SmallVectorImpl<SDValue> &InVals);
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
- CallingConv::ID CallConv, bool isVarArg, bool isTailCall,
+ CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/MSP430/MSP430InstrInfo.cpp b/lib/Target/MSP430/MSP430InstrInfo.cpp
index 9dc69e0..6372482 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.cpp
+++ b/lib/Target/MSP430/MSP430InstrInfo.cpp
@@ -356,12 +356,12 @@ unsigned MSP430InstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
switch (Desc.getOpcode()) {
default:
assert(0 && "Unknown instruction size!");
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
- case TargetInstrInfo::IMPLICIT_DEF:
- case TargetInstrInfo::KILL:
+ case TargetOpcode::DBG_LABEL:
+ case TargetOpcode::EH_LABEL:
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
return 0;
- case TargetInstrInfo::INLINEASM: {
+ case TargetOpcode::INLINEASM: {
const MachineFunction *MF = MI->getParent()->getParent();
const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
return TII.getInlineAsmLength(MI->getOperand(0).getSymbolName(),
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index cd502cf..bb06f7b 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -285,7 +285,7 @@ def MOV16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
// up to 16 bits.
def def8 : PatLeaf<(i8 GR8:$src), [{
return N->getOpcode() != ISD::TRUNCATE &&
- N->getOpcode() != TargetInstrInfo::EXTRACT_SUBREG &&
+ N->getOpcode() != TargetOpcode::EXTRACT_SUBREG &&
N->getOpcode() != ISD::CopyFromReg;
}]>;
diff --git a/lib/Target/MSP430/MSP430MCAsmInfo.cpp b/lib/Target/MSP430/MSP430MCAsmInfo.cpp
index 516eacb..cfb499d 100644
--- a/lib/Target/MSP430/MSP430MCAsmInfo.cpp
+++ b/lib/Target/MSP430/MSP430MCAsmInfo.cpp
@@ -17,7 +17,6 @@ using namespace llvm;
MSP430MCAsmInfo::MSP430MCAsmInfo(const Target &T, const StringRef &TT) {
PrivateGlobalPrefix = ".L";
WeakRefDirective ="\t.weak\t";
- SetDirective = "\t.set\t";
PCSymbol=".";
CommentString = ";";
diff --git a/lib/Target/MSP430/Makefile b/lib/Target/MSP430/Makefile
index 11195a4..b1f33d6 100644
--- a/lib/Target/MSP430/Makefile
+++ b/lib/Target/MSP430/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMMSP430CodeGen
TARGET = MSP430
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = MSP430GenRegisterInfo.h.inc MSP430GenRegisterNames.inc \
diff --git a/lib/Target/MSP430/TargetInfo/Makefile b/lib/Target/MSP430/TargetInfo/Makefile
index d17fa7b..abb08f2 100644
--- a/lib/Target/MSP430/TargetInfo/Makefile
+++ b/lib/Target/MSP430/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMSP430Info
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Makefile b/lib/Target/Makefile
index 281d58b..50a360f 100644
--- a/lib/Target/Makefile
+++ b/lib/Target/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../..
LIBRARYNAME = LLVMTarget
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
# We include this early so we can access the value of TARGETS_TO_BUILD as the
# value for PARALLEL_DIRS which must be set before Makefile.rules is included
diff --git a/lib/Target/Mips/AsmPrinter/Makefile b/lib/Target/Mips/AsmPrinter/Makefile
index aed801e..a2fecf4 100644
--- a/lib/Target/Mips/AsmPrinter/Makefile
+++ b/lib/Target/Mips/AsmPrinter/Makefile
@@ -9,7 +9,6 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMMipsAsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' Mips target directory to grab
# private headers
diff --git a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
index 9af9bd8..b8641c3 100644
--- a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
@@ -37,7 +37,6 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
@@ -46,15 +45,14 @@
#include <cctype>
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
namespace {
class MipsAsmPrinter : public AsmPrinter {
const MipsSubtarget *Subtarget;
public:
explicit MipsAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V)
- : AsmPrinter(O, TM, T, V) {
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+ : AsmPrinter(O, TM, Ctx, Streamer, T) {
Subtarget = &TM.getSubtarget<MipsSubtarget>();
}
@@ -70,18 +68,22 @@ namespace {
const char *Modifier = 0);
void printFCCOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
- void printSavedRegsBitmask(MachineFunction &MF);
+ void printSavedRegsBitmask();
void printHex32(unsigned int Value);
const char *emitCurrentABIString();
- void emitFunctionStart(MachineFunction &MF);
- void emitFunctionEnd(MachineFunction &MF);
- void emitFrameDirective(MachineFunction &MF);
+ void emitFrameDirective();
void printInstruction(const MachineInstr *MI); // autogenerated.
+ void EmitInstruction(const MachineInstr *MI) {
+ printInstruction(MI);
+ OutStreamer.AddBlankLine();
+ }
+ virtual void EmitFunctionBodyStart();
+ virtual void EmitFunctionBodyEnd();
static const char *getRegisterName(unsigned RegNo);
- bool runOnMachineFunction(MachineFunction &F);
+ virtual void EmitFunctionEntryLabel();
void EmitStartOfAsmFile(Module &M);
};
} // end of anonymous namespace
@@ -125,18 +127,16 @@ namespace {
// Create a bitmask with all callee saved registers for CPU or Floating Point
// registers. For CPU registers consider RA, GP and FP for saving if necessary.
-void MipsAsmPrinter::
-printSavedRegsBitmask(MachineFunction &MF)
-{
+void MipsAsmPrinter::printSavedRegsBitmask() {
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
- MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
+ const MipsFunctionInfo *MipsFI = MF->getInfo<MipsFunctionInfo>();
// CPU and FPU Saved Registers Bitmasks
unsigned int CPUBitmask = 0;
unsigned int FPUBitmask = 0;
// Set the CPU and FPU Bitmasks
- MachineFrameInfo *MFI = MF.getFrameInfo();
+ const MachineFrameInfo *MFI = MF->getFrameInfo();
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned RegNum = MipsRegisterInfo::getRegisterNumbering(CSI[i].getReg());
@@ -147,11 +147,11 @@ printSavedRegsBitmask(MachineFunction &MF)
}
// Return Address and Frame registers must also be set in CPUBitmask.
- if (RI.hasFP(MF))
+ if (RI.hasFP(*MF))
CPUBitmask |= (1 << MipsRegisterInfo::
- getRegisterNumbering(RI.getFrameRegister(MF)));
+ getRegisterNumbering(RI.getFrameRegister(*MF)));
- if (MF.getFrameInfo()->hasCalls())
+ if (MFI->hasCalls())
CPUBitmask |= (1 << MipsRegisterInfo::
getRegisterNumbering(RI.getRARegister()));
@@ -178,12 +178,12 @@ printHex32(unsigned int Value)
//===----------------------------------------------------------------------===//
/// Frame Directive
-void MipsAsmPrinter::emitFrameDirective(MachineFunction &MF) {
+void MipsAsmPrinter::emitFrameDirective() {
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
- unsigned stackReg = RI.getFrameRegister(MF);
+ unsigned stackReg = RI.getFrameRegister(*MF);
unsigned returnReg = RI.getRARegister();
- unsigned stackSize = MF.getFrameInfo()->getStackSize();
+ unsigned stackSize = MF->getFrameInfo()->getStackSize();
O << "\t.frame\t" << '$' << LowercaseString(getRegisterName(stackReg))
@@ -207,96 +207,30 @@ const char *MipsAsmPrinter::emitCurrentABIString() {
return NULL;
}
-/// Emit the directives used by GAS on the start of functions
-void MipsAsmPrinter::emitFunctionStart(MachineFunction &MF) {
- // Print out the label for the function.
- const Function *F = MF.getFunction();
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-
- // 2 bits aligned
- EmitAlignment(MF.getAlignment(), F);
-
- O << "\t.globl\t" << *CurrentFnSym << '\n';
+void MipsAsmPrinter::EmitFunctionEntryLabel() {
O << "\t.ent\t" << *CurrentFnSym << '\n';
+ OutStreamer.EmitLabel(CurrentFnSym);
+}
- printVisibility(CurrentFnSym, F->getVisibility());
-
- if ((MAI->hasDotTypeDotSizeDirective()) && Subtarget->isLinux())
- O << "\t.type\t" << *CurrentFnSym << ", @function\n";
-
- O << *CurrentFnSym << ":\n";
-
- emitFrameDirective(MF);
- printSavedRegsBitmask(MF);
-
- O << '\n';
+/// EmitFunctionBodyStart - Targets can override this to emit stuff before
+/// the first basic block in the function.
+void MipsAsmPrinter::EmitFunctionBodyStart() {
+ emitFrameDirective();
+ printSavedRegsBitmask();
}
-/// Emit the directives used by GAS on the end of functions
-void MipsAsmPrinter::emitFunctionEnd(MachineFunction &MF) {
+/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
+/// the last basic block in the function.
+void MipsAsmPrinter::EmitFunctionBodyEnd() {
// There are instruction for this macros, but they must
// always be at the function end, and we can't emit and
// break with BB logic.
O << "\t.set\tmacro\n";
O << "\t.set\treorder\n";
-
+
O << "\t.end\t" << *CurrentFnSym << '\n';
- if (MAI->hasDotTypeDotSizeDirective() && !Subtarget->isLinux())
- O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
}
-/// runOnMachineFunction - This uses the printMachineInstruction()
-/// method to print assembly for each instruction.
-bool MipsAsmPrinter::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);
-
- O << "\n\n";
-
- // Emit the function start directives
- emitFunctionStart(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()) {
- EmitBasicBlockStart(I);
- }
-
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II) {
- processDebugLoc(II, true);
-
- // Print the assembly for the instruction.
- printInstruction(II);
-
- if (VerboseAsm)
- EmitComments(*II);
- O << '\n';
-
- processDebugLoc(II, false);
- ++EmittedInsts;
- }
-
- // Each Basic Block is separated by a newline
- O << '\n';
- }
-
- // Emit function end directives
- emitFunctionEnd(MF);
-
- // We didn't modify anything.
- return false;
-}
// Print out an operand for an inline asm expression.
bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
@@ -343,7 +277,7 @@ void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
break;
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_GlobalAddress:
diff --git a/lib/Target/Mips/Makefile b/lib/Target/Mips/Makefile
index 4e4d874..2ed8d77 100644
--- a/lib/Target/Mips/Makefile
+++ b/lib/Target/Mips/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMMipsCodeGen
TARGET = Mips
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = MipsGenRegisterInfo.h.inc MipsGenRegisterNames.inc \
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index e3a45d2..f1d4a67 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -245,7 +245,7 @@ SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDNode *N) {
// lwc $f1, X+4($3)
SDNode *LD0 = CurDAG->getMachineNode(Mips::LWC1, dl, MVT::f32,
MVT::Other, Offset0, Base, Chain);
- SDValue Undef = SDValue(CurDAG->getMachineNode(TargetInstrInfo::IMPLICIT_DEF,
+ SDValue Undef = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, NVT), 0);
SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPEVEN, dl,
MVT::f64, Undef, SDValue(LD0, 0));
@@ -426,7 +426,7 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
SDValue InFlag = SDValue(MulNode, 0);
- if (MulOp == ISD::MUL)
+ if (Opcode == ISD::MUL)
return CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32, InFlag);
else
return CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag);
@@ -464,8 +464,7 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
Mips::ZERO, MVT::i32);
SDValue Undef = SDValue(
- CurDAG->getMachineNode(
- TargetInstrInfo::IMPLICIT_DEF, dl, MVT::f64), 0);
+ CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::f64), 0);
SDNode *MTC = CurDAG->getMachineNode(Mips::MTC1, dl, MVT::f32, Zero);
SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPEVEN, dl,
MVT::f64, Undef, SDValue(MTC, 0));
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index ced8b93..584b887 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -60,9 +60,6 @@ MipsTargetLowering(MipsTargetMachine &TM)
// setcc operations results (slt, sgt, ...).
setBooleanContents(ZeroOrOneBooleanContent);
- // JumpTable targets must use GOT when using PIC_
- setUsesGlobalOffsetTable(true);
-
// Set up the register classes
addRegisterClass(MVT::i32, Mips::CPURegsRegisterClass);
addRegisterClass(MVT::f32, Mips::FGR32RegisterClass);
@@ -100,6 +97,8 @@ MipsTargetLowering(MipsTargetMachine &TM)
setOperationAction(ISD::BRCOND, MVT::Other, Custom);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+ setOperationAction(ISD::VASTART, MVT::Other, Custom);
+
// We custom lower AND/OR to handle the case where the DAG contain 'ands/ors'
// with operands comming from setcc fp comparions. This is necessary since
@@ -182,6 +181,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG)
case ISD::OR: return LowerANDOR(Op, DAG);
case ISD::SELECT: return LowerSELECT(Op, DAG);
case ISD::SETCC: return LowerSETCC(Op, DAG);
+ case ISD::VASTART: return LowerVASTART(Op, DAG);
}
return SDValue();
}
@@ -510,7 +510,8 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32, 0,
MipsII::MO_GOT);
SDValue ResNode = DAG.getLoad(MVT::i32, dl,
- DAG.getEntryNode(), GA, NULL, 0);
+ DAG.getEntryNode(), GA, NULL, 0,
+ false, false, 0);
// On functions and global targets not internal linked only
// a load from got/GP is necessary for PIC to work.
if (!GV->hasLocalLinkage() || isa<Function>(GV))
@@ -549,7 +550,8 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG)
SDValue Ops[] = { JTI };
HiPart = DAG.getNode(MipsISD::Hi, dl, DAG.getVTList(MVT::i32), Ops, 1);
} else // Emit Load from Global Pointer
- HiPart = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), JTI, NULL, 0);
+ HiPart = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), JTI, NULL, 0,
+ false, false, 0);
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, JTI);
ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo);
@@ -586,7 +588,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG)
SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
N->getOffset(), MipsII::MO_GOT);
SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(),
- CP, NULL, 0);
+ CP, NULL, 0, false, false, 0);
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CP);
ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, Load, Lo);
}
@@ -594,6 +596,17 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG)
return ResNode;
}
+SDValue MipsTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) {
+ DebugLoc dl = Op.getDebugLoc();
+ SDValue FI = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
+
+ // vastart just stores the address of the VarArgsFrameIndex slot into the
+ // memory location argument.
+ const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
+ return DAG.getStore(Op.getOperand(0), dl, FI, Op.getOperand(1), SV, 0,
+ false, false, 0);
+}
+
//===----------------------------------------------------------------------===//
// Calling Convention Implementation
//===----------------------------------------------------------------------===//
@@ -679,21 +692,86 @@ static bool CC_MipsO32(unsigned ValNo, EVT ValVT,
return false; // CC must always match
}
+static bool CC_MipsO32_VarArgs(unsigned ValNo, EVT ValVT,
+ EVT LocVT, CCValAssign::LocInfo LocInfo,
+ ISD::ArgFlagsTy ArgFlags, CCState &State) {
+
+ static const unsigned IntRegsSize=4;
+
+ static const unsigned IntRegs[] = {
+ Mips::A0, Mips::A1, Mips::A2, Mips::A3
+ };
+
+ // Promote i8 and i16
+ if (LocVT == MVT::i8 || LocVT == MVT::i16) {
+ LocVT = MVT::i32;
+ if (ArgFlags.isSExt())
+ LocInfo = CCValAssign::SExt;
+ else if (ArgFlags.isZExt())
+ LocInfo = CCValAssign::ZExt;
+ else
+ LocInfo = CCValAssign::AExt;
+ }
+
+ if (ValVT == MVT::i32 || ValVT == MVT::f32) {
+ if (unsigned Reg = State.AllocateReg(IntRegs, IntRegsSize)) {
+ State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, MVT::i32, LocInfo));
+ return false;
+ }
+ unsigned Off = State.AllocateStack(4, 4);
+ State.addLoc(CCValAssign::getMem(ValNo, ValVT, Off, LocVT, LocInfo));
+ return false;
+ }
+
+ unsigned UnallocIntReg = State.getFirstUnallocated(IntRegs, IntRegsSize);
+ if (ValVT == MVT::f64) {
+ if (IntRegs[UnallocIntReg] == (unsigned (Mips::A1))) {
+ // A1 can't be used anymore, because 64 bit arguments
+ // must be aligned when copied back to the caller stack
+ State.AllocateReg(IntRegs, IntRegsSize);
+ UnallocIntReg++;
+ }
+
+ if (IntRegs[UnallocIntReg] == (unsigned (Mips::A0)) ||
+ IntRegs[UnallocIntReg] == (unsigned (Mips::A2))) {
+ unsigned Reg = State.AllocateReg(IntRegs, IntRegsSize);
+ State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, MVT::i32, LocInfo));
+ // Shadow the next register so it can be used
+ // later to get the other 32bit part.
+ State.AllocateReg(IntRegs, IntRegsSize);
+ return false;
+ }
+
+ // Register is shadowed to preserve alignment, and the
+ // argument goes to a stack location.
+ if (UnallocIntReg != IntRegsSize)
+ State.AllocateReg(IntRegs, IntRegsSize);
+
+ unsigned Off = State.AllocateStack(8, 8);
+ State.addLoc(CCValAssign::getMem(ValNo, ValVT, Off, LocVT, LocInfo));
+ return false;
+ }
+
+ return true; // CC didn't match
+}
+
//===----------------------------------------------------------------------===//
// Call Calling Convention Implementation
//===----------------------------------------------------------------------===//
/// LowerCall - functions arguments are copied from virtual regs to
/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
-/// TODO: isVarArg, isTailCall.
+/// TODO: isTailCall.
SDValue
MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // MIPs target does not yet support tail call optimization.
+ isTailCall = false;
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
@@ -709,7 +787,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (Subtarget->isABI_O32()) {
int VTsize = EVT(MVT::i32).getSizeInBits()/8;
MFI->CreateFixedObject(VTsize, (VTsize*3), true, false);
- CCInfo.AnalyzeCallOperands(Outs, CC_MipsO32);
+ CCInfo.AnalyzeCallOperands(Outs,
+ isVarArg ? CC_MipsO32_VarArgs : CC_MipsO32);
} else
CCInfo.AnalyzeCallOperands(Outs, CC_Mips);
@@ -783,7 +862,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// emit ISD::STORE whichs stores the
// parameter value to a stack Location
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
}
// Transform all store nodes into one single node because all store
@@ -835,11 +915,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
Chain = DAG.getNode(MipsISD::JmpLink, dl, NodeTys, &Ops[0], Ops.size());
InFlag = Chain.getValue(1);
- // Create the CALLSEQ_END node.
- Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true),
- DAG.getIntPtrConstant(0, true), InFlag);
- InFlag = Chain.getValue(1);
-
// Create a stack location to hold GP when PIC is used. This stack
// location is used on function prologue to save GP and also after all
// emited CALL's to restore GP.
@@ -862,13 +937,19 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// Reload GP value.
FI = MipsFI->getGPFI();
SDValue FIN = DAG.getFrameIndex(FI,getPointerTy());
- SDValue GPLoad = DAG.getLoad(MVT::i32, dl, Chain, FIN, NULL, 0);
+ SDValue GPLoad = DAG.getLoad(MVT::i32, dl, Chain, FIN, NULL, 0,
+ false, false, 0);
Chain = GPLoad.getValue(1);
Chain = DAG.getCopyToReg(Chain, dl, DAG.getRegister(Mips::GP, MVT::i32),
GPLoad, SDValue(0,0));
InFlag = Chain.getValue(1);
}
+ // Create the CALLSEQ_END node.
+ Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true),
+ DAG.getIntPtrConstant(0, true), InFlag);
+ InFlag = Chain.getValue(1);
+
// Handle result values, copying them out of physregs into vregs that we
// return.
return LowerCallResult(Chain, InFlag, CallConv, isVarArg,
@@ -906,23 +987,28 @@ MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
// Formal Arguments Calling Convention Implementation
//===----------------------------------------------------------------------===//
-/// LowerFormalArguments - transform physical registers into
-/// virtual registers and generate load operations for
-/// arguments places on the stack.
-/// TODO: isVarArg
+/// LowerFormalArguments - transform physical registers into virtual registers
+/// and generate load operations for arguments places on the stack.
SDValue
MipsTargetLowering::LowerFormalArguments(SDValue Chain,
- CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg>
- &Ins,
- DebugLoc dl, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &InVals) {
+ CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg>
+ &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF);
+ VarArgsFrameIndex = 0;
+
+ // Used with vargs to acumulate store chains.
+ std::vector<SDValue> OutChains;
+
+ // Keep track of the last register used for arguments
+ unsigned ArgRegEnd = 0;
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -930,7 +1016,8 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
ArgLocs, *DAG.getContext());
if (Subtarget->isABI_O32())
- CCInfo.AnalyzeFormalArguments(Ins, CC_MipsO32);
+ CCInfo.AnalyzeFormalArguments(Ins,
+ isVarArg ? CC_MipsO32_VarArgs : CC_MipsO32);
else
CCInfo.AnalyzeFormalArguments(Ins, CC_Mips);
@@ -944,6 +1031,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
// Arguments stored on registers
if (VA.isRegLoc()) {
EVT RegVT = VA.getLocVT();
+ ArgRegEnd = VA.getLocReg();
TargetRegisterClass *RC = 0;
if (RegVT == MVT::i32)
@@ -954,11 +1042,11 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
if (!Subtarget->isSingleFloat())
RC = Mips::AFGR64RegisterClass;
} else
- llvm_unreachable("RegVT not supported by LowerFormalArguments Lowering");
+ llvm_unreachable("RegVT not supported by FormalArguments Lowering");
// Transform the arguments stored on
// physical registers into virtual ones
- unsigned Reg = AddLiveIn(DAG.getMachineFunction(), VA.getLocReg(), RC);
+ unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgRegEnd, RC);
SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
// If this is an 8 or 16-bit value, it has been passed promoted
@@ -991,34 +1079,13 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
}
InVals.push_back(ArgValue);
-
- // To meet ABI, when VARARGS are passed on registers, the registers
- // must have their values written to the caller stack frame.
- if ((isVarArg) && (Subtarget->isABI_O32())) {
- if (StackPtr.getNode() == 0)
- StackPtr = DAG.getRegister(StackReg, getPointerTy());
-
- // The stack pointer offset is relative to the caller stack frame.
- // Since the real stack size is unknown here, a negative SPOffset
- // is used so there's a way to adjust these offsets when the stack
- // size get known (on EliminateFrameIndex). A dummy SPOffset is
- // used instead of a direct negative address (which is recorded to
- // be used on emitPrologue) to avoid mis-calc of the first stack
- // offset on PEI::calculateFrameObjectOffsets.
- // Arguments are always 32-bit.
- int FI = MFI->CreateFixedObject(4, 0, true, false);
- MipsFI->recordStoreVarArgsFI(FI, -(4+(i*4)));
- SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy());
-
- // emit ISD::STORE whichs stores the
- // parameter value to a stack Location
- InVals.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, NULL, 0));
- }
-
} else { // VA.isRegLoc()
// sanity check
assert(VA.isMemLoc());
+
+ // The last argument is not a register anymore
+ ArgRegEnd = 0;
// The stack pointer offset is relative to the caller stack frame.
// Since the real stack size is unknown here, a negative SPOffset
@@ -1035,7 +1102,8 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
// Create load nodes to retrieve arguments from the stack
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
- InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0));
+ InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0,
+ false, false, 0));
}
}
@@ -1052,6 +1120,42 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
}
+ // To meet ABI, when VARARGS are passed on registers, the registers
+ // must have their values written to the caller stack frame. If the last
+ // argument was placed in the stack, there's no need to save any register.
+ if ((isVarArg) && (Subtarget->isABI_O32() && ArgRegEnd)) {
+ if (StackPtr.getNode() == 0)
+ StackPtr = DAG.getRegister(StackReg, getPointerTy());
+
+ // The last register argument that must be saved is Mips::A3
+ TargetRegisterClass *RC = Mips::CPURegsRegisterClass;
+ unsigned StackLoc = ArgLocs.size()-1;
+
+ for (++ArgRegEnd; ArgRegEnd <= Mips::A3; ++ArgRegEnd, ++StackLoc) {
+ unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgRegEnd, RC);
+ SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, MVT::i32);
+
+ int FI = MFI->CreateFixedObject(4, 0, true, false);
+ MipsFI->recordStoreVarArgsFI(FI, -(4+(StackLoc*4)));
+ SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy());
+ OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, NULL, 0,
+ false, false, 0));
+
+ // Record the frame index of the first variable argument
+ // which is a value necessary to VASTART.
+ if (!VarArgsFrameIndex)
+ VarArgsFrameIndex = FI;
+ }
+ }
+
+ // All stores are grouped in one node to allow the matching between
+ // the size of Ins and InVals. This only happens when on varg functions
+ if (!OutChains.empty()) {
+ OutChains.push_back(Chain);
+ Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
+ &OutChains[0], OutChains.size());
+ }
+
return Chain;
}
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h
index cacf4b5..7256617 100644
--- a/lib/Target/Mips/MipsISelLowering.h
+++ b/lib/Target/Mips/MipsISelLowering.h
@@ -68,6 +68,8 @@ namespace llvm {
//===--------------------------------------------------------------------===//
class MipsTargetLowering : public TargetLowering {
+ int VarArgsFrameIndex; // FrameIndex for start of varargs area.
+
public:
explicit MipsTargetLowering(MipsTargetMachine &TM);
@@ -107,6 +109,7 @@ namespace llvm {
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG);
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG);
virtual SDValue
LowerFormalArguments(SDValue Chain,
@@ -118,7 +121,7 @@ namespace llvm {
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td
index ce89cfd..fa4518d 100644
--- a/lib/Target/Mips/MipsInstrFPU.td
+++ b/lib/Target/Mips/MipsInstrFPU.td
@@ -113,7 +113,6 @@ let ft = 0 in {
defm ROUND_W : FFR1_1<0b001100, "round.w">;
defm TRUNC_W : FFR1_1<0b001101, "trunc.w">;
defm CVTW : FFR1_1<0b100100, "cvt.w">;
- defm FMOV : FFR1_1<0b000110, "mov">;
defm FABS : FFR1_2<0b000101, "abs", fabs>;
defm FNEG : FFR1_2<0b000111, "neg", fneg>;
@@ -173,6 +172,11 @@ let fd = 0 in {
"mtc1 $rt, $fs", []>;
}
+def FMOV_S32 : FFR<0x11, 0b000110, 0x0, (outs FGR32:$fd), (ins FGR32:$fs),
+ "mov.s $fd, $fs", []>;
+def FMOV_D32 : FFR<0x11, 0b000110, 0x1, (outs AFGR64:$fd), (ins AFGR64:$fs),
+ "mov.d $fd, $fs", []>;
+
/// Floating Point Memory Instructions
let Predicates = [IsNotSingleFloat, IsNotMipsI] in {
def LDC1 : FFI<0b110101, (outs AFGR64:$ft), (ins mem:$addr),
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index e67bcbf..f16a805 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -120,7 +120,7 @@ def immZExt5 : PatLeaf<(imm), [{
// Mips Address Mode! SDNode frameindex could possibily be a match
// since load and store instructions from stack used it.
-def addr : ComplexPattern<i32, 2, "SelectAddr", [frameindex], []>;
+def addr : ComplexPattern<iPTR, 2, "SelectAddr", [frameindex], []>;
//===----------------------------------------------------------------------===//
// Instructions specific format
diff --git a/lib/Target/Mips/MipsMCAsmInfo.cpp b/lib/Target/Mips/MipsMCAsmInfo.cpp
index 60ef1c9..89e3e11 100644
--- a/lib/Target/Mips/MipsMCAsmInfo.cpp
+++ b/lib/Target/Mips/MipsMCAsmInfo.cpp
@@ -16,12 +16,12 @@ using namespace llvm;
MipsMCAsmInfo::MipsMCAsmInfo(const Target &T, const StringRef &TT) {
AlignmentIsInBytes = false;
- COMMDirectiveTakesAlignment = true;
Data16bitsDirective = "\t.half\t";
Data32bitsDirective = "\t.word\t";
Data64bitsDirective = 0;
PrivateGlobalPrefix = "$";
CommentString = "#";
ZeroDirective = "\t.space\t";
- PICJumpTableDirective = "\t.gpword\t";
+ GPRel32Directive = "\t.gpword\t";
+ HasSetDirective = false;
}
diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp
index 80fd917..f923bed 100644
--- a/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -223,6 +223,8 @@ void MipsRegisterInfo::adjustMipsStackFrame(MachineFunction &MF) const
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
+ unsigned RegSize = Subtarget.isGP32bit() ? 4 : 8;
+ bool HasGP = MipsFI->needGPSaveRestore();
// Min and Max CSI FrameIndex.
int MinCSFI = -1, MaxCSFI = -1;
@@ -248,6 +250,9 @@ void MipsRegisterInfo::adjustMipsStackFrame(MachineFunction &MF) const
for (unsigned i = 0, e = CSI.size(); i != e; ++i)
CalleeSavedAreaSize += MFI->getObjectAlignment(CSI[i].getFrameIdx());
+ unsigned StackOffset = HasGP ? (MipsFI->getGPStackOffset()+RegSize)
+ : (Subtarget.isABI_O32() ? 16 : 0);
+
// Adjust local variables. They should come on the stack right
// after the arguments.
int LastOffsetFI = -1;
@@ -256,7 +261,8 @@ void MipsRegisterInfo::adjustMipsStackFrame(MachineFunction &MF) const
continue;
if (MFI->isDeadObjectIndex(i))
continue;
- unsigned Offset = MFI->getObjectOffset(i) - CalleeSavedAreaSize;
+ unsigned Offset =
+ StackOffset + MFI->getObjectOffset(i) - CalleeSavedAreaSize;
if (LastOffsetFI == -1)
LastOffsetFI = i;
if (Offset > MFI->getObjectOffset(LastOffsetFI))
@@ -265,11 +271,8 @@ void MipsRegisterInfo::adjustMipsStackFrame(MachineFunction &MF) const
}
// Adjust CPU Callee Saved Registers Area. Registers RA and FP must
- // be saved in this CPU Area there is the need. This whole Area must
- // be aligned to the default Stack Alignment requirements.
- unsigned StackOffset = 0;
- unsigned RegSize = Subtarget.isGP32bit() ? 4 : 8;
-
+ // be saved in this CPU Area. This whole area must be aligned to the
+ // default Stack Alignment requirements.
if (LastOffsetFI >= 0)
StackOffset = MFI->getObjectOffset(LastOffsetFI)+
MFI->getObjectSize(LastOffsetFI);
@@ -283,21 +286,26 @@ void MipsRegisterInfo::adjustMipsStackFrame(MachineFunction &MF) const
StackOffset += MFI->getObjectAlignment(CSI[i].getFrameIdx());
}
- if (hasFP(MF)) {
+ // Stack locations for FP and RA. If only one of them is used,
+ // the space must be allocated for both, otherwise no space at all.
+ if (hasFP(MF) || MFI->hasCalls()) {
+ // FP stack location
MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
StackOffset);
MipsFI->setFPStackOffset(StackOffset);
TopCPUSavedRegOff = StackOffset;
StackOffset += RegSize;
- }
- if (MFI->hasCalls()) {
+ // SP stack location
MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
StackOffset);
MipsFI->setRAStackOffset(StackOffset);
- TopCPUSavedRegOff = StackOffset;
StackOffset += RegSize;
+
+ if (MFI->hasCalls())
+ TopCPUSavedRegOff += RegSize;
}
+
StackOffset = ((StackOffset+StackAlign-1)/StackAlign*StackAlign);
// Adjust FPU Callee Saved Registers Area. This Area must be
diff --git a/lib/Target/Mips/MipsTargetObjectFile.h b/lib/Target/Mips/MipsTargetObjectFile.h
index 32e0436..237b160 100644
--- a/lib/Target/Mips/MipsTargetObjectFile.h
+++ b/lib/Target/Mips/MipsTargetObjectFile.h
@@ -10,7 +10,7 @@
#ifndef LLVM_TARGET_MIPS_TARGETOBJECTFILE_H
#define LLVM_TARGET_MIPS_TARGETOBJECTFILE_H
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
namespace llvm {
diff --git a/lib/Target/Mips/TargetInfo/Makefile b/lib/Target/Mips/TargetInfo/Makefile
index f27d49e..32f4e16 100644
--- a/lib/Target/Mips/TargetInfo/Makefile
+++ b/lib/Target/Mips/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMipsInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PIC16/AsmPrinter/Makefile b/lib/Target/PIC16/AsmPrinter/Makefile
index 27c4045..f4db57e 100644
--- a/lib/Target/PIC16/AsmPrinter/Makefile
+++ b/lib/Target/PIC16/AsmPrinter/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPIC16AsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' pic16 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
index 0463596..b015edd 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
@@ -35,21 +35,17 @@ using namespace llvm;
#include "PIC16GenAsmWriter.inc"
PIC16AsmPrinter::PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V)
-: AsmPrinter(O, TM, T, V), DbgInfo(O, T) {
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+: AsmPrinter(O, TM, Ctx, Streamer, T), DbgInfo(O, T) {
PTLI = static_cast<PIC16TargetLowering*>(TM.getTargetLowering());
PMAI = static_cast<const PIC16MCAsmInfo*>(T);
PTOF = (PIC16TargetObjectFile *)&PTLI->getObjFileLowering();
}
-bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
- processDebugLoc(MI, true);
+void PIC16AsmPrinter::EmitInstruction(const MachineInstr *MI) {
printInstruction(MI);
- if (VerboseAsm)
- EmitComments(*MI);
- O << '\n';
- processDebugLoc(MI, false);
- return true;
+ OutStreamer.AddBlankLine();
}
static int getFunctionColor(const Function *F) {
@@ -96,8 +92,6 @@ void PIC16AsmPrinter::ColorAutoSection(const Function *F) {
/// 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);
@@ -112,8 +106,9 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
DbgInfo.BeginFunction(MF);
// Now emit the instructions of function in its code section.
- const MCSection *fCodeSection
- = getObjFileLowering().SectionForCode(CurrentFnSym->getName());
+ const MCSection *fCodeSection =
+ getObjFileLowering().SectionForCode(CurrentFnSym->getName(),
+ PAN::isISR(F->getSection()));
// Start the Code Section.
O << "\n";
@@ -149,7 +144,7 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
// Print the assembly for the instruction.
- printMachineInstruction(II);
+ EmitInstruction(II);
}
}
@@ -211,7 +206,7 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
break;
}
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
default:
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
index 74ab72c..77b6e63 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
@@ -31,7 +31,8 @@ namespace llvm {
class VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
public:
explicit PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V);
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T);
private:
virtual const char *getPassName() const {
return "PIC16 Assembly Printer";
@@ -47,7 +48,7 @@ namespace llvm {
void printInstruction(const MachineInstr *MI); // definition autogenerated.
static const char *getRegisterName(unsigned RegNo);
- bool printMachineInstruction(const MachineInstr *MI);
+ void EmitInstruction(const MachineInstr *MI);
void EmitFunctionDecls (Module &M);
void EmitUndefinedVars (Module &M);
void EmitDefinedVars (Module &M);
diff --git a/lib/Target/PIC16/Makefile b/lib/Target/PIC16/Makefile
index a1dbde5..9e784d1 100644
--- a/lib/Target/PIC16/Makefile
+++ b/lib/Target/PIC16/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMPIC16CodeGen
TARGET = PIC16
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = PIC16GenRegisterInfo.h.inc PIC16GenRegisterNames.inc \
diff --git a/lib/Target/PIC16/PIC16.h b/lib/Target/PIC16/PIC16.h
index e46c9b2..8d067de 100644
--- a/lib/Target/PIC16/PIC16.h
+++ b/lib/Target/PIC16/PIC16.h
@@ -55,9 +55,10 @@ namespace PIC16CC {
// External symbol names require memory to live till the program end.
// So we have to allocate it and keep.
+ // FIXME: Don't leak the allocated strings.
inline static const char *createESName (const std::string &name) {
char *tmpName = new char[name.size() + 1];
- strcpy (tmpName, name.c_str());
+ memcpy(tmpName, name.c_str(), name.size() + 1);
return tmpName;
}
diff --git a/lib/Target/PIC16/PIC16ABINames.h b/lib/Target/PIC16/PIC16ABINames.h
index e18ddf1..b0b9318 100644
--- a/lib/Target/PIC16/PIC16ABINames.h
+++ b/lib/Target/PIC16/PIC16ABINames.h
@@ -325,6 +325,19 @@ namespace llvm {
return o.str();
}
+
+ // Return true if the current function is an ISR
+ inline static bool isISR(const std::string SectName) {
+ if (SectName.find("interrupt") != std::string::npos)
+ return true;
+
+ return false;
+ }
+
+ // Return the address for ISR starts in rom.
+ inline static std::string getISRAddr(void) {
+ return "0x4";
+ }
}; // class PAN.
} // end namespace llvm;
diff --git a/lib/Target/PIC16/PIC16DebugInfo.cpp b/lib/Target/PIC16/PIC16DebugInfo.cpp
index 8368a3c..c517b1b 100644
--- a/lib/Target/PIC16/PIC16DebugInfo.cpp
+++ b/lib/Target/PIC16/PIC16DebugInfo.cpp
@@ -68,7 +68,7 @@ void PIC16DbgInfo::PopulateDerivedTypeInfo (DIType Ty, unsigned short &TypeNo,
TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
}
- // We also need to encode the the information about the base type of
+ // We also need to encode the information about the base type of
// pointer in TypeNo.
DIType BaseType = DIDerivedType(Ty.getNode()).getTypeDerivedFrom();
PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TagName);
diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp
index 9f093e8..d2fc8db 100644
--- a/lib/Target/PIC16/PIC16ISelLowering.cpp
+++ b/lib/Target/PIC16/PIC16ISelLowering.cpp
@@ -622,12 +622,12 @@ SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) {
ChainHi = Chain.getOperand(1);
}
SDValue Store1 = DAG.getStore(ChainLo, dl, SrcLo, Ptr, NULL,
- 0 + StoreOffset);
+ 0 + StoreOffset, false, false, 0);
Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
DAG.getConstant(4, Ptr.getValueType()));
SDValue Store2 = DAG.getStore(ChainHi, dl, SrcHi, Ptr, NULL,
- 1 + StoreOffset);
+ 1 + StoreOffset, false, false, 0);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1,
Store2);
@@ -1355,11 +1355,13 @@ GetDataAddress(DebugLoc dl, SDValue Callee, SDValue &Chain,
SDValue
PIC16TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // PIC16 target does not yet support tail call optimization.
+ isTailCall = false;
assert(Callee.getValueType() == MVT::i16 &&
"Don't know how to legalize this call node!!!");
@@ -1511,8 +1513,7 @@ bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp,
// Direct load operands are folded in binary operations. But before folding
// verify if this folding is legal. Fold only if it is legal otherwise
// convert this direct load to a separate memory operation.
- if(ISel->IsLegalAndProfitableToFold(Op.getOperand(0).getNode(),
- Op.getNode(), Op.getNode()))
+ if(ISel->IsLegalToFold(Op.getOperand(0), Op.getNode(), Op.getNode()))
return false;
else
MemOp = 0;
diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h
index afdd4b4..de14520 100644
--- a/lib/Target/PIC16/PIC16ISelLowering.h
+++ b/lib/Target/PIC16/PIC16ISelLowering.h
@@ -143,7 +143,7 @@ namespace llvm {
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
- CallingConv::ID CallConv, bool isVarArg, bool isTailCall,
+ CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/PIC16/PIC16MCAsmInfo.cpp b/lib/Target/PIC16/PIC16MCAsmInfo.cpp
index 827315e..b080542 100644
--- a/lib/Target/PIC16/PIC16MCAsmInfo.cpp
+++ b/lib/Target/PIC16/PIC16MCAsmInfo.cpp
@@ -37,7 +37,7 @@ PIC16MCAsmInfo::PIC16MCAsmInfo(const Target &T, const StringRef &TT) {
RomData8bitsDirective = " dw ";
RomData16bitsDirective = " rom_di ";
RomData32bitsDirective = " rom_dl ";
-
+ HasSetDirective = false;
// Set it to false because we weed to generate c file name and not bc file
// name.
diff --git a/lib/Target/PIC16/PIC16MemSelOpt.cpp b/lib/Target/PIC16/PIC16MemSelOpt.cpp
index cc71b04..ab81ed1 100644
--- a/lib/Target/PIC16/PIC16MemSelOpt.cpp
+++ b/lib/Target/PIC16/PIC16MemSelOpt.cpp
@@ -59,6 +59,7 @@ namespace {
const TargetInstrInfo *TII; // Machine instruction info.
MachineBasicBlock *MBB; // Current basic block
std::string CurBank;
+ int PageChanged;
};
char MemSelOpt::ID = 0;
@@ -93,10 +94,56 @@ bool MemSelOpt::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
// Let us assume that when entering a basic block now bank is selected.
// Ideally we should look at the predecessors for this information.
CurBank="";
+ PageChanged=0;
- for (MachineBasicBlock::iterator I = BB.begin(); I != BB.end(); ++I) {
+ MachineBasicBlock::iterator I;
+ for (I = BB.begin(); I != BB.end(); ++I) {
Changed |= processInstruction(I);
+
+ // if the page has changed insert a page sel before
+ // any instruction that needs one
+ if (PageChanged == 1)
+ {
+ // Restore the page if it was changed, before leaving the basic block,
+ // because it may be required by the goto terminator or the fall thru
+ // basic blcok.
+ // If the terminator is return, we don't need to restore since there
+ // is no goto or fall thru basic block.
+ if ((I->getOpcode() == PIC16::sublw_3) || //macro has goto
+ (I->getOpcode() == PIC16::sublw_6) || //macro has goto
+ (I->getOpcode() == PIC16::addlwc) || //macro has goto
+ (TII->get(I->getOpcode()).isBranch()))
+ {
+ DebugLoc dl = I->getDebugLoc();
+ BuildMI(*MBB, I, dl, TII->get(PIC16::pagesel)).addExternalSymbol("$");
+ Changed = true;
+ PageChanged = 0;
+ }
+ }
}
+
+ // The basic block is over, but if we did not find any goto yet,
+ // we haven't restored the page.
+ // Restore the page if it was changed, before leaving the basic block,
+ // because it may be required by fall thru basic blcok.
+ // If the terminator is return, we don't need to restore since there
+ // is fall thru basic block.
+ if (PageChanged == 1) {
+ // save the end pointer before we move back to last insn.
+ MachineBasicBlock::iterator J = I;
+ I--;
+ const TargetInstrDesc &TID = TII->get(I->getOpcode());
+ if (! TID.isReturn())
+ {
+ DebugLoc dl = I->getDebugLoc();
+ BuildMI(*MBB, J, dl,
+ TII->get(PIC16::pagesel)).addExternalSymbol("$");
+ Changed = true;
+ PageChanged = 0;
+ }
+ }
+
+
return Changed;
}
@@ -112,42 +159,74 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
if (!(TID.isBranch() || TID.isCall() || TID.mayLoad() || TID.mayStore()))
return false;
+ // The first thing we should do is that record if banksel/pagesel are
+ // changed in an unknown way. This can happend via any type of call.
+ // We do it here first before scanning of MemOp / BBOp as the indirect
+ // call insns do not have any operands, but they still may change bank/page.
+ if (TID.isCall()) {
+ // Record that we have changed the page, so that we can restore it
+ // before basic block ends.
+ // We require to signal that a page anc bank change happened even for
+ // indirect calls.
+ PageChanged = 1;
+
+ // When a call is made, there may be banksel for variables in callee.
+ // Hence the banksel in caller needs to be reset.
+ CurBank = "";
+ }
+
// Scan for the memory address operand.
// FIXME: Should we use standard interfaces like memoperands_iterator,
// hasMemOperand() etc ?
int MemOpPos = -1;
+ int BBOpPos = -1;
for (unsigned i = 0; i < NumOperands; i++) {
MachineOperand Op = MI->getOperand(i);
if (Op.getType() == MachineOperand::MO_GlobalAddress ||
- Op.getType() == MachineOperand::MO_ExternalSymbol ||
- Op.getType() == MachineOperand::MO_MachineBasicBlock) {
+ Op.getType() == MachineOperand::MO_ExternalSymbol) {
// We found one mem operand. Next one may be BS.
MemOpPos = i;
- break;
+ }
+ if (Op.getType() == MachineOperand::MO_MachineBasicBlock) {
+ // We found one BB operand. Next one may be pagesel.
+ BBOpPos = i;
}
}
// If we did not find an insn accessing memory. Continue.
- if (MemOpPos == -1) return Changed;
+ if ((MemOpPos == -1) &&
+ (BBOpPos == -1))
+ return false;
+ assert ((BBOpPos != MemOpPos) && "operand can only be of one type");
- // Get the MemOp.
- MachineOperand &Op = MI->getOperand(MemOpPos);
// If this is a pagesel material, handle it first.
- if (MI->getOpcode() == PIC16::CALL ||
- MI->getOpcode() == PIC16::br_uncond) {
+ // CALL and br_ucond insns use MemOp (GA or ES) and not BBOp.
+ // Pagesel is required only for a direct call.
+ if ((MI->getOpcode() == PIC16::CALL)) {
+ // Get the BBOp.
+ MachineOperand &MemOp = MI->getOperand(MemOpPos);
DebugLoc dl = MI->getDebugLoc();
- BuildMI(*MBB, MI, dl, TII->get(PIC16::pagesel)).
- addOperand(Op);
- return true;
+ BuildMI(*MBB, MI, dl, TII->get(PIC16::pagesel)).addOperand(MemOp);
+
+ // CALL and br_ucond needs only pagesel. so we are done.
+ return true;
}
+ // Pagesel is handled. Now, add a Banksel if needed.
+ if (MemOpPos == -1) return Changed;
+ // Get the MemOp.
+ MachineOperand &Op = MI->getOperand(MemOpPos);
+
// Get the section name(NewBank) for MemOp.
// This assumes that the section names for globals are already set by
// AsmPrinter->doInitialization.
std::string NewBank = CurBank;
+ bool hasExternalLinkage = false;
if (Op.getType() == MachineOperand::MO_GlobalAddress &&
Op.getGlobal()->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) {
+ if (Op.getGlobal()->hasExternalLinkage())
+ hasExternalLinkage= true;
NewBank = Op.getGlobal()->getSection();
} else if (Op.getType() == MachineOperand::MO_ExternalSymbol) {
// External Symbol is generated for temp data and arguments. They are
@@ -162,7 +241,7 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
// If the previous and new section names are same, we don't need to
// emit banksel.
- if (NewBank.compare(CurBank) != 0 ) {
+ if (NewBank.compare(CurBank) != 0 || hasExternalLinkage) {
DebugLoc dl = MI->getDebugLoc();
BuildMI(*MBB, MI, dl, TII->get(PIC16::banksel)).
addOperand(Op);
diff --git a/lib/Target/PIC16/PIC16Passes/Makefile b/lib/Target/PIC16/PIC16Passes/Makefile
index fb45d71..9684b8d 100644
--- a/lib/Target/PIC16/PIC16Passes/Makefile
+++ b/lib/Target/PIC16/PIC16Passes/Makefile
@@ -10,7 +10,6 @@ LEVEL = ../../../..
TARGET = PIC16
LIBRARYNAME = LLVMpic16passes
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.cpp b/lib/Target/PIC16/PIC16TargetObjectFile.cpp
index d7cfe02..b891c18 100644
--- a/lib/Target/PIC16/PIC16TargetObjectFile.cpp
+++ b/lib/Target/PIC16/PIC16TargetObjectFile.cpp
@@ -315,8 +315,12 @@ PIC16TargetObjectFile::allocateSHARED(const GlobalVariable *GV,
// Interface used by AsmPrinter to get a code section for a function.
const PIC16Section *
-PIC16TargetObjectFile::SectionForCode(const std::string &FnName) const {
+PIC16TargetObjectFile::SectionForCode(const std::string &FnName,
+ bool isISR) const {
const std::string &sec_name = PAN::getCodeSectionName(FnName);
+ // If it is ISR, its code section starts at a specific address.
+ if (isISR)
+ return getPIC16Section(sec_name, CODE, PAN::getISRAddr());
return getPIC16Section(sec_name, CODE);
}
diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.h b/lib/Target/PIC16/PIC16TargetObjectFile.h
index 0b0ad43..cf8bf84 100644
--- a/lib/Target/PIC16/PIC16TargetObjectFile.h
+++ b/lib/Target/PIC16/PIC16TargetObjectFile.h
@@ -137,7 +137,8 @@ namespace llvm {
/// Return a code section for a function.
- const PIC16Section *SectionForCode (const std::string &FnName) const;
+ const PIC16Section *SectionForCode (const std::string &FnName,
+ bool isISR) const;
/// Return a frame section for a function.
const PIC16Section *SectionForFrame (const std::string &FnName) const;
diff --git a/lib/Target/PIC16/TargetInfo/Makefile b/lib/Target/PIC16/TargetInfo/Makefile
index 9004be8..76609f6 100644
--- a/lib/Target/PIC16/TargetInfo/Makefile
+++ b/lib/Target/PIC16/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPIC16Info
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PowerPC/AsmPrinter/Makefile b/lib/Target/PowerPC/AsmPrinter/Makefile
index 4378151..269ef92 100644
--- a/lib/Target/PowerPC/AsmPrinter/Makefile
+++ b/lib/Target/PowerPC/AsmPrinter/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPowerPCAsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' PowerPC target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index b89c2b4..ac901d0 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -31,13 +31,13 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetOptions.h"
@@ -47,14 +47,11 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/SmallString.h"
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
namespace {
class PPCAsmPrinter : public AsmPrinter {
protected:
@@ -63,8 +60,9 @@ namespace {
uint64_t LabelID;
public:
explicit PPCAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V)
- : AsmPrinter(O, TM, T, V),
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+ : AsmPrinter(O, TM, Ctx, Streamer, T),
Subtarget(TM.getSubtarget<PPCSubtarget>()), LabelID(0) {}
virtual const char *getPassName() const {
@@ -98,7 +96,7 @@ namespace {
static const char *getRegisterName(unsigned RegNo);
- void printMachineInstruction(const MachineInstr *MI);
+ virtual void EmitInstruction(const MachineInstr *MI);
void printOp(const MachineOperand &MO);
/// stripRegisterPrefix - This method strips the character prefix from a
@@ -200,7 +198,7 @@ namespace {
if (GV->isDeclaration() || GV->isWeakForLinker()) {
// Dynamically-resolved functions need a stub for the function.
MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
- const MCSymbol *&StubSym =
+ MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
if (StubSym == 0)
StubSym = GetGlobalValueSymbol(GV);
@@ -213,8 +211,8 @@ namespace {
TempNameStr += StringRef(MO.getSymbolName());
TempNameStr += StringRef("$stub");
- const MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
- const MCSymbol *&StubSym =
+ MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
+ MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
if (StubSym == 0)
StubSym = GetExternalSymbolSymbol(MO.getSymbolName());
@@ -319,24 +317,24 @@ namespace {
void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
const char *Modifier);
-
- virtual bool runOnMachineFunction(MachineFunction &F) = 0;
};
/// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
class PPCLinuxAsmPrinter : public PPCAsmPrinter {
public:
explicit PPCLinuxAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V)
- : PPCAsmPrinter(O, TM, T, V){}
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+ : PPCAsmPrinter(O, TM, Ctx, Streamer, T) {}
virtual const char *getPassName() const {
return "Linux PPC Assembly Printer";
}
- bool runOnMachineFunction(MachineFunction &F);
bool doFinalization(Module &M);
+ virtual void EmitFunctionEntryLabel();
+
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineModuleInfo>();
@@ -351,14 +349,14 @@ namespace {
formatted_raw_ostream &OS;
public:
explicit PPCDarwinAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V)
- : PPCAsmPrinter(O, TM, T, V), OS(O) {}
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+ : PPCAsmPrinter(O, TM, Ctx, Streamer, T), OS(O) {}
virtual const char *getPassName() const {
return "Darwin PPC Assembly Printer";
}
- bool runOnMachineFunction(MachineFunction &F);
bool doFinalization(Module &M);
void EmitStartOfAsmFile(Module &M);
@@ -382,7 +380,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
llvm_unreachable("printOp() does not handle immediate values");
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
@@ -403,10 +401,10 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
return;
}
- const MCSymbol *NLPSym =
+ MCSymbol *NLPSym =
OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
MO.getSymbolName()+"$non_lazy_ptr");
- const MCSymbol *&StubSym =
+ MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
if (StubSym == 0)
StubSym = GetExternalSymbolSymbol(MO.getSymbolName());
@@ -424,7 +422,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
(GV->isDeclaration() || GV->isWeakForLinker())) {
if (!GV->hasHiddenVisibility()) {
SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
- const MCSymbol *&StubSym =
+ MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(SymToPrint);
if (StubSym == 0)
StubSym = GetGlobalValueSymbol(GV);
@@ -432,7 +430,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
GV->hasAvailableExternallyLinkage()) {
SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
- const MCSymbol *&StubSym =
+ MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().
getHiddenGVStubEntry(SymToPrint);
if (StubSym == 0)
@@ -535,20 +533,16 @@ void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
}
-/// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
+/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
/// the current output stream.
///
-void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
- ++EmittedInsts;
-
- processDebugLoc(MI, true);
-
+void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Check for slwi/srwi mnemonics.
- bool useSubstituteMnemonic = false;
if (MI->getOpcode() == PPC::RLWINM) {
unsigned char SH = MI->getOperand(2).getImm();
unsigned char MB = MI->getOperand(3).getImm();
unsigned char ME = MI->getOperand(4).getImm();
+ bool useSubstituteMnemonic = false;
if (SH <= 31 && MB == 0 && ME == (31-SH)) {
O << "\tslwi "; useSubstituteMnemonic = true;
}
@@ -561,122 +555,55 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
O << ", ";
printOperand(MI, 1);
O << ", " << (unsigned int)SH;
+ OutStreamer.AddBlankLine();
+ return;
}
- } else if (MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) {
- if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
- useSubstituteMnemonic = true;
- O << "\tmr ";
- printOperand(MI, 0);
- O << ", ";
- printOperand(MI, 1);
- }
- } else if (MI->getOpcode() == PPC::RLDICR) {
+ }
+
+ if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) &&
+ MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
+ O << "\tmr ";
+ printOperand(MI, 0);
+ O << ", ";
+ printOperand(MI, 1);
+ OutStreamer.AddBlankLine();
+ return;
+ }
+
+ if (MI->getOpcode() == PPC::RLDICR) {
unsigned char SH = MI->getOperand(2).getImm();
unsigned char ME = MI->getOperand(3).getImm();
// rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
if (63-SH == ME) {
- useSubstituteMnemonic = true;
O << "\tsldi ";
printOperand(MI, 0);
O << ", ";
printOperand(MI, 1);
O << ", " << (unsigned int)SH;
+ OutStreamer.AddBlankLine();
+ return;
}
}
- if (!useSubstituteMnemonic)
- printInstruction(MI);
-
- if (VerboseAsm)
- EmitComments(*MI);
- O << '\n';
-
- processDebugLoc(MI, false);
+ printInstruction(MI);
+ OutStreamer.AddBlankLine();
}
-/// runOnMachineFunction - This uses the printMachineInstruction()
-/// method to print assembly for each instruction.
-///
-bool PPCLinuxAsmPrinter::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();
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-
- switch (F->getLinkage()) {
- default: llvm_unreachable("Unknown linkage type!");
- case Function::PrivateLinkage:
- case Function::InternalLinkage: // Symbols default to internal.
- break;
- case Function::ExternalLinkage:
- O << "\t.global\t" << *CurrentFnSym << '\n' << "\t.type\t";
- O << *CurrentFnSym << ", @function\n";
- break;
- case Function::LinkerPrivateLinkage:
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- O << "\t.global\t" << *CurrentFnSym << '\n';
- O << "\t.weak\t" << *CurrentFnSym << '\n';
- break;
- }
-
- printVisibility(CurrentFnSym, F->getVisibility());
-
- EmitAlignment(MF.getAlignment(), F);
-
- if (Subtarget.isPPC64()) {
- // Emit an official procedure descriptor.
- // FIXME 64-bit SVR4: Use MCSection here!
- O << "\t.section\t\".opd\",\"aw\"\n";
- O << "\t.align 3\n";
- O << *CurrentFnSym << ":\n";
- O << "\t.quad .L." << *CurrentFnSym << ",.TOC.@tocbase\n";
- O << "\t.previous\n";
- O << ".L." << *CurrentFnSym << ":\n";
- } else {
- O << *CurrentFnSym << ":\n";
- }
-
- // 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()) {
- EmitBasicBlockStart(I);
- }
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II) {
- // Print the assembly for the instruction.
- printMachineInstruction(II);
- }
- }
-
- O << "\t.size\t" << *CurrentFnSym << ",.-" << *CurrentFnSym << '\n';
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-
- // Emit post-function debug information.
- DW->EndFunction(&MF);
-
- // Print out jump tables referenced by the function.
- EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
-
- // We didn't modify anything.
- return false;
+void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
+ if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label.
+ return AsmPrinter::EmitFunctionEntryLabel();
+
+ // Emit an official procedure descriptor.
+ // FIXME 64-bit SVR4: Use MCSection here!
+ O << "\t.section\t\".opd\",\"aw\"\n";
+ O << "\t.align 3\n";
+ OutStreamer.EmitLabel(CurrentFnSym);
+ O << "\t.quad .L." << *CurrentFnSym << ",.TOC.@tocbase\n";
+ O << "\t.previous\n";
+ O << ".L." << *CurrentFnSym << ":\n";
}
+
bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
const TargetData *TD = TM.getTargetData();
@@ -697,81 +624,6 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
return AsmPrinter::doFinalization(M);
}
-/// runOnMachineFunction - This uses the printMachineInstruction()
-/// method to print assembly for each instruction.
-///
-bool PPCDarwinAsmPrinter::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();
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-
- switch (F->getLinkage()) {
- default: llvm_unreachable("Unknown linkage type!");
- case Function::PrivateLinkage:
- case Function::InternalLinkage: // Symbols default to internal.
- break;
- case Function::ExternalLinkage:
- O << "\t.globl\t" << *CurrentFnSym << '\n';
- break;
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- case Function::LinkerPrivateLinkage:
- O << "\t.globl\t" << *CurrentFnSym << '\n';
- O << "\t.weak_definition\t" << *CurrentFnSym << '\n';
- break;
- }
-
- printVisibility(CurrentFnSym, F->getVisibility());
-
- EmitAlignment(MF.getAlignment(), F);
- O << *CurrentFnSym << ":\n";
-
- // Emit pre-function debug information.
- DW->BeginFunction(&MF);
-
- // 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.
- MachineFunction::iterator I = MF.begin();
-
- if (++I == MF.end() && MF.front().empty())
- O << "\tnop\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()) {
- EmitBasicBlockStart(I);
- }
- for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
- II != IE; ++II) {
- // Print the assembly for the instruction.
- printMachineInstruction(II);
- }
- }
-
- // Emit post-function debug information.
- DW->EndFunction(&MF);
-
- // Print out jump tables referenced by the function.
- EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
-
- // We didn't modify anything.
- return false;
-}
-
-
void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
static const char *const CPUDirectives[] = {
"",
@@ -928,9 +780,8 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
for (std::vector<Function *>::const_iterator I = Personalities.begin(),
E = Personalities.end(); I != E; ++I) {
if (*I) {
- const MCSymbol *NLPSym =
- GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
- const MCSymbol *&StubSym = MMIMacho.getGVStubEntry(NLPSym);
+ MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
+ MCSymbol *&StubSym = MMIMacho.getGVStubEntry(NLPSym);
StubSym = GetGlobalValueSymbol(*I);
}
}
@@ -981,13 +832,13 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
///
static AsmPrinter *createPPCAsmPrinterPass(formatted_raw_ostream &o,
TargetMachine &tm,
- const MCAsmInfo *tai,
- bool verbose) {
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *tai) {
const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
if (Subtarget->isDarwin())
- return new PPCDarwinAsmPrinter(o, tm, tai, verbose);
- return new PPCLinuxAsmPrinter(o, tm, tai, verbose);
+ return new PPCDarwinAsmPrinter(o, tm, Ctx, Streamer, tai);
+ return new PPCLinuxAsmPrinter(o, tm, Ctx, Streamer, tai);
}
// Force static initialization.
diff --git a/lib/Target/PowerPC/CMakeLists.txt b/lib/Target/PowerPC/CMakeLists.txt
index bdd6d36..c997c5c 100644
--- a/lib/Target/PowerPC/CMakeLists.txt
+++ b/lib/Target/PowerPC/CMakeLists.txt
@@ -19,7 +19,6 @@ add_llvm_target(PowerPCCodeGen
PPCISelDAGToDAG.cpp
PPCISelLowering.cpp
PPCJITInfo.cpp
- PPCMachOWriterInfo.cpp
PPCMCAsmInfo.cpp
PPCPredicates.cpp
PPCRegisterInfo.cpp
diff --git a/lib/Target/PowerPC/Makefile b/lib/Target/PowerPC/Makefile
index cd30011..1265f1d 100644
--- a/lib/Target/PowerPC/Makefile
+++ b/lib/Target/PowerPC/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMPowerPCCodeGen
TARGET = PPC
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = PPCGenInstrNames.inc PPCGenRegisterNames.inc \
diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h
index 7b98268..67e3a4a 100644
--- a/lib/Target/PowerPC/PPC.h
+++ b/lib/Target/PowerPC/PPC.h
@@ -23,18 +23,12 @@
namespace llvm {
class PPCTargetMachine;
class FunctionPass;
- class MachineCodeEmitter;
- class ObjectCodeEmitter;
class formatted_raw_ostream;
FunctionPass *createPPCBranchSelectionPass();
FunctionPass *createPPCISelDag(PPCTargetMachine &TM);
-FunctionPass *createPPCCodeEmitterPass(PPCTargetMachine &TM,
- MachineCodeEmitter &MCE);
FunctionPass *createPPCJITCodeEmitterPass(PPCTargetMachine &TM,
JITCodeEmitter &MCE);
-FunctionPass *createPPCObjectCodeEmitterPass(PPCTargetMachine &TM,
- ObjectCodeEmitter &OCE);
extern Target ThePPC32Target;
extern Target ThePPC64Target;
diff --git a/lib/Target/PowerPC/PPCCallingConv.td b/lib/Target/PowerPC/PPCCallingConv.td
index c7ce171..155fba2 100644
--- a/lib/Target/PowerPC/PPCCallingConv.td
+++ b/lib/Target/PowerPC/PPCCallingConv.td
@@ -66,28 +66,13 @@ def CC_PPC : CallingConv<[
// PowerPC System V Release 4 ABI
//===----------------------------------------------------------------------===//
-// _Complex arguments are never split, thus their two scalars are either
-// passed both in argument registers or both on the stack. Also _Complex
-// arguments are always passed in general purpose registers, never in
-// Floating-point registers or vector registers. Arguments which should go
-// on the stack are marked with the inreg parameter attribute.
-// Giving inreg this target-dependent (and counter-intuitive) meaning
-// simplifies things, because functions calls are not always coming from the
-// frontend but are also created implicitly e.g. for libcalls. If inreg would
-// actually mean that the argument is passed in a register, then all places
-// which create function calls/function definitions implicitly would need to
-// be aware of this fact and would need to mark arguments accordingly. With
-// inreg meaning that the argument is passed on the stack, this is not an
-// issue, except for calls which involve _Complex types.
-
def CC_PPC_SVR4_Common : CallingConv<[
// The ABI requires i64 to be passed in two adjacent registers with the first
// register having an odd register number.
CCIfType<[i32], CCIfSplit<CCCustom<"CC_PPC_SVR4_Custom_AlignArgRegs">>>,
// The first 8 integer arguments are passed in integer registers.
- CCIfType<[i32], CCIf<"!ArgFlags.isInReg()",
- CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>>,
+ CCIfType<[i32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>,
// Make sure the i64 words from a long double are either both passed in
// registers or both passed on the stack.
diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp
index da9ea36..327470d 100644
--- a/lib/Target/PowerPC/PPCCodeEmitter.cpp
+++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp
@@ -17,26 +17,34 @@
#include "PPC.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
-#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
namespace {
- class PPCCodeEmitter {
+ class PPCCodeEmitter : public MachineFunctionPass {
TargetMachine &TM;
- MachineCodeEmitter &MCE;
+ JITCodeEmitter &MCE;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<MachineModuleInfo>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ static char ID;
+
+ /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record
+ /// its address in the function into this pointer.
+ void *MovePCtoLROffset;
public:
- PPCCodeEmitter(TargetMachine &tm, MachineCodeEmitter &mce):
- TM(tm), MCE(mce) {}
+
+ PPCCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
+ : MachineFunctionPass(&ID), TM(tm), MCE(mce) {}
/// getBinaryCodeForInstr - This function, generated by the
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
@@ -49,27 +57,6 @@ namespace {
unsigned getMachineOpValue(const MachineInstr &MI,
const MachineOperand &MO);
- /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record
- /// its address in the function into this pointer.
-
- void *MovePCtoLROffset;
- };
-
- template <class CodeEmitter>
- class Emitter : public MachineFunctionPass, public PPCCodeEmitter {
- TargetMachine &TM;
- CodeEmitter &MCE;
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<MachineModuleInfo>();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
- public:
- static char ID;
- Emitter(TargetMachine &tm, CodeEmitter &mce)
- : MachineFunctionPass(&ID), PPCCodeEmitter(tm, mce), TM(tm), MCE(mce) {}
-
const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
/// runOnMachineFunction - emits the given MachineFunction to memory
@@ -84,31 +71,18 @@ namespace {
///
unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
};
-
- template <class CodeEmitter>
- char Emitter<CodeEmitter>::ID = 0;
}
+char PPCCodeEmitter::ID = 0;
+
/// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code
/// to the specified MCE object.
-
-FunctionPass *llvm::createPPCCodeEmitterPass(PPCTargetMachine &TM,
- MachineCodeEmitter &MCE) {
- return new Emitter<MachineCodeEmitter>(TM, MCE);
-}
-
FunctionPass *llvm::createPPCJITCodeEmitterPass(PPCTargetMachine &TM,
JITCodeEmitter &JCE) {
- return new Emitter<JITCodeEmitter>(TM, JCE);
-}
-
-FunctionPass *llvm::createPPCObjectCodeEmitterPass(PPCTargetMachine &TM,
- ObjectCodeEmitter &OCE) {
- return new Emitter<ObjectCodeEmitter>(TM, OCE);
+ return new PPCCodeEmitter(TM, JCE);
}
-template <class CodeEmitter>
-bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
+bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
MF.getTarget().getRelocationModel() != Reloc::Static) &&
"JIT relocation model must be set to static or default!");
@@ -124,8 +98,7 @@ bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
return false;
}
-template <class CodeEmitter>
-void Emitter<CodeEmitter>::emitBasicBlock(MachineBasicBlock &MBB) {
+void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
MCE.StartMachineBasicBlock(&MBB);
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
@@ -135,12 +108,12 @@ void Emitter<CodeEmitter>::emitBasicBlock(MachineBasicBlock &MBB) {
default:
MCE.emitWordBE(getBinaryCodeForInstr(MI));
break;
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
+ case TargetOpcode::DBG_LABEL:
+ case TargetOpcode::EH_LABEL:
MCE.emitLabel(MI.getOperand(0).getImm());
break;
- case TargetInstrInfo::IMPLICIT_DEF:
- case TargetInstrInfo::KILL:
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
break; // pseudo opcode, no side effects
case PPC::MovePCtoLR:
case PPC::MovePCtoLR8:
diff --git a/lib/Target/PowerPC/PPCHazardRecognizers.cpp b/lib/Target/PowerPC/PPCHazardRecognizers.cpp
index 6af7e0f..3a15f7e 100644
--- a/lib/Target/PowerPC/PPCHazardRecognizers.cpp
+++ b/lib/Target/PowerPC/PPCHazardRecognizers.cpp
@@ -118,7 +118,7 @@ isLoadOfStoredAddress(unsigned LoadSize, SDValue Ptr1, SDValue Ptr2) const {
}
/// getHazardType - We return hazard for any non-branch instruction that would
-/// terminate terminate the dispatch group. We turn NoopHazard for any
+/// terminate the dispatch group. We turn NoopHazard for any
/// instructions that wouldn't terminate the dispatch group that would cause a
/// pipeline flush.
ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970::
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 32c1879..004997f 100644
--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -199,7 +199,7 @@ void PPCDAGToDAGISel::InsertVRSaveCode(MachineFunction &Fn) {
// Check to see if this function uses vector registers, which means we have to
// save and restore the VRSAVE register and update it with the regs we use.
//
- // In this case, there will be virtual registers of vector type type created
+ // In this case, there will be virtual registers of vector type created
// by the scheduler. Detect them now.
bool HasVectorVReg = false;
for (unsigned i = TargetRegisterInfo::FirstVirtualRegister,
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 8248c94..e73af56 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -25,13 +25,13 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Intrinsics.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -1243,7 +1243,8 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
// If the global is weak or external, we have to go through the lazy
// resolution stub.
- return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Lo, NULL, 0);
+ return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Lo, NULL, 0,
+ false, false, 0);
}
SDValue PPCTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
@@ -1355,7 +1356,8 @@ SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG,
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
- return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
// For the 32-bit SVR4 ABI we follow the layout of the va_list struct.
@@ -1405,25 +1407,29 @@ SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG,
// Store first byte : number of int regs
SDValue firstStore = DAG.getTruncStore(Op.getOperand(0), dl, ArgGPR,
- Op.getOperand(1), SV, 0, MVT::i8);
+ Op.getOperand(1), SV, 0, MVT::i8,
+ false, false, 0);
uint64_t nextOffset = FPROffset;
SDValue nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, Op.getOperand(1),
ConstFPROffset);
// Store second byte : number of float regs
SDValue secondStore =
- DAG.getTruncStore(firstStore, dl, ArgFPR, nextPtr, SV, nextOffset, MVT::i8);
+ DAG.getTruncStore(firstStore, dl, ArgFPR, nextPtr, SV, nextOffset, MVT::i8,
+ false, false, 0);
nextOffset += StackOffset;
nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
// Store second word : arguments given on stack
SDValue thirdStore =
- DAG.getStore(secondStore, dl, StackOffsetFI, nextPtr, SV, nextOffset);
+ DAG.getStore(secondStore, dl, StackOffsetFI, nextPtr, SV, nextOffset,
+ false, false, 0);
nextOffset += FrameOffset;
nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
// Store third word : arguments given in registers
- return DAG.getStore(thirdStore, dl, FR, nextPtr, SV, nextOffset);
+ return DAG.getStore(thirdStore, dl, FR, nextPtr, SV, nextOffset,
+ false, false, 0);
}
@@ -1572,7 +1578,7 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
// Potential tail calls could cause overwriting of argument stack slots.
- bool isImmutable = !(PerformTailCallOpt && (CallConv==CallingConv::Fast));
+ bool isImmutable = !(GuaranteedTailCallOpt && (CallConv==CallingConv::Fast));
unsigned PtrByteSize = 4;
// Assign locations to all of the incoming arguments.
@@ -1628,7 +1634,8 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
// Create load nodes to retrieve arguments from the stack.
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
- InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0));
+ InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0,
+ false, false, 0));
}
}
@@ -1700,7 +1707,8 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
unsigned GPRIndex = 0;
for (; GPRIndex != VarArgsNumGPR; ++GPRIndex) {
SDValue Val = DAG.getRegister(GPArgRegs[GPRIndex], PtrVT);
- SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Increment the address by four for the next argument to store
SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT);
@@ -1714,7 +1722,8 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
unsigned VReg = MF.addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Increment the address by four for the next argument to store
SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT);
@@ -1729,7 +1738,8 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
unsigned FPRIndex = 0;
for (FPRIndex = 0; FPRIndex != VarArgsNumFPR; ++FPRIndex) {
SDValue Val = DAG.getRegister(FPArgRegs[FPRIndex], MVT::f64);
- SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Increment the address by eight for the next argument to store
SDValue PtrOff = DAG.getConstant(EVT(MVT::f64).getSizeInBits()/8,
@@ -1741,7 +1751,8 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
unsigned VReg = MF.addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::f64);
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Increment the address by eight for the next argument to store
SDValue PtrOff = DAG.getConstant(EVT(MVT::f64).getSizeInBits()/8,
@@ -1773,7 +1784,7 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
bool isPPC64 = PtrVT == MVT::i64;
// Potential tail calls could cause overwriting of argument stack slots.
- bool isImmutable = !(PerformTailCallOpt && (CallConv==CallingConv::Fast));
+ bool isImmutable = !(GuaranteedTailCallOpt && (CallConv==CallingConv::Fast));
unsigned PtrByteSize = isPPC64 ? 8 : 4;
unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, true);
@@ -1903,7 +1914,9 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
SDValue Store = DAG.getTruncStore(Val.getValue(1), dl, Val, FIN,
- NULL, 0, ObjSize==1 ? MVT::i8 : MVT::i16 );
+ NULL, 0,
+ ObjSize==1 ? MVT::i8 : MVT::i16,
+ false, false, 0);
MemOps.push_back(Store);
++GPR_idx;
}
@@ -1921,7 +1934,8 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
int FI = MFI->CreateFixedObject(PtrByteSize, ArgOffset, true, false);
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
++GPR_idx;
ArgOffset += PtrByteSize;
@@ -2045,7 +2059,8 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
CurArgOffset + (ArgSize - ObjSize),
isImmutable, false);
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
- ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0);
+ ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0,
+ false, false, 0);
}
InVals.push_back(ArgVal);
@@ -2091,7 +2106,8 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Increment the address by four for the next argument to store
SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT);
@@ -2164,7 +2180,7 @@ CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG,
PPCFrameInfo::getMinCallFrameSize(isPPC64, true));
// Tail call needs the stack to be aligned.
- if (CC==CallingConv::Fast && PerformTailCallOpt) {
+ if (CC==CallingConv::Fast && GuaranteedTailCallOpt) {
unsigned TargetAlign = DAG.getMachineFunction().getTarget().getFrameInfo()->
getStackAlignment();
unsigned AlignMask = TargetAlign-1;
@@ -2200,6 +2216,9 @@ PPCTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
SelectionDAG& DAG) const {
+ if (!GuaranteedTailCallOpt)
+ return false;
+
// Variable argument functions are not supported.
if (isVarArg)
return false;
@@ -2268,7 +2287,7 @@ StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG,
// Store relative to framepointer.
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, FIN,
PseudoSourceValue::getFixedStack(FI),
- 0));
+ 0, false, false, 0));
}
}
@@ -2294,7 +2313,8 @@ static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG,
EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
SDValue NewRetAddrFrIdx = DAG.getFrameIndex(NewRetAddr, VT);
Chain = DAG.getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
- PseudoSourceValue::getFixedStack(NewRetAddr), 0);
+ PseudoSourceValue::getFixedStack(NewRetAddr), 0,
+ false, false, 0);
// When using the 32/64-bit SVR4 ABI there is no need to move the FP stack
// slot as the FP is never overwritten.
@@ -2305,7 +2325,8 @@ static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG,
true, false);
SDValue NewFramePtrIdx = DAG.getFrameIndex(NewFPIdx, VT);
Chain = DAG.getStore(Chain, dl, OldFP, NewFramePtrIdx,
- PseudoSourceValue::getFixedStack(NewFPIdx), 0);
+ PseudoSourceValue::getFixedStack(NewFPIdx), 0,
+ false, false, 0);
}
}
return Chain;
@@ -2343,14 +2364,16 @@ SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(SelectionDAG & DAG,
// Load the LR and FP stack slot for later adjusting.
EVT VT = PPCSubTarget.isPPC64() ? MVT::i64 : MVT::i32;
LROpOut = getReturnAddrFrameIndex(DAG);
- LROpOut = DAG.getLoad(VT, dl, Chain, LROpOut, NULL, 0);
+ LROpOut = DAG.getLoad(VT, dl, Chain, LROpOut, NULL, 0,
+ false, false, 0);
Chain = SDValue(LROpOut.getNode(), 1);
// When using the 32/64-bit SVR4 ABI there is no need to load the FP stack
// slot as the FP is never overwritten.
if (isDarwinABI) {
FPOpOut = getFramePointerFrameIndex(DAG);
- FPOpOut = DAG.getLoad(VT, dl, Chain, FPOpOut, NULL, 0);
+ FPOpOut = DAG.getLoad(VT, dl, Chain, FPOpOut, NULL, 0,
+ false, false, 0);
Chain = SDValue(FPOpOut.getNode(), 1);
}
}
@@ -2392,7 +2415,8 @@ LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain,
PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr,
DAG.getConstant(ArgOffset, PtrVT));
}
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0));
// Calculate and remember argument location.
} else CalculateTailCallArgDest(DAG, MF, isPPC64, Arg, SPDiff, ArgOffset,
TailCallArguments);
@@ -2601,7 +2625,7 @@ PPCTargetLowering::FinishCall(CallingConv::ID CallConv, DebugLoc dl,
// the stack. Account for this here so these bytes can be pushed back on in
// PPCRegisterInfo::eliminateCallFramePseudoInstr.
int BytesCalleePops =
- (CallConv==CallingConv::Fast && PerformTailCallOpt) ? NumBytes : 0;
+ (CallConv==CallingConv::Fast && GuaranteedTailCallOpt) ? NumBytes : 0;
if (InFlag.getNode())
Ops.push_back(InFlag);
@@ -2673,11 +2697,15 @@ PPCTargetLowering::FinishCall(CallingConv::ID CallConv, DebugLoc dl,
SDValue
PPCTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ if (isTailCall)
+ isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg,
+ Ins, DAG);
+
if (PPCSubTarget.isSVR4ABI() && !PPCSubTarget.isPPC64()) {
return LowerCall_SVR4(Chain, Callee, CallConv, isVarArg,
isTailCall, Outs, Ins,
@@ -2700,10 +2728,6 @@ PPCTargetLowering::LowerCall_SVR4(SDValue Chain, SDValue Callee,
// See PPCTargetLowering::LowerFormalArguments_SVR4() for a description
// of the 32-bit SVR4 ABI stack frame layout.
- assert((!isTailCall ||
- (CallConv == CallingConv::Fast && PerformTailCallOpt)) &&
- "IsEligibleForTailCallOptimization missed a case!");
-
assert((CallConv == CallingConv::C ||
CallConv == CallingConv::Fast) && "Unknown calling convention!");
@@ -2717,7 +2741,7 @@ PPCTargetLowering::LowerCall_SVR4(SDValue Chain, SDValue Callee,
// and restoring the callers stack pointer in this functions epilog. This is
// done because by tail calling the called function might overwrite the value
// in this function's (MF) stack pointer stack slot 0(SP).
- if (PerformTailCallOpt && CallConv==CallingConv::Fast)
+ if (GuaranteedTailCallOpt && CallConv==CallingConv::Fast)
MF.getInfo<PPCFunctionInfo>()->setHasFastCall();
// Count how many bytes are to be pushed on the stack, including the linkage
@@ -2859,7 +2883,8 @@ PPCTargetLowering::LowerCall_SVR4(SDValue Chain, SDValue Callee,
PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, PtrOff);
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
- PseudoSourceValue::getStack(), LocMemOffset));
+ PseudoSourceValue::getStack(), LocMemOffset,
+ false, false, 0));
} else {
// Calculate and remember argument location.
CalculateTailCallArgDest(DAG, MF, false, Arg, SPDiff, LocMemOffset,
@@ -2920,7 +2945,7 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
// and restoring the callers stack pointer in this functions epilog. This is
// done because by tail calling the called function might overwrite the value
// in this function's (MF) stack pointer stack slot 0(SP).
- if (PerformTailCallOpt && CallConv==CallingConv::Fast)
+ if (GuaranteedTailCallOpt && CallConv==CallingConv::Fast)
MF.getInfo<PPCFunctionInfo>()->setHasFastCall();
unsigned nAltivecParamsAtEnd = 0;
@@ -3021,7 +3046,7 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
EVT VT = (Size==1) ? MVT::i8 : MVT::i16;
if (GPR_idx != NumGPRs) {
SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, PtrVT, Chain, Arg,
- NULL, 0, VT);
+ NULL, 0, VT, false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
@@ -3058,7 +3083,8 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
SDValue Const = DAG.getConstant(j, PtrOff.getValueType());
SDValue AddArg = DAG.getNode(ISD::ADD, dl, PtrVT, Arg, Const);
if (GPR_idx != NumGPRs) {
- SDValue Load = DAG.getLoad(PtrVT, dl, Chain, AddArg, NULL, 0);
+ SDValue Load = DAG.getLoad(PtrVT, dl, Chain, AddArg, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
ArgOffset += PtrByteSize;
@@ -3089,19 +3115,22 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
RegsToPass.push_back(std::make_pair(FPR[FPR_idx++], Arg));
if (isVarArg) {
- SDValue Store = DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0);
+ SDValue Store = DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Store);
// Float varargs are always shadowed in available integer registers
if (GPR_idx != NumGPRs) {
- SDValue Load = DAG.getLoad(PtrVT, dl, Store, PtrOff, NULL, 0);
+ SDValue Load = DAG.getLoad(PtrVT, dl, Store, PtrOff, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
}
if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64){
SDValue ConstFour = DAG.getConstant(4, PtrOff.getValueType());
PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff, ConstFour);
- SDValue Load = DAG.getLoad(PtrVT, dl, Store, PtrOff, NULL, 0);
+ SDValue Load = DAG.getLoad(PtrVT, dl, Store, PtrOff, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
}
@@ -3144,10 +3173,12 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
// entirely in R registers. Maybe later.
PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr,
DAG.getConstant(ArgOffset, PtrVT));
- SDValue Store = DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0);
+ SDValue Store = DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Store);
if (VR_idx != NumVRs) {
- SDValue Load = DAG.getLoad(MVT::v4f32, dl, Store, PtrOff, NULL, 0);
+ SDValue Load = DAG.getLoad(MVT::v4f32, dl, Store, PtrOff, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(VR[VR_idx++], Load));
}
@@ -3157,7 +3188,8 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
break;
SDValue Ix = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff,
DAG.getConstant(i, PtrVT));
- SDValue Load = DAG.getLoad(PtrVT, dl, Store, Ix, NULL, 0);
+ SDValue Load = DAG.getLoad(PtrVT, dl, Store, Ix, NULL, 0,
+ false, false, 0);
MemOpChains.push_back(Load.getValue(1));
RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
}
@@ -3222,7 +3254,8 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
// TOC save area offset.
SDValue PtrOff = DAG.getIntPtrConstant(40);
SDValue AddPtr = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
- Chain = DAG.getStore(Val.getValue(1), dl, Val, AddPtr, NULL, 0);
+ Chain = DAG.getStore(Val.getValue(1), dl, Val, AddPtr, NULL, 0,
+ false, false, 0);
}
// Build a sequence of copy-to-reg nodes chained together with token chain
@@ -3297,13 +3330,15 @@ SDValue PPCTargetLowering::LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG,
SDValue SaveSP = Op.getOperand(1);
// Load the old link SP.
- SDValue LoadLinkSP = DAG.getLoad(PtrVT, dl, Chain, StackPtr, NULL, 0);
+ SDValue LoadLinkSP = DAG.getLoad(PtrVT, dl, Chain, StackPtr, NULL, 0,
+ false, false, 0);
// Restore the stack pointer.
Chain = DAG.getCopyToReg(LoadLinkSP.getValue(1), dl, SP, SaveSP);
// Store the old link SP.
- return DAG.getStore(Chain, dl, LoadLinkSP, StackPtr, NULL, 0);
+ return DAG.getStore(Chain, dl, LoadLinkSP, StackPtr, NULL, 0,
+ false, false, 0);
}
@@ -3480,14 +3515,16 @@ SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
SDValue FIPtr = DAG.CreateStackTemporary(MVT::f64);
// Emit a store to the stack slot.
- SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl, Tmp, FIPtr, NULL, 0);
+ SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl, Tmp, FIPtr, NULL, 0,
+ false, false, 0);
// Result is a load from the stack slot. If loading 4 bytes, make sure to
// add in a bias.
if (Op.getValueType() == MVT::i32)
FIPtr = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr,
DAG.getConstant(4, FIPtr.getValueType()));
- return DAG.getLoad(Op.getValueType(), dl, Chain, FIPtr, NULL, 0);
+ return DAG.getLoad(Op.getValueType(), dl, Chain, FIPtr, NULL, 0,
+ false, false, 0);
}
SDValue PPCTargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
@@ -3530,7 +3567,7 @@ SDValue PPCTargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
DAG.getMemIntrinsicNode(PPCISD::STD_32, dl, DAG.getVTList(MVT::Other),
Ops, 4, MVT::i64, MMO);
// Load the value as a double.
- SDValue Ld = DAG.getLoad(MVT::f64, dl, Store, FIdx, NULL, 0);
+ SDValue Ld = DAG.getLoad(MVT::f64, dl, Store, FIdx, NULL, 0, false, false, 0);
// FCFID it and return it.
SDValue FP = DAG.getNode(PPCISD::FCFID, dl, MVT::f64, Ld);
@@ -3575,12 +3612,13 @@ SDValue PPCTargetLowering::LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) {
int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8, false);
SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Chain,
- StackSlot, NULL, 0);
+ StackSlot, NULL, 0, false, false, 0);
// Load FP Control Word from low 32 bits of stack slot.
SDValue Four = DAG.getConstant(4, PtrVT);
SDValue Addr = DAG.getNode(ISD::ADD, dl, PtrVT, StackSlot, Four);
- SDValue CWD = DAG.getLoad(MVT::i32, dl, Store, Addr, NULL, 0);
+ SDValue CWD = DAG.getLoad(MVT::i32, dl, Store, Addr, NULL, 0,
+ false, false, 0);
// Transform as necessary
SDValue CWD1 =
@@ -4246,9 +4284,11 @@ SDValue PPCTargetLowering::LowerSCALAR_TO_VECTOR(SDValue Op,
// Store the input value into Value#0 of the stack slot.
SDValue Store = DAG.getStore(DAG.getEntryNode(), dl,
- Op.getOperand(0), FIdx, NULL, 0);
+ Op.getOperand(0), FIdx, NULL, 0,
+ false, false, 0);
// Load it out.
- return DAG.getLoad(Op.getValueType(), dl, Store, FIdx, NULL, 0);
+ return DAG.getLoad(Op.getValueType(), dl, Store, FIdx, NULL, 0,
+ false, false, 0);
}
SDValue PPCTargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) {
@@ -5457,7 +5497,8 @@ SDValue PPCTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
// to the stack.
FuncInfo->setLRStoreRequired();
return DAG.getLoad(getPointerTy(), dl,
- DAG.getEntryNode(), RetAddrFI, NULL, 0);
+ DAG.getEntryNode(), RetAddrFI, NULL, 0,
+ false, false, 0);
}
SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h
index cf81395..9c390ac 100644
--- a/lib/Target/PowerPC/PPCISelLowering.h
+++ b/lib/Target/PowerPC/PPCISelLowering.h
@@ -345,13 +345,6 @@ namespace llvm {
/// the offset of the target addressing mode.
virtual bool isLegalAddressImmediate(GlobalValue *GV) const;
- virtual bool
- IsEligibleForTailCallOptimization(SDValue Callee,
- CallingConv::ID CalleeCC,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- SelectionDAG& DAG) const;
-
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
virtual EVT getOptimalMemOpType(uint64_t Size, unsigned Align,
@@ -365,6 +358,13 @@ namespace llvm {
SDValue getFramePointerFrameIndex(SelectionDAG & DAG) const;
SDValue getReturnAddrFrameIndex(SelectionDAG & DAG) const;
+ bool
+ IsEligibleForTailCallOptimization(SDValue Callee,
+ CallingConv::ID CalleeCC,
+ bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ SelectionDAG& DAG) const;
+
SDValue EmitTailCallLoadFPAndRetAddr(SelectionDAG & DAG,
int SPDiff,
SDValue Chain,
@@ -431,7 +431,7 @@ namespace llvm {
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
- CallingConv::ID CallConv, bool isVarArg, bool isTailCall,
+ CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp
index af7d812..3db623a 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -421,22 +421,30 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF,
FrameIdx));
return true;
} else {
- // FIXME: We use R0 here, because it isn't available for RA. We need to
- // store the CR in the low 4-bits of the saved value. First, issue a MFCR
- // to save all of the CRBits.
- NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFCR), PPC::R0));
+ // FIXME: We need a scatch reg here. The trouble with using R0 is that
+ // it's possible for the stack frame to be so big the save location is
+ // out of range of immediate offsets, necessitating another register.
+ // We hack this on Darwin by reserving R2. It's probably broken on Linux
+ // at the moment.
+
+ // We need to store the CR in the low 4-bits of the saved value. First,
+ // issue a MFCR to save all of the CRBits.
+ unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ?
+ PPC::R2 : PPC::R0;
+ NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFCR), ScratchReg));
// If the saved register wasn't CR0, shift the bits left so that they are
// in CR0's slot.
if (SrcReg != PPC::CR0) {
unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(SrcReg)*4;
- // rlwinm r0, r0, ShiftBits, 0, 31.
- NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), PPC::R0)
- .addReg(PPC::R0).addImm(ShiftBits).addImm(0).addImm(31));
+ // rlwinm scratch, scratch, ShiftBits, 0, 31.
+ NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg)
+ .addReg(ScratchReg).addImm(ShiftBits)
+ .addImm(0).addImm(31));
}
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW))
- .addReg(PPC::R0,
+ .addReg(ScratchReg,
getKillRegState(isKill)),
FrameIdx));
}
@@ -540,20 +548,28 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg),
FrameIdx));
} else if (RC == PPC::CRRCRegisterClass) {
- // FIXME: We use R0 here, because it isn't available for RA.
- NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), PPC::R0),
- FrameIdx));
+ // FIXME: We need a scatch reg here. The trouble with using R0 is that
+ // it's possible for the stack frame to be so big the save location is
+ // out of range of immediate offsets, necessitating another register.
+ // We hack this on Darwin by reserving R2. It's probably broken on Linux
+ // at the moment.
+ unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ?
+ PPC::R2 : PPC::R0;
+ NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ),
+ ScratchReg), FrameIdx));
// If the reloaded register isn't CR0, shift the bits right so that they are
// in the right CR's slot.
if (DestReg != PPC::CR0) {
unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(DestReg)*4;
// rlwinm r11, r11, 32-ShiftBits, 0, 31.
- NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), PPC::R0)
- .addReg(PPC::R0).addImm(32-ShiftBits).addImm(0).addImm(31));
+ NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg)
+ .addReg(ScratchReg).addImm(32-ShiftBits).addImm(0)
+ .addImm(31));
}
- NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg).addReg(PPC::R0));
+ NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg)
+ .addReg(ScratchReg));
} else if (RC == PPC::CRBITRCRegisterClass) {
unsigned Reg = 0;
diff --git a/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
index d2ff3b7..b37aee8 100644
--- a/lib/Target/PowerPC/PPCMCAsmInfo.cpp
+++ b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
@@ -26,6 +26,9 @@ PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) {
}
PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
+ // ".comm align is in bytes but .align is pow-2."
+ AlignmentIsInBytes = false;
+
CommentString = "#";
GlobalPrefix = "";
PrivateGlobalPrefix = ".L";
@@ -49,9 +52,7 @@ PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
AbsoluteEHSectionOffsets = false;
ZeroDirective = "\t.space\t";
- SetDirective = "\t.set";
Data64bitsDirective = is64Bit ? "\t.quad\t" : 0;
- AlignmentIsInBytes = false;
HasLCOMMDirective = true;
AssemblerDialect = 0; // Old-Style mnemonics.
}
diff --git a/lib/Target/PowerPC/PPCMachOWriterInfo.cpp b/lib/Target/PowerPC/PPCMachOWriterInfo.cpp
deleted file mode 100644
index 4c14454..0000000
--- a/lib/Target/PowerPC/PPCMachOWriterInfo.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-//===-- PPCMachOWriterInfo.cpp - Mach-O Writer Info for the PowerPC -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements Mach-O writer information for the PowerPC backend.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PPCMachOWriterInfo.h"
-#include "PPCRelocations.h"
-#include "PPCTargetMachine.h"
-#include "llvm/CodeGen/MachORelocation.h"
-#include "llvm/Support/OutputBuffer.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <cstdio>
-using namespace llvm;
-
-PPCMachOWriterInfo::PPCMachOWriterInfo(const PPCTargetMachine &TM)
- : TargetMachOWriterInfo(TM.getTargetData()->getPointerSizeInBits() == 64 ?
- HDR_CPU_TYPE_POWERPC64 :
- HDR_CPU_TYPE_POWERPC,
- HDR_CPU_SUBTYPE_POWERPC_ALL) {}
-PPCMachOWriterInfo::~PPCMachOWriterInfo() {}
-
-/// GetTargetRelocation - For the MachineRelocation MR, convert it to one or
-/// more PowerPC MachORelocation(s), add the new relocations to the
-/// MachOSection, and rewrite the instruction at the section offset if required
-/// by that relocation type.
-unsigned PPCMachOWriterInfo::GetTargetRelocation(MachineRelocation &MR,
- unsigned FromIdx,
- unsigned ToAddr,
- unsigned ToIdx,
- OutputBuffer &RelocOut,
- OutputBuffer &SecOut,
- bool Scattered,
- bool isExtern) const {
- unsigned NumRelocs = 0;
- uint64_t Addr = 0;
-
- // Get the address of whatever it is we're relocating, if possible.
- if (!isExtern)
- Addr = (uintptr_t)MR.getResultPointer() + ToAddr;
-
- switch ((PPC::RelocationType)MR.getRelocationType()) {
- default: llvm_unreachable("Unknown PPC relocation type!");
- case PPC::reloc_absolute_low_ix:
- llvm_unreachable("Unhandled PPC relocation type!");
- break;
- case PPC::reloc_vanilla:
- {
- // FIXME: need to handle 64 bit vanilla relocs
- MachORelocation VANILLA(MR.getMachineCodeOffset(), ToIdx,
- false, 2, isExtern,
- PPC_RELOC_VANILLA,
- Scattered, (intptr_t)MR.getResultPointer());
- ++NumRelocs;
-
- if (Scattered) {
- RelocOut.outword(VANILLA.getPackedFields());
- RelocOut.outword(VANILLA.getAddress());
- } else {
- RelocOut.outword(VANILLA.getAddress());
- RelocOut.outword(VANILLA.getPackedFields());
- }
-
- intptr_t SymbolOffset;
-
- if (Scattered)
- SymbolOffset = Addr + MR.getConstantVal();
- else
- SymbolOffset = Addr;
-
- printf("vanilla fixup: sec_%x[%x] = %x\n", FromIdx,
- unsigned(MR.getMachineCodeOffset()),
- unsigned(SymbolOffset));
- SecOut.fixword(SymbolOffset, MR.getMachineCodeOffset());
- }
- break;
- case PPC::reloc_pcrel_bx:
- {
- // FIXME: Presumably someday we will need to branch to other, non-extern
- // functions too. Need to figure out some way to distinguish between
- // target is BB and target is function.
- if (isExtern) {
- MachORelocation BR24(MR.getMachineCodeOffset(), ToIdx, true, 2,
- isExtern, PPC_RELOC_BR24, Scattered,
- (intptr_t)MR.getMachineCodeOffset());
- RelocOut.outword(BR24.getAddress());
- RelocOut.outword(BR24.getPackedFields());
- ++NumRelocs;
- }
-
- Addr -= MR.getMachineCodeOffset();
- Addr >>= 2;
- Addr &= 0xFFFFFF;
- Addr <<= 2;
- Addr |= (SecOut[MR.getMachineCodeOffset()] << 24);
- Addr |= (SecOut[MR.getMachineCodeOffset()+3] & 0x3);
- SecOut.fixword(Addr, MR.getMachineCodeOffset());
- break;
- }
- case PPC::reloc_pcrel_bcx:
- {
- Addr -= MR.getMachineCodeOffset();
- Addr &= 0xFFFC;
-
- SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2);
- break;
- }
- case PPC::reloc_absolute_high:
- {
- MachORelocation HA16(MR.getMachineCodeOffset(), ToIdx, false, 2,
- isExtern, PPC_RELOC_HA16);
- MachORelocation PAIR(Addr & 0xFFFF, 0xFFFFFF, false, 2, isExtern,
- PPC_RELOC_PAIR);
- NumRelocs = 2;
-
- RelocOut.outword(HA16.getRawAddress());
- RelocOut.outword(HA16.getPackedFields());
- RelocOut.outword(PAIR.getRawAddress());
- RelocOut.outword(PAIR.getPackedFields());
-
- Addr += 0x8000;
-
- SecOut.fixhalf(Addr >> 16, MR.getMachineCodeOffset() + 2);
- break;
- }
- case PPC::reloc_absolute_low:
- {
- MachORelocation LO16(MR.getMachineCodeOffset(), ToIdx, false, 2,
- isExtern, PPC_RELOC_LO16);
- MachORelocation PAIR(Addr >> 16, 0xFFFFFF, false, 2, isExtern,
- PPC_RELOC_PAIR);
- NumRelocs = 2;
-
- RelocOut.outword(LO16.getRawAddress());
- RelocOut.outword(LO16.getPackedFields());
- RelocOut.outword(PAIR.getRawAddress());
- RelocOut.outword(PAIR.getPackedFields());
-
- SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2);
- break;
- }
- }
-
- return NumRelocs;
-}
diff --git a/lib/Target/PowerPC/PPCMachOWriterInfo.h b/lib/Target/PowerPC/PPCMachOWriterInfo.h
deleted file mode 100644
index d46334d..0000000
--- a/lib/Target/PowerPC/PPCMachOWriterInfo.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===-- PPCMachOWriterInfo.h - Mach-O Writer Info for PowerPC ---*- 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 Mach-O writer information for the PowerPC backend.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef PPC_MACHO_WRITER_INFO_H
-#define PPC_MACHO_WRITER_INFO_H
-
-#include "llvm/Target/TargetMachOWriterInfo.h"
-
-namespace llvm {
-
- // Forward declarations
- class MachineRelocation;
- class OutputBuffer;
- class PPCTargetMachine;
-
- class PPCMachOWriterInfo : public TargetMachOWriterInfo {
- public:
- PPCMachOWriterInfo(const PPCTargetMachine &TM);
- virtual ~PPCMachOWriterInfo();
-
- virtual unsigned GetTargetRelocation(MachineRelocation &MR,
- unsigned FromIdx,
- unsigned ToAddr,
- unsigned ToIdx,
- OutputBuffer &RelocOut,
- OutputBuffer &SecOut,
- bool Scattered, bool Extern) const;
-
- // Constants for the relocation r_type field.
- // See <mach-o/ppc/reloc.h>
- enum {
- PPC_RELOC_VANILLA, // generic relocation
- PPC_RELOC_PAIR, // the second relocation entry of a pair
- PPC_RELOC_BR14, // 14 bit branch displacement to word address
- PPC_RELOC_BR24, // 24 bit branch displacement to word address
- PPC_RELOC_HI16, // a PAIR follows with the low 16 bits
- PPC_RELOC_LO16, // a PAIR follows with the high 16 bits
- PPC_RELOC_HA16, // a PAIR follows, which is sign extended to 32b
- PPC_RELOC_LO14 // LO16 with low 2 bits implicitly zero
- };
- };
-
-} // end llvm namespace
-
-#endif // PPC_MACHO_WRITER_INFO_H
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 0c3c8eb..0b509ac 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -406,7 +406,7 @@ PPCRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
static bool needsFP(const MachineFunction &MF) {
const MachineFrameInfo *MFI = MF.getFrameInfo();
return NoFramePointerElim || MFI->hasVarSizedObjects() ||
- (PerformTailCallOpt && MF.getInfo<PPCFunctionInfo>()->hasFastCall());
+ (GuaranteedTailCallOpt && MF.getInfo<PPCFunctionInfo>()->hasFastCall());
}
static bool spillsCR(const MachineFunction &MF) {
@@ -427,6 +427,12 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
Reserved.set(PPC::R2); // System-reserved register
Reserved.set(PPC::R13); // Small Data Area pointer register
}
+ // Reserve R2 on Darwin to hack around the problem of save/restore of CR
+ // when the stack frame is too big to address directly; we need two regs.
+ // This is a hack.
+ if (Subtarget.isDarwinABI()) {
+ Reserved.set(PPC::R2);
+ }
// On PPC64, r13 is the thread pointer. Never allocate this register.
// Note that this is over conservative, as it also prevents allocation of R31
@@ -447,6 +453,12 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
if (Subtarget.isSVR4ABI()) {
Reserved.set(PPC::X2);
}
+ // Reserve R2 on Darwin to hack around the problem of save/restore of CR
+ // when the stack frame is too big to address directly; we need two regs.
+ // This is a hack.
+ if (Subtarget.isDarwinABI()) {
+ Reserved.set(PPC::X2);
+ }
}
if (needsFP(MF))
@@ -486,7 +498,7 @@ static bool MustSaveLR(const MachineFunction &MF, unsigned LR) {
void PPCRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
- if (PerformTailCallOpt && I->getOpcode() == PPC::ADJCALLSTACKUP) {
+ if (GuaranteedTailCallOpt && I->getOpcode() == PPC::ADJCALLSTACKUP) {
// Add (actually subtract) back the amount the callee popped on return.
if (int CalleeAmt = I->getOperand(1).getImm()) {
bool is64Bit = Subtarget.isPPC64();
@@ -724,7 +736,7 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
}
// Take into account whether it's an add or mem instruction
unsigned OffsetOperandNo = (FIOperandNo == 2) ? 1 : 2;
- if (MI.getOpcode() == TargetInstrInfo::INLINEASM)
+ if (MI.isInlineAsm())
OffsetOperandNo = FIOperandNo-1;
// Get the frame index.
@@ -817,7 +829,7 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
// addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
unsigned OperandBase;
- if (OpC != TargetInstrInfo::INLINEASM) {
+ if (OpC != TargetOpcode::INLINEASM) {
assert(ImmToIdxMap.count(OpC) &&
"No indexed form of load or store available!");
unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
@@ -1050,7 +1062,7 @@ PPCRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
// Reserve stack space to move the linkage area to in case of a tail call.
int TCSPDelta = 0;
- if (PerformTailCallOpt && (TCSPDelta = FI->getTailCallSPDelta()) < 0) {
+ if (GuaranteedTailCallOpt && (TCSPDelta = FI->getTailCallSPDelta()) < 0) {
MF.getFrameInfo()->CreateFixedObject(-1 * TCSPDelta, TCSPDelta,
true, false);
}
@@ -1160,7 +1172,7 @@ PPCRegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF)
// Take into account stack space reserved for tail calls.
int TCSPDelta = 0;
- if (PerformTailCallOpt && (TCSPDelta = PFI->getTailCallSPDelta()) < 0) {
+ if (GuaranteedTailCallOpt && (TCSPDelta = PFI->getTailCallSPDelta()) < 0) {
LowerBound = TCSPDelta;
}
@@ -1575,7 +1587,7 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
// The loaded (or persistent) stack pointer value is offset by the 'stwu'
// on entry to the function. Add this offset back now.
if (!isPPC64) {
- // If this function contained a fastcc call and PerformTailCallOpt is
+ // If this function contained a fastcc call and GuaranteedTailCallOpt is
// enabled (=> hasFastCall()==true) the fastcc call might contain a tail
// call which invalidates the stack pointer value in SP(0). So we use the
// value of R31 in this case.
@@ -1654,7 +1666,7 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
// Callee pop calling convention. Pop parameter/linkage area. Used for tail
// call optimization
- if (PerformTailCallOpt && RetOpcode == PPC::BLR &&
+ if (GuaranteedTailCallOpt && RetOpcode == PPC::BLR &&
MF.getFunction()->getCallingConv() == CallingConv::Fast) {
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
unsigned CallerAllocatedAmt = FI->getMinReservedArea();
diff --git a/lib/Target/PowerPC/PPCSubtarget.cpp b/lib/Target/PowerPC/PPCSubtarget.cpp
index f75e781..40914ba 100644
--- a/lib/Target/PowerPC/PPCSubtarget.cpp
+++ b/lib/Target/PowerPC/PPCSubtarget.cpp
@@ -130,7 +130,7 @@ bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV,
return false;
// If symbol visibility is hidden, the extra load is not needed if
// the symbol is definitely defined in the current translation unit.
- bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
+ bool isDecl = GV->isDeclaration() && !GV->isMaterializable();
if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage())
return false;
return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index c7f7882..cac6962 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -45,7 +45,7 @@ PPCTargetMachine::PPCTargetMachine(const Target &T, const std::string &TT,
Subtarget(TT, FS, is64Bit),
DataLayout(Subtarget.getTargetDataString()), InstrInfo(*this),
FrameInfo(*this, is64Bit), JITInfo(*this, is64Bit), TLInfo(*this),
- InstrItins(Subtarget.getInstrItineraryData()), MachOWriterInfo(*this) {
+ InstrItins(Subtarget.getInstrItineraryData()) {
if (getRelocationModel() == Reloc::Default) {
if (Subtarget.isDarwin())
@@ -91,33 +91,6 @@ bool PPCTargetMachine::addPreEmitPass(PassManagerBase &PM,
bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM,
CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE) {
- // The JIT should use the static relocation model in ppc32 mode, PIC in ppc64.
- // FIXME: This should be moved to TargetJITInfo!!
- if (Subtarget.isPPC64()) {
- // We use PIC codegen in ppc64 mode, because otherwise we'd have to use many
- // instructions to materialize arbitrary global variable + function +
- // constant pool addresses.
- setRelocationModel(Reloc::PIC_);
- // Temporary workaround for the inability of PPC64 JIT to handle jump
- // tables.
- DisableJumpTables = true;
- } else {
- setRelocationModel(Reloc::Static);
- }
-
- // Inform the subtarget that we are in JIT mode. FIXME: does this break macho
- // writing?
- Subtarget.SetJITMode();
-
- // Machine code emitter pass for PowerPC.
- PM.add(createPPCCodeEmitterPass(*this, MCE));
-
- return false;
-}
-
-bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
JITCodeEmitter &JCE) {
// The JIT should use the static relocation model in ppc32 mode, PIC in ppc64.
// FIXME: This should be moved to TargetJITInfo!!
@@ -142,83 +115,3 @@ bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM,
return false;
}
-
-bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE) {
- // The JIT should use the static relocation model in ppc32 mode, PIC in ppc64.
- // FIXME: This should be moved to TargetJITInfo!!
- if (Subtarget.isPPC64()) {
- // We use PIC codegen in ppc64 mode, because otherwise we'd have to use many
- // instructions to materialize arbitrary global variable + function +
- // constant pool addresses.
- setRelocationModel(Reloc::PIC_);
- // Temporary workaround for the inability of PPC64 JIT to handle jump
- // tables.
- DisableJumpTables = true;
- } else {
- setRelocationModel(Reloc::Static);
- }
-
- // Inform the subtarget that we are in JIT mode. FIXME: does this break macho
- // writing?
- Subtarget.SetJITMode();
-
- // Machine code emitter pass for PowerPC.
- PM.add(createPPCObjectCodeEmitterPass(*this, OCE));
-
- return false;
-}
-
-bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE) {
- // Machine code emitter pass for PowerPC.
- PM.add(createPPCCodeEmitterPass(*this, MCE));
- return false;
-}
-
-bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- JITCodeEmitter &JCE) {
- // Machine code emitter pass for PowerPC.
- PM.add(createPPCJITCodeEmitterPass(*this, JCE));
- return false;
-}
-
-bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE) {
- // Machine code emitter pass for PowerPC.
- PM.add(createPPCObjectCodeEmitterPass(*this, OCE));
- return false;
-}
-
-/// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are 4-byte,
-/// 8-byte, and target default. The CIE is hard-coded to indicate that the LSDA
-/// pointer in the FDE section is an "sdata4", and should be encoded as a 4-byte
-/// pointer by default. However, some systems may require a different size due
-/// to bugs or other conditions. We will default to a 4-byte encoding unless the
-/// system tells us otherwise.
-///
-/// The issue is when the CIE says their is an LSDA. That mandates that every
-/// FDE have an LSDA slot. But if the function does not need an LSDA. There
-/// needs to be some way to signify there is none. The LSDA is encoded as
-/// pc-rel. But you don't look for some magic value after adding the pc. You
-/// have to look for a zero before adding the pc. The problem is that the size
-/// of the zero to look for depends on the encoding. The unwinder bug in SL is
-/// that it always checks for a pointer-size zero. So on x86_64 it looks for 8
-/// bytes of zero. If you have an LSDA, it works fine since the 8-bytes are
-/// non-zero so it goes ahead and then reads the value based on the encoding.
-/// But if you use sdata4 and there is no LSDA, then the test for zero gives a
-/// false negative and the unwinder thinks there is an LSDA.
-///
-/// FIXME: This call-back isn't good! We should be using the correct encoding
-/// regardless of the system. However, there are some systems which have bugs
-/// that prevent this from occuring.
-DwarfLSDAEncoding::Encoding PPCTargetMachine::getLSDAEncoding() const {
- if (Subtarget.isDarwin() && Subtarget.getDarwinVers() != 10)
- return DwarfLSDAEncoding::Default;
-
- return DwarfLSDAEncoding::EightByte;
-}
diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h
index 4afcb23..ac9ae2b 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/lib/Target/PowerPC/PPCTargetMachine.h
@@ -19,7 +19,6 @@
#include "PPCJITInfo.h"
#include "PPCInstrInfo.h"
#include "PPCISelLowering.h"
-#include "PPCMachOWriterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
@@ -37,7 +36,6 @@ class PPCTargetMachine : public LLVMTargetMachine {
PPCJITInfo JITInfo;
PPCTargetLowering TLInfo;
InstrItineraryData InstrItins;
- PPCMachOWriterInfo MachOWriterInfo;
public:
PPCTargetMachine(const Target &T, const std::string &TT,
@@ -58,40 +56,12 @@ public:
virtual const InstrItineraryData getInstrItineraryData() const {
return InstrItins;
}
- virtual const PPCMachOWriterInfo *getMachOWriterInfo() const {
- return &MachOWriterInfo;
- }
-
- /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are
- /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that
- /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded
- /// as a 4-byte pointer by default. However, some systems may require a
- /// different size due to bugs or other conditions. We will default to a
- /// 4-byte encoding unless the system tells us otherwise.
- ///
- /// FIXME: This call-back isn't good! We should be using the correct encoding
- /// regardless of the system. However, there are some systems which have bugs
- /// that prevent this from occuring.
- virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const;
// Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE);
- virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
JITCodeEmitter &JCE);
- virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- JITCodeEmitter &JCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE);
virtual bool getEnableTailMergeDefault() const;
};
diff --git a/lib/Target/PowerPC/README.txt b/lib/Target/PowerPC/README.txt
index 060d6a5..e49bda0 100644
--- a/lib/Target/PowerPC/README.txt
+++ b/lib/Target/PowerPC/README.txt
@@ -430,6 +430,35 @@ This theoretically may help improve twolf slightly (used in dimbox.c:142?).
===-------------------------------------------------------------------------===
+PR5945: This:
+define i32 @clamp0g(i32 %a) {
+entry:
+ %cmp = icmp slt i32 %a, 0
+ %sel = select i1 %cmp, i32 0, i32 %a
+ ret i32 %sel
+}
+
+Is compile to this with the PowerPC (32-bit) backend:
+
+_clamp0g:
+ cmpwi cr0, r3, 0
+ li r2, 0
+ blt cr0, LBB1_2
+; BB#1: ; %entry
+ mr r2, r3
+LBB1_2: ; %entry
+ mr r3, r2
+ blr
+
+This could be reduced to the much simpler:
+
+_clamp0g:
+ srawi r2, r3, 31
+ andc r3, r3, r2
+ blr
+
+===-------------------------------------------------------------------------===
+
int foo(int N, int ***W, int **TK, int X) {
int t, i;
@@ -635,6 +664,32 @@ This sort of thing occurs a lot due to globalopt.
===-------------------------------------------------------------------------===
+We compile:
+
+define i32 @bar(i32 %x) nounwind readnone ssp {
+entry:
+ %0 = icmp eq i32 %x, 0 ; <i1> [#uses=1]
+ %neg = sext i1 %0 to i32 ; <i32> [#uses=1]
+ ret i32 %neg
+}
+
+to:
+
+_bar:
+ cntlzw r2, r3
+ slwi r2, r2, 26
+ srawi r3, r2, 31
+ blr
+
+it would be better to produce:
+
+_bar:
+ addic r3,r3,-1
+ subfe r3,r3,r3
+ blr
+
+===-------------------------------------------------------------------------===
+
We currently compile 32-bit bswap:
declare i32 @llvm.bswap.i32(i32 %A)
@@ -840,3 +895,20 @@ define double @test_FNEG_sel(double %A, double %B, double %C) {
ret double %E
}
+//===----------------------------------------------------------------------===//
+The save/restore sequence for CR in prolog/epilog is terrible:
+- Each CR subreg is saved individually, rather than doing one save as a unit.
+- On Darwin, the save is done after the decrement of SP, which means the offset
+from SP of the save slot can be too big for a store instruction, which means we
+need an additional register (currently hacked in 96015+96020; the solution there
+is correct, but poor).
+- On SVR4 the same thing can happen, and I don't think saving before the SP
+decrement is safe on that target, as there is no red zone. This is currently
+broken AFAIK, although it's not a target I can exercise.
+The following demonstrates the problem:
+extern void bar(char *p);
+void foo() {
+ char x[100000];
+ bar(x);
+ __asm__("" ::: "cr2");
+}
diff --git a/lib/Target/PowerPC/TargetInfo/Makefile b/lib/Target/PowerPC/TargetInfo/Makefile
index 16d0167..a101aa4 100644
--- a/lib/Target/PowerPC/TargetInfo/Makefile
+++ b/lib/Target/PowerPC/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPowerPCInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/README.txt b/lib/Target/README.txt
index 080ea42..4fd46a8 100644
--- a/lib/Target/README.txt
+++ b/lib/Target/README.txt
@@ -156,6 +156,45 @@ void f () { /* this can be optimized to four additions... */
This requires reassociating to forms of expressions that are already available,
something that reassoc doesn't think about yet.
+
+//===---------------------------------------------------------------------===//
+
+This function: (derived from GCC PR19988)
+double foo(double x, double y) {
+ return ((x + 0.1234 * y) * (x + -0.1234 * y));
+}
+
+compiles to:
+_foo:
+ movapd %xmm1, %xmm2
+ mulsd LCPI1_1(%rip), %xmm1
+ mulsd LCPI1_0(%rip), %xmm2
+ addsd %xmm0, %xmm1
+ addsd %xmm0, %xmm2
+ movapd %xmm1, %xmm0
+ mulsd %xmm2, %xmm0
+ ret
+
+Reassociate should be able to turn it into:
+
+double foo(double x, double y) {
+ return ((x + 0.1234 * y) * (x - 0.1234 * y));
+}
+
+Which allows the multiply by constant to be CSE'd, producing:
+
+_foo:
+ mulsd LCPI1_0(%rip), %xmm1
+ movapd %xmm1, %xmm2
+ addsd %xmm0, %xmm2
+ subsd %xmm1, %xmm0
+ mulsd %xmm2, %xmm0
+ ret
+
+This doesn't need -ffast-math support at all. This is particularly bad because
+the llvm-gcc frontend is canonicalizing the later into the former, but clang
+doesn't have this problem.
+
//===---------------------------------------------------------------------===//
These two functions should generate the same code on big-endian systems:
@@ -237,24 +276,6 @@ define void @test(i32* %P) {
//===---------------------------------------------------------------------===//
-dag/inst combine "clz(x)>>5 -> x==0" for 32-bit x.
-
-Compile:
-
-int bar(int x)
-{
- int t = __builtin_clz(x);
- return -(t>>5);
-}
-
-to:
-
-_bar: addic r3,r3,-1
- subfe r3,r3,r3
- blr
-
-//===---------------------------------------------------------------------===//
-
quantum_sigma_x in 462.libquantum contains the following loop:
for(i=0; i<reg->size; i++)
@@ -294,6 +315,8 @@ unsigned long reverse(unsigned v) {
//===---------------------------------------------------------------------===//
+[LOOP RECOGNITION]
+
These idioms should be recognized as popcount (see PR1488):
unsigned countbits_slow(unsigned v) {
@@ -356,12 +379,36 @@ this construct.
//===---------------------------------------------------------------------===//
+[LOOP RECOGNITION]
+
viterbi speeds up *significantly* if the various "history" related copy loops
are turned into memcpy calls at the source level. We need a "loops to memcpy"
pass.
//===---------------------------------------------------------------------===//
+[LOOP OPTIMIZATION]
+
+SingleSource/Benchmarks/Misc/dt.c shows several interesting optimization
+opportunities in its double_array_divs_variable function: it needs loop
+interchange, memory promotion (which LICM already does), vectorization and
+variable trip count loop unrolling (since it has a constant trip count). ICC
+apparently produces this very nice code with -ffast-math:
+
+..B1.70: # Preds ..B1.70 ..B1.69
+ mulpd %xmm0, %xmm1 #108.2
+ mulpd %xmm0, %xmm1 #108.2
+ mulpd %xmm0, %xmm1 #108.2
+ mulpd %xmm0, %xmm1 #108.2
+ addl $8, %edx #
+ cmpl $131072, %edx #108.2
+ jb ..B1.70 # Prob 99% #108.2
+
+It would be better to count down to zero, but this is a lot better than what we
+do.
+
+//===---------------------------------------------------------------------===//
+
Consider:
typedef unsigned U32;
@@ -1218,9 +1265,16 @@ store->load.
//===---------------------------------------------------------------------===//
+[ALIAS ANALYSIS]
+
Type based alias analysis:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14705
+We should do better analysis of posix_memalign. At the least it should
+no-capture its pointer argument, at best, we should know that the out-value
+result doesn't point to anything (like malloc). One example of this is in
+SingleSource/Benchmarks/Misc/dt.c
+
//===---------------------------------------------------------------------===//
A/B get pinned to the stack because we turn an if/then into a select instead
@@ -1697,22 +1751,71 @@ from gcc.
Missed instcombine transformation:
define i32 @a(i32 %x) nounwind readnone {
entry:
- %shr = lshr i32 %x, 5 ; <i32> [#uses=1]
- %xor = xor i32 %shr, 67108864 ; <i32> [#uses=1]
- %sub = add i32 %xor, -67108864 ; <i32> [#uses=1]
+ %rem = srem i32 %x, 32
+ %shl = shl i32 1, %rem
+ ret i32 %shl
+}
+
+The srem can be transformed to an and because if x is negative, the shift is
+undefined. Testcase derived from gcc.
+
+//===---------------------------------------------------------------------===//
+
+Missed instcombine/dagcombine transformation:
+define i32 @a(i32 %x, i32 %y) nounwind readnone {
+entry:
+ %mul = mul i32 %y, -8
+ %sub = sub i32 %x, %mul
ret i32 %sub
}
-This function is equivalent to "ashr i32 %x, 5". Testcase derived from gcc.
+Should compile to something like x+y*8, but currently compiles to an
+inefficient result. Testcase derived from gcc.
//===---------------------------------------------------------------------===//
-isSafeToLoadUnconditionally should allow a GEP of a global/alloca with constant
-indicies within the bounds of the allocated object. Reduced example:
+Missed instcombine/dagcombine transformation:
+define void @lshift_lt(i8 zeroext %a) nounwind {
+entry:
+ %conv = zext i8 %a to i32
+ %shl = shl i32 %conv, 3
+ %cmp = icmp ult i32 %shl, 33
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @bar() nounwind
+ ret void
+
+if.end:
+ ret void
+}
+declare void @bar() nounwind
-const int a[] = {3,6};
-int b(int y) { int* x = y ? &a[0] : &a[1]; return *x; }
+The shift should be eliminated. Testcase derived from gcc.
-All the loads should be eliminated. Testcase derived from gcc.
+//===---------------------------------------------------------------------===//
+
+These compile into different code, one gets recognized as a switch and the
+other doesn't due to phase ordering issues (PR6212):
+
+int test1(int mainType, int subType) {
+ if (mainType == 7)
+ subType = 4;
+ else if (mainType == 9)
+ subType = 6;
+ else if (mainType == 11)
+ subType = 9;
+ return subType;
+}
+
+int test2(int mainType, int subType) {
+ if (mainType == 7)
+ subType = 4;
+ if (mainType == 9)
+ subType = 6;
+ if (mainType == 11)
+ subType = 9;
+ return subType;
+}
//===---------------------------------------------------------------------===//
diff --git a/lib/Target/Sparc/AsmPrinter/Makefile b/lib/Target/Sparc/AsmPrinter/Makefile
index 404fad1..a856828 100644
--- a/lib/Target/Sparc/AsmPrinter/Makefile
+++ b/lib/Target/Sparc/AsmPrinter/Makefile
@@ -8,8 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSparcAsmPrinter
-CXXFLAGS = -fno-rtti
-
# Hack: we need to include 'main' Sparc target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
index 8fc4e5a..9a2ce6b 100644
--- a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
@@ -16,45 +16,23 @@
#include "Sparc.h"
#include "SparcInstrInfo.h"
#include "SparcTargetMachine.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/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/MathExtras.h"
-#include <cctype>
-#include <cstring>
-#include <map>
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
namespace {
class SparcAsmPrinter : public AsmPrinter {
- /// We name each basic block in a Function with a unique number, so
- /// that we can consistently refer to them later. This is cleared
- /// at the beginning of each call to runOnMachineFunction().
- ///
- typedef std::map<const Value *, unsigned> ValueMapTy;
- ValueMapTy NumberForBB;
- unsigned BBNumber;
public:
explicit SparcAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V)
- : AsmPrinter(O, TM, T, V), BBNumber(0) {}
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+ : AsmPrinter(O, TM, Ctx, Streamer, T) {}
virtual const char *getPassName() const {
return "Sparc Assembly Printer";
@@ -65,114 +43,24 @@ namespace {
const char *Modifier = 0);
void printCCOperand(const MachineInstr *MI, int opNum);
+ virtual void EmitInstruction(const MachineInstr *MI) {
+ printInstruction(MI);
+ OutStreamer.AddBlankLine();
+ }
void printInstruction(const MachineInstr *MI); // autogenerated.
static const char *getRegisterName(unsigned RegNo);
- bool runOnMachineFunction(MachineFunction &F);
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 emitFunctionHeader(const MachineFunction &MF);
bool printGetPCX(const MachineInstr *MI, unsigned OpNo);
};
} // end of anonymous namespace
#include "SparcGenAsmWriter.inc"
-/// runOnMachineFunction - This uses the printInstruction()
-/// method to print assembly for each instruction.
-///
-bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
- this->MF = &MF;
-
- SetupMachineFunction(MF);
-
- // Print out constants referenced by the function
- EmitConstantPool(MF.getConstantPool());
-
- // BBNumber is used here so that a given Printer will never give two
- // BBs the same name. (If you have a better way, please let me know!)
-
- O << "\n\n";
- emitFunctionHeader(MF);
-
-
- // Emit pre-function debug information.
- DW->BeginFunction(&MF);
-
- // Number each basic block so that we can consistently refer to them
- // in PC-relative references.
- // FIXME: Why not use the MBB numbers?
- NumberForBB.clear();
- for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
- I != E; ++I) {
- NumberForBB[I->getBasicBlock()] = BBNumber++;
- }
-
- // 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()) {
- EmitBasicBlockStart(I);
- }
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II) {
- // Print the assembly for the instruction.
- processDebugLoc(II, true);
- printInstruction(II);
-
- if (VerboseAsm)
- EmitComments(*II);
- O << '\n';
- processDebugLoc(II, false);
- ++EmittedInsts;
- }
- }
-
- // Emit post-function debug information.
- DW->EndFunction(&MF);
-
- // We didn't modify anything.
- O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
- return false;
-}
-
-void SparcAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
- const Function *F = MF.getFunction();
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
- EmitAlignment(MF.getAlignment(), F);
-
- switch (F->getLinkage()) {
- default: llvm_unreachable("Unknown linkage type");
- case Function::PrivateLinkage:
- case Function::InternalLinkage:
- // Function is internal.
- break;
- case Function::DLLExportLinkage:
- case Function::ExternalLinkage:
- // Function is externally visible
- O << "\t.global\t" << *CurrentFnSym << '\n';
- break;
- case Function::LinkerPrivateLinkage:
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- // Function is weak
- O << "\t.weak\t" << *CurrentFnSym << '\n';
- break;
- }
-
- printVisibility(CurrentFnSym, F->getVisibility());
-
- O << "\t.type\t" << *CurrentFnSym << ", #function\n";
- O << *CurrentFnSym << ":\n";
-}
-
-
void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
const MachineOperand &MO = MI->getOperand (opNum);
bool CloseParen = false;
@@ -193,7 +81,7 @@ void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << (int)MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_GlobalAddress:
O << *GetGlobalValueSymbol(MO.getGlobal());
@@ -252,7 +140,7 @@ bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum) {
break;
}
- unsigned bbNum = NumberForBB[MI->getParent()->getBasicBlock()];
+ unsigned bbNum = MI->getParent()->getNumber();
O << '\n' << ".LLGETPCH" << bbNum << ":\n";
O << "\tcall\t.LLGETPC" << bbNum << '\n' ;
@@ -312,4 +200,5 @@ bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
// Force static initialization.
extern "C" void LLVMInitializeSparcAsmPrinter() {
RegisterAsmPrinter<SparcAsmPrinter> X(TheSparcTarget);
+ RegisterAsmPrinter<SparcAsmPrinter> Y(TheSparcV9Target);
}
diff --git a/lib/Target/Sparc/Makefile b/lib/Target/Sparc/Makefile
index d3e2a89..e407848 100644
--- a/lib/Target/Sparc/Makefile
+++ b/lib/Target/Sparc/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMSparcCodeGen
TARGET = Sparc
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = SparcGenRegisterInfo.h.inc SparcGenRegisterNames.inc \
diff --git a/lib/Target/Sparc/Sparc.h b/lib/Target/Sparc/Sparc.h
index bb5155e1..a37920d 100644
--- a/lib/Target/Sparc/Sparc.h
+++ b/lib/Target/Sparc/Sparc.h
@@ -29,6 +29,7 @@ namespace llvm {
FunctionPass *createSparcFPMoverPass(TargetMachine &TM);
extern Target TheSparcTarget;
+ extern Target TheSparcV9Target;
} // end namespace llvm;
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp
index 1b3ca3e..4e93ef0 100644
--- a/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/lib/Target/Sparc/SparcISelLowering.cpp
@@ -21,7 +21,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
@@ -134,7 +134,8 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
SDValue Load;
if (ObjectVT == MVT::i32) {
- Load = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0);
+ Load = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0,
+ false, false, 0);
} else {
ISD::LoadExtType LoadOp = ISD::SEXTLOAD;
@@ -143,7 +144,7 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr,
DAG.getConstant(Offset, MVT::i32));
Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Chain, FIPtr,
- NULL, 0, ObjectVT);
+ NULL, 0, ObjectVT, false, false, 0);
Load = DAG.getNode(ISD::TRUNCATE, dl, ObjectVT, Load);
}
InVals.push_back(Load);
@@ -167,7 +168,8 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset,
true, false);
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
- SDValue Load = DAG.getLoad(MVT::f32, dl, Chain, FIPtr, NULL, 0);
+ SDValue Load = DAG.getLoad(MVT::f32, dl, Chain, FIPtr, NULL, 0,
+ false, false, 0);
InVals.push_back(Load);
}
ArgOffset += 4;
@@ -189,7 +191,8 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset,
true, false);
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
- HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0);
+ HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0,
+ false, false, 0);
}
SDValue LoVal;
@@ -201,7 +204,8 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset+4,
true, false);
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
- LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0);
+ LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0,
+ false, false, 0);
}
// Compose the two halves together into an i64 unit.
@@ -235,7 +239,8 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
true, false);
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
- OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, NULL, 0));
+ OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, NULL, 0,
+ false, false, 0));
ArgOffset += 4;
}
@@ -252,11 +257,13 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
SDValue
SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // Sparc target does not yet support tail call optimization.
+ isTailCall = false;
#if 0
// Analyze operands of the call, assigning locations to each operand.
@@ -337,7 +344,8 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// FIXME: VERIFY THAT 68 IS RIGHT.
SDValue PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset()+68);
PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
- MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+ MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0,
+ false, false, 0));
}
#else
@@ -383,14 +391,17 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// out the parts as integers. Top part goes in a reg.
SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32);
SDValue Store = DAG.getStore(DAG.getEntryNode(), dl,
- Val, StackPtr, NULL, 0);
+ Val, StackPtr, NULL, 0,
+ false, false, 0);
// Sparc is big-endian, so the high part comes first.
- SDValue Hi = DAG.getLoad(MVT::i32, dl, Store, StackPtr, NULL, 0, 0);
+ SDValue Hi = DAG.getLoad(MVT::i32, dl, Store, StackPtr, NULL, 0,
+ false, false, 0);
// Increment the pointer to the other half.
StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
DAG.getIntPtrConstant(4));
// Load the low part.
- SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr, NULL, 0, 0);
+ SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr, NULL, 0,
+ false, false, 0);
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi));
@@ -433,7 +444,8 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
SDValue PtrOff = DAG.getConstant(ArgOffset, MVT::i32);
PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
MemOpChains.push_back(DAG.getStore(Chain, dl, ValToStore,
- PtrOff, NULL, 0));
+ PtrOff, NULL, 0,
+ false, false, 0));
}
ArgOffset += ObjSize;
}
@@ -757,7 +769,7 @@ SDValue SparcTargetLowering::LowerGlobalAddress(SDValue Op,
SDValue AbsAddr = DAG.getNode(ISD::ADD, dl, MVT::i32,
GlobalBase, RelAddr);
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
- AbsAddr, NULL, 0);
+ AbsAddr, NULL, 0, false, false, 0);
}
SDValue SparcTargetLowering::LowerConstantPool(SDValue Op,
@@ -778,7 +790,7 @@ SDValue SparcTargetLowering::LowerConstantPool(SDValue Op,
SDValue AbsAddr = DAG.getNode(ISD::ADD, dl, MVT::i32,
GlobalBase, RelAddr);
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
- AbsAddr, NULL, 0);
+ AbsAddr, NULL, 0, false, false, 0);
}
static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
@@ -870,7 +882,8 @@ static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,
DAG.getConstant(TLI.getVarArgsFrameOffset(),
MVT::i32));
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
- return DAG.getStore(Op.getOperand(0), dl, Offset, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, Offset, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
static SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) {
@@ -880,21 +893,23 @@ static SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) {
SDValue VAListPtr = Node->getOperand(1);
const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
DebugLoc dl = Node->getDebugLoc();
- SDValue VAList = DAG.getLoad(MVT::i32, dl, InChain, VAListPtr, SV, 0);
+ SDValue VAList = DAG.getLoad(MVT::i32, dl, InChain, VAListPtr, SV, 0,
+ false, false, 0);
// Increment the pointer, VAList, to the next vaarg
SDValue NextPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, VAList,
DAG.getConstant(VT.getSizeInBits()/8,
MVT::i32));
// Store the incremented VAList to the legalized pointer
InChain = DAG.getStore(VAList.getValue(1), dl, NextPtr,
- VAListPtr, SV, 0);
+ VAListPtr, SV, 0, false, false, 0);
// Load the actual argument out of the pointer VAList, unless this is an
// f64 load.
if (VT != MVT::f64)
- return DAG.getLoad(VT, dl, InChain, VAList, NULL, 0);
+ return DAG.getLoad(VT, dl, InChain, VAList, NULL, 0, false, false, 0);
// Otherwise, load it as i64, then do a bitconvert.
- SDValue V = DAG.getLoad(MVT::i64, dl, InChain, VAList, NULL, 0);
+ SDValue V = DAG.getLoad(MVT::i64, dl, InChain, VAList, NULL, 0,
+ false, false, 0);
// Bit-Convert the value to f64.
SDValue Ops[2] = {
diff --git a/lib/Target/Sparc/SparcISelLowering.h b/lib/Target/Sparc/SparcISelLowering.h
index 55781be..2ee73c1 100644
--- a/lib/Target/Sparc/SparcISelLowering.h
+++ b/lib/Target/Sparc/SparcISelLowering.h
@@ -87,7 +87,7 @@ namespace llvm {
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/Sparc/SparcMCAsmInfo.cpp b/lib/Target/Sparc/SparcMCAsmInfo.cpp
index b67537c..53a9bde 100644
--- a/lib/Target/Sparc/SparcMCAsmInfo.cpp
+++ b/lib/Target/Sparc/SparcMCAsmInfo.cpp
@@ -21,7 +21,6 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(const Target &T, const StringRef &TT) {
Data64bitsDirective = 0; // .xword is only supported by V9.
ZeroDirective = "\t.skip\t";
CommentString = "!";
- COMMDirectiveTakesAlignment = true;
HasLEB128 = true;
AbsoluteDebugSectionOffsets = true;
SupportsDebugInformation = true;
@@ -30,7 +29,6 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(const Target &T, const StringRef &TT) {
UsesELFSectionDirectiveForBSS = true;
WeakRefDirective = "\t.weak\t";
- SetDirective = "\t.set\t";
PrivateGlobalPrefix = ".L";
}
diff --git a/lib/Target/Sparc/SparcSubtarget.cpp b/lib/Target/Sparc/SparcSubtarget.cpp
index 8a88cc0..ce11af1 100644
--- a/lib/Target/Sparc/SparcSubtarget.cpp
+++ b/lib/Target/Sparc/SparcSubtarget.cpp
@@ -15,29 +15,20 @@
#include "SparcGenSubtarget.inc"
using namespace llvm;
-// FIXME: temporary.
-#include "llvm/Support/CommandLine.h"
-namespace {
- cl::opt<bool> EnableV9("enable-sparc-v9-insts", cl::Hidden,
- cl::desc("Enable V9 instructions in the V8 target"));
-}
-
-SparcSubtarget::SparcSubtarget(const std::string &TT, const std::string &FS) {
- // Set the default features.
- IsV9 = false;
- V8DeprecatedInsts = false;
- IsVIS = false;
+SparcSubtarget::SparcSubtarget(const std::string &TT, const std::string &FS,
+ bool is64Bit) :
+ IsV9(false),
+ V8DeprecatedInsts(false),
+ IsVIS(false),
+ Is64Bit(is64Bit) {
// Determine default and user specified characteristics
- std::string CPU = "generic";
+ const char *CPU = "v8";
+ if (is64Bit) {
+ CPU = "v9";
+ IsV9 = true;
+ }
- // FIXME: autodetect host here!
- CPU = "v9"; // What is a good way to detect V9?
-
// Parse features string.
ParseSubtargetFeatures(FS, CPU);
-
- // Unless explicitly enabled, disable the V9 instructions.
- if (!EnableV9)
- IsV9 = false;
}
diff --git a/lib/Target/Sparc/SparcSubtarget.h b/lib/Target/Sparc/SparcSubtarget.h
index 4377034..cec0ab4 100644
--- a/lib/Target/Sparc/SparcSubtarget.h
+++ b/lib/Target/Sparc/SparcSubtarget.h
@@ -23,8 +23,10 @@ class SparcSubtarget : public TargetSubtarget {
bool IsV9;
bool V8DeprecatedInsts;
bool IsVIS;
+ bool Is64Bit;
+
public:
- SparcSubtarget(const std::string &TT, const std::string &FS);
+ SparcSubtarget(const std::string &TT, const std::string &FS, bool is64bit);
bool isV9() const { return IsV9; }
bool isVIS() const { return IsVIS; }
@@ -34,7 +36,17 @@ public:
/// subtarget options. Definition of function is auto generated by tblgen.
std::string ParseSubtargetFeatures(const std::string &FS,
const std::string &CPU);
-
+
+ bool is64Bit() const { return Is64Bit; }
+ std::string getDataLayout() const {
+ const char *p;
+ if (is64Bit()) {
+ p = "E-p:64:64:64-i64:64:64-f64:64:64-f128:128:128-n32:64";
+ } else {
+ p = "E-p:32:32:32-i64:64:64-f64:64:64-f128:64:64-n32";
+ }
+ return std::string(p);
+ }
};
} // end namespace llvm
diff --git a/lib/Target/Sparc/SparcTargetMachine.cpp b/lib/Target/Sparc/SparcTargetMachine.cpp
index 1eec112..a676623 100644
--- a/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -19,18 +19,22 @@ using namespace llvm;
extern "C" void LLVMInitializeSparcTarget() {
// Register the target.
- RegisterTargetMachine<SparcTargetMachine> X(TheSparcTarget);
- RegisterAsmInfo<SparcELFMCAsmInfo> Y(TheSparcTarget);
+ RegisterTargetMachine<SparcV8TargetMachine> X(TheSparcTarget);
+ RegisterTargetMachine<SparcV9TargetMachine> Y(TheSparcV9Target);
+
+ RegisterAsmInfo<SparcELFMCAsmInfo> A(TheSparcTarget);
+ RegisterAsmInfo<SparcELFMCAsmInfo> B(TheSparcV9Target);
}
/// SparcTargetMachine ctor - Create an ILP32 architecture model
///
SparcTargetMachine::SparcTargetMachine(const Target &T, const std::string &TT,
- const std::string &FS)
+ const std::string &FS, bool is64bit)
: LLVMTargetMachine(T, TT),
- DataLayout("E-p:32:32-f128:128:128-n32"),
- Subtarget(TT, FS), TLInfo(*this), InstrInfo(Subtarget),
+ Subtarget(TT, FS, is64bit),
+ DataLayout(Subtarget.getDataLayout()),
+ TLInfo(*this), InstrInfo(Subtarget),
FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
}
@@ -49,3 +53,15 @@ bool SparcTargetMachine::addPreEmitPass(PassManagerBase &PM,
PM.add(createSparcDelaySlotFillerPass(*this));
return true;
}
+
+SparcV8TargetMachine::SparcV8TargetMachine(const Target &T,
+ const std::string &TT,
+ const std::string &FS)
+ : SparcTargetMachine(T, TT, FS, false) {
+}
+
+SparcV9TargetMachine::SparcV9TargetMachine(const Target &T,
+ const std::string &TT,
+ const std::string &FS)
+ : SparcTargetMachine(T, TT, FS, true) {
+}
diff --git a/lib/Target/Sparc/SparcTargetMachine.h b/lib/Target/Sparc/SparcTargetMachine.h
index cce5510..5834d08 100644
--- a/lib/Target/Sparc/SparcTargetMachine.h
+++ b/lib/Target/Sparc/SparcTargetMachine.h
@@ -24,14 +24,14 @@
namespace llvm {
class SparcTargetMachine : public LLVMTargetMachine {
- const TargetData DataLayout; // Calculates type size & alignment
SparcSubtarget Subtarget;
+ const TargetData DataLayout; // Calculates type size & alignment
SparcTargetLowering TLInfo;
SparcInstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
public:
SparcTargetMachine(const Target &T, const std::string &TT,
- const std::string &FS);
+ const std::string &FS, bool is64bit);
virtual const SparcInstrInfo *getInstrInfo() const { return &InstrInfo; }
virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; }
@@ -49,6 +49,22 @@ public:
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
};
+/// SparcV8TargetMachine - Sparc 32-bit target machine
+///
+class SparcV8TargetMachine : public SparcTargetMachine {
+public:
+ SparcV8TargetMachine(const Target &T, const std::string &TT,
+ const std::string &FS);
+};
+
+/// SparcV9TargetMachine - Sparc 64-bit target machine
+///
+class SparcV9TargetMachine : public SparcTargetMachine {
+public:
+ SparcV9TargetMachine(const Target &T, const std::string &TT,
+ const std::string &FS);
+};
+
} // end namespace llvm
#endif
diff --git a/lib/Target/Sparc/TargetInfo/Makefile b/lib/Target/Sparc/TargetInfo/Makefile
index 0827fdb..641ed87 100644
--- a/lib/Target/Sparc/TargetInfo/Makefile
+++ b/lib/Target/Sparc/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSparcInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Sparc/TargetInfo/SparcTargetInfo.cpp b/lib/Target/Sparc/TargetInfo/SparcTargetInfo.cpp
index 5d697bd..5c06f07 100644
--- a/lib/Target/Sparc/TargetInfo/SparcTargetInfo.cpp
+++ b/lib/Target/Sparc/TargetInfo/SparcTargetInfo.cpp
@@ -13,7 +13,9 @@
using namespace llvm;
Target llvm::TheSparcTarget;
+Target llvm::TheSparcV9Target;
extern "C" void LLVMInitializeSparcTargetInfo() {
RegisterTarget<Triple::sparc> X(TheSparcTarget, "sparc", "Sparc");
+ RegisterTarget<Triple::sparcv9> Y(TheSparcV9Target, "sparcv9", "Sparc V9");
}
diff --git a/lib/Target/SubtargetFeature.cpp b/lib/Target/SubtargetFeature.cpp
index 7cc4fd1..2094cc9 100644
--- a/lib/Target/SubtargetFeature.cpp
+++ b/lib/Target/SubtargetFeature.cpp
@@ -67,7 +67,7 @@ static void Split(std::vector<std::string> &V, const std::string &S) {
while (true) {
// Find the next comma
size_t Comma = S.find(',', Pos);
- // If no comma found then the the rest of the string is used
+ // If no comma found then the rest of the string is used
if (Comma == std::string::npos) {
// Add string to vector
V.push_back(S.substr(Pos));
diff --git a/lib/Target/SystemZ/AsmPrinter/Makefile b/lib/Target/SystemZ/AsmPrinter/Makefile
index 36cd6f8..9a350df 100644
--- a/lib/Target/SystemZ/AsmPrinter/Makefile
+++ b/lib/Target/SystemZ/AsmPrinter/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSystemZAsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' SystemZ target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
index 5c3fe37..7a9e8dd 100644
--- a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
+++ b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
@@ -32,19 +32,17 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
namespace {
class SystemZAsmPrinter : public AsmPrinter {
public:
SystemZAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *MAI, bool V)
- : AsmPrinter(O, TM, MAI, V) {}
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *MAI)
+ : AsmPrinter(O, TM, Ctx, Streamer, MAI) {}
virtual const char *getPassName() const {
return "SystemZ Assembly Printer";
@@ -67,10 +65,7 @@ namespace {
void printInstruction(const MachineInstr *MI); // autogenerated.
static const char *getRegisterName(unsigned RegNo);
- void printMachineInstruction(const MachineInstr * MI);
-
- void emitFunctionHeader(const MachineFunction &MF);
- bool runOnMachineFunction(MachineFunction &F);
+ void EmitInstruction(const MachineInstr *MI);
void getAnalysisUsage(AnalysisUsage &AU) const {
AsmPrinter::getAnalysisUsage(AU);
@@ -81,82 +76,10 @@ namespace {
#include "SystemZGenAsmWriter.inc"
-void SystemZAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
- unsigned FnAlign = MF.getAlignment();
- const Function *F = MF.getFunction();
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-
- EmitAlignment(FnAlign, F);
-
- switch (F->getLinkage()) {
- default: assert(0 && "Unknown linkage type!");
- case Function::InternalLinkage: // Symbols default to internal.
- case Function::PrivateLinkage:
- case Function::LinkerPrivateLinkage:
- break;
- case Function::ExternalLinkage:
- O << "\t.globl\t" << *CurrentFnSym << '\n';
- break;
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- O << "\t.weak\t" << *CurrentFnSym << '\n';
- break;
- }
-
- printVisibility(CurrentFnSym, F->getVisibility());
-
- O << "\t.type\t" << *CurrentFnSym << ",@function\n";
- O << *CurrentFnSym << ":\n";
-}
-
-bool SystemZAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
- SetupMachineFunction(MF);
- O << "\n\n";
-
- // Print out constants referenced by the function
- EmitConstantPool(MF.getConstantPool());
-
- // 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.
- EmitBasicBlockStart(I);
-
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II)
- // Print the assembly for the instruction.
- printMachineInstruction(II);
- }
-
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
-
- // Print out jump tables referenced by the function.
- EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
-
- // We didn't modify anything
- return false;
-}
-
-void SystemZAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
- ++EmittedInsts;
-
- processDebugLoc(MI, true);
-
+void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Call the autogenerated instruction printer routines.
printInstruction(MI);
-
- if (VerboseAsm)
- EmitComments(*MI);
- O << '\n';
-
- processDebugLoc(MI, false);
+ OutStreamer.AddBlankLine();
}
void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum){
@@ -166,7 +89,7 @@ void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum){
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_GlobalAddress: {
const GlobalValue *GV = MO.getGlobal();
@@ -221,7 +144,7 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
diff --git a/lib/Target/SystemZ/Makefile b/lib/Target/SystemZ/Makefile
index 6d0cbbd..5b44090 100644
--- a/lib/Target/SystemZ/Makefile
+++ b/lib/Target/SystemZ/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMSystemZCodeGen
TARGET = SystemZ
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = SystemZGenRegisterInfo.h.inc SystemZGenRegisterNames.inc \
diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index 7096c0e..7f0d9fb 100644
--- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -594,8 +594,7 @@ bool SystemZDAGToDAGISel::SelectLAAddr(SDNode *Op, SDValue Addr,
bool SystemZDAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Disp, SDValue &Index) {
if (ISD::isNON_EXTLoad(N.getNode()) &&
- N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), P, P))
+ IsLegalToFold(N, P, P))
return SelectAddrRRI20(P, N.getOperand(1), Base, Disp, Index);
return false;
}
@@ -665,10 +664,10 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
Dividend = N0.getNode();
// Insert prepared dividend into suitable 'subreg'
- SDNode *Tmp = CurDAG->getMachineNode(TargetInstrInfo::IMPLICIT_DEF,
+ SDNode *Tmp = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, ResVT);
Dividend =
- CurDAG->getMachineNode(TargetInstrInfo::INSERT_SUBREG, dl, ResVT,
+ CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, ResVT,
SDValue(Tmp, 0), SDValue(Dividend, 0),
CurDAG->getTargetConstant(subreg_odd, MVT::i32));
@@ -687,7 +686,7 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
// Copy the division (odd subreg) result, if it is needed.
if (!SDValue(Node, 0).use_empty()) {
unsigned SubRegIdx = (is32Bit ? subreg_odd32 : subreg_odd);
- SDNode *Div = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG,
+ SDNode *Div = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
dl, NVT,
SDValue(Result, 0),
CurDAG->getTargetConstant(SubRegIdx,
@@ -702,7 +701,7 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
// Copy the remainder (even subreg) result, if it is needed.
if (!SDValue(Node, 1).use_empty()) {
unsigned SubRegIdx = (is32Bit ? subreg_even32 : subreg_even);
- SDNode *Rem = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG,
+ SDNode *Rem = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
dl, NVT,
SDValue(Result, 0),
CurDAG->getTargetConstant(SubRegIdx,
@@ -749,12 +748,12 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
SDNode *Dividend = N0.getNode();
// Insert prepared dividend into suitable 'subreg'
- SDNode *Tmp = CurDAG->getMachineNode(TargetInstrInfo::IMPLICIT_DEF,
+ SDNode *Tmp = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, ResVT);
{
unsigned SubRegIdx = (is32Bit ? subreg_odd32 : subreg_odd);
Dividend =
- CurDAG->getMachineNode(TargetInstrInfo::INSERT_SUBREG, dl, ResVT,
+ CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, ResVT,
SDValue(Tmp, 0), SDValue(Dividend, 0),
CurDAG->getTargetConstant(SubRegIdx, MVT::i32));
}
@@ -777,7 +776,7 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
// Copy the division (odd subreg) result, if it is needed.
if (!SDValue(Node, 0).use_empty()) {
unsigned SubRegIdx = (is32Bit ? subreg_odd32 : subreg_odd);
- SDNode *Div = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG,
+ SDNode *Div = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
dl, NVT,
SDValue(Result, 0),
CurDAG->getTargetConstant(SubRegIdx,
@@ -791,7 +790,7 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
// Copy the remainder (even subreg) result, if it is needed.
if (!SDValue(Node, 1).use_empty()) {
unsigned SubRegIdx = (is32Bit ? subreg_even32 : subreg_even);
- SDNode *Rem = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG,
+ SDNode *Rem = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
dl, NVT,
SDValue(Result, 0),
CurDAG->getTargetConstant(SubRegIdx,
diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp
index d6b476e..6f4b30f 100644
--- a/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -30,9 +30,9 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -250,11 +250,13 @@ SystemZTargetLowering::LowerFormalArguments(SDValue Chain,
SDValue
SystemZTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // SystemZ target does not yet support tail call optimization.
+ isTailCall = false;
switch (CallConv) {
default:
@@ -335,7 +337,8 @@ SystemZTargetLowering::LowerCCCArguments(SDValue Chain,
// from this parameter
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
ArgValue = DAG.getLoad(LocVT, dl, Chain, FIN,
- PseudoSourceValue::getFixedStack(FI), 0);
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0);
}
// If this is an 8/16/32-bit value, it is really passed promoted to 64
@@ -433,7 +436,8 @@ SystemZTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
DAG.getIntPtrConstant(Offset));
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
- PseudoSourceValue::getStack(), Offset));
+ PseudoSourceValue::getStack(), Offset,
+ false, false, 0));
}
}
@@ -736,7 +740,7 @@ SDValue SystemZTargetLowering::LowerGlobalAddress(SDValue Op,
if (ExtraLoadRequired)
Result = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), Result,
- PseudoSourceValue::getGOT(), 0);
+ PseudoSourceValue::getGOT(), 0, false, false, 0);
// If there was a non-zero offset that we didn't fold, create an explicit
// addition for it.
diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h
index 5bf1ed6..36ff994 100644
--- a/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/lib/Target/SystemZ/SystemZISelLowering.h
@@ -125,7 +125,7 @@ namespace llvm {
SmallVectorImpl<SDValue> &InVals);
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
- CallingConv::ID CallConv, bool isVarArg, bool isTailCall,
+ CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/SystemZ/SystemZMCAsmInfo.cpp b/lib/Target/SystemZ/SystemZMCAsmInfo.cpp
index ba392bb..1a09206 100644
--- a/lib/Target/SystemZ/SystemZMCAsmInfo.cpp
+++ b/lib/Target/SystemZ/SystemZMCAsmInfo.cpp
@@ -16,11 +16,8 @@
using namespace llvm;
SystemZMCAsmInfo::SystemZMCAsmInfo(const Target &T, const StringRef &TT) {
- AlignmentIsInBytes = true;
-
PrivateGlobalPrefix = ".L";
WeakRefDirective = "\t.weak\t";
- SetDirective = "\t.set\t";
PCSymbol = ".";
}
diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/lib/Target/SystemZ/SystemZRegisterInfo.cpp
index 1318195..fe50c90 100644
--- a/lib/Target/SystemZ/SystemZRegisterInfo.cpp
+++ b/lib/Target/SystemZ/SystemZRegisterInfo.cpp
@@ -86,10 +86,11 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MBB.erase(I);
}
-int SystemZRegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
+int SystemZRegisterInfo::getFrameIndexOffset(const MachineFunction &MF,
+ int FI) const {
const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
- MachineFrameInfo *MFI = MF.getFrameInfo();
- SystemZMachineFunctionInfo *SystemZMFI =
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+ const SystemZMachineFunctionInfo *SystemZMFI =
MF.getInfo<SystemZMachineFunctionInfo>();
int Offset = MFI->getObjectOffset(FI) + MFI->getOffsetAdjustment();
uint64_t StackSize = MFI->getStackSize();
diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.h b/lib/Target/SystemZ/SystemZRegisterInfo.h
index 93f6aee..fabd4e8 100644
--- a/lib/Target/SystemZ/SystemZRegisterInfo.h
+++ b/lib/Target/SystemZ/SystemZRegisterInfo.h
@@ -49,7 +49,7 @@ struct SystemZRegisterInfo : public SystemZGenRegisterInfo {
bool hasReservedCallFrame(MachineFunction &MF) const { return true; }
bool hasFP(const MachineFunction &MF) const;
- int getFrameIndexOffset(MachineFunction &MF, int FI) const;
+ int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
diff --git a/lib/Target/SystemZ/TargetInfo/Makefile b/lib/Target/SystemZ/TargetInfo/Makefile
index 9f36b2c..0be80eb 100644
--- a/lib/Target/SystemZ/TargetInfo/Makefile
+++ b/lib/Target/SystemZ/TargetInfo/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSystemZInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/TargetAsmLexer.cpp b/lib/Target/TargetAsmLexer.cpp
index 0ae6c14..d4893ff 100644
--- a/lib/Target/TargetAsmLexer.cpp
+++ b/lib/Target/TargetAsmLexer.cpp
@@ -10,5 +10,5 @@
#include "llvm/Target/TargetAsmLexer.h"
using namespace llvm;
-TargetAsmLexer::TargetAsmLexer(const Target &T) : TheTarget(T) {}
+TargetAsmLexer::TargetAsmLexer(const Target &T) : TheTarget(T), Lexer(NULL) {}
TargetAsmLexer::~TargetAsmLexer() {}
diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp
index ba3cc9d..295b30f 100644
--- a/lib/Target/TargetData.cpp
+++ b/lib/Target/TargetData.cpp
@@ -545,6 +545,13 @@ unsigned char TargetData::getABITypeAlignment(const Type *Ty) const {
return getAlignment(Ty, true);
}
+/// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for
+/// an integer type of the specified bitwidth.
+unsigned char TargetData::getABIIntegerTypeAlignment(unsigned BitWidth) const {
+ return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, 0);
+}
+
+
unsigned char TargetData::getCallFrameTypeAlignment(const Type *Ty) const {
for (unsigned i = 0, e = Alignments.size(); i != e; ++i)
if (Alignments[i].AlignType == STACK_ALIGN)
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index a231ebc..0c105e9 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -19,17 +19,15 @@
#include "llvm/GlobalVariable.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCSectionMachO.h"
-#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -289,832 +287,54 @@ TargetLoweringObjectFile::getSectionForConstant(SectionKind Kind) const {
}
/// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a
-/// pc-relative reference to the specified global variable from exception
-/// handling information. In addition to the symbol, this returns
-/// by-reference:
-///
-/// IsIndirect - True if the returned symbol is actually a stub that contains
-/// the address of the symbol, false if the symbol is the global itself.
-///
-/// IsPCRel - True if the symbol reference is already pc-relative, false if
-/// the caller needs to subtract off the address of the reference from the
-/// symbol.
-///
+/// reference to the specified global variable from exception
+/// handling information.
const MCExpr *TargetLoweringObjectFile::
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const {
- // The generic implementation of this just returns a direct reference to the
- // symbol.
- IsIndirect = false;
- IsPCRel = false;
-
+ MachineModuleInfo *MMI, unsigned Encoding) const {
// FIXME: Use GetGlobalValueSymbol.
SmallString<128> Name;
Mang->getNameWithPrefix(Name, GV, false);
- return MCSymbolRefExpr::Create(Name.str(), getContext());
-}
-
-
-//===----------------------------------------------------------------------===//
-// ELF
-//===----------------------------------------------------------------------===//
-typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
-
-TargetLoweringObjectFileELF::~TargetLoweringObjectFileELF() {
- // If we have the section uniquing map, free it.
- delete (ELFUniqueMapTy*)UniquingMap;
-}
-
-const MCSection *TargetLoweringObjectFileELF::
-getELFSection(StringRef Section, unsigned Type, unsigned Flags,
- SectionKind Kind, bool IsExplicit) const {
- if (UniquingMap == 0)
- UniquingMap = new ELFUniqueMapTy();
- ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)UniquingMap;
-
- // Do the lookup, if we have a hit, return it.
- const MCSectionELF *&Entry = Map[Section];
- if (Entry) return Entry;
-
- return Entry = MCSectionELF::Create(Section, Type, Flags, Kind, IsExplicit,
- getContext());
-}
-
-void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
- const TargetMachine &TM) {
- if (UniquingMap != 0)
- ((ELFUniqueMapTy*)UniquingMap)->clear();
- TargetLoweringObjectFile::Initialize(Ctx, TM);
-
- BSSSection =
- getELFSection(".bss", MCSectionELF::SHT_NOBITS,
- MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
- SectionKind::getBSS());
-
- TextSection =
- getELFSection(".text", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_EXECINSTR | MCSectionELF::SHF_ALLOC,
- SectionKind::getText());
-
- DataSection =
- getELFSection(".data", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
- SectionKind::getDataRel());
-
- ReadOnlySection =
- getELFSection(".rodata", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC,
- SectionKind::getReadOnly());
-
- TLSDataSection =
- getELFSection(".tdata", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
- MCSectionELF::SHF_WRITE, SectionKind::getThreadData());
-
- TLSBSSSection =
- getELFSection(".tbss", MCSectionELF::SHT_NOBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
- MCSectionELF::SHF_WRITE, SectionKind::getThreadBSS());
-
- DataRelSection =
- getELFSection(".data.rel", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getDataRel());
-
- DataRelLocalSection =
- getELFSection(".data.rel.local", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getDataRelLocal());
-
- DataRelROSection =
- getELFSection(".data.rel.ro", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getReadOnlyWithRel());
-
- DataRelROLocalSection =
- getELFSection(".data.rel.ro.local", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getReadOnlyWithRelLocal());
-
- MergeableConst4Section =
- getELFSection(".rodata.cst4", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
- SectionKind::getMergeableConst4());
-
- MergeableConst8Section =
- getELFSection(".rodata.cst8", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
- SectionKind::getMergeableConst8());
-
- MergeableConst16Section =
- getELFSection(".rodata.cst16", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
- SectionKind::getMergeableConst16());
-
- StaticCtorSection =
- getELFSection(".ctors", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getDataRel());
-
- StaticDtorSection =
- getELFSection(".dtors", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getDataRel());
-
- // Exception Handling Sections.
-
- // FIXME: We're emitting LSDA info into a readonly section on ELF, even though
- // it contains relocatable pointers. In PIC mode, this is probably a big
- // runtime hit for C++ apps. Either the contents of the LSDA need to be
- // adjusted or this should be a data section.
- LSDASection =
- getELFSection(".gcc_except_table", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC, SectionKind::getReadOnly());
- EHFrameSection =
- getELFSection(".eh_frame", MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
- SectionKind::getDataRel());
-
- // Debug Info Sections.
- DwarfAbbrevSection =
- getELFSection(".debug_abbrev", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfInfoSection =
- getELFSection(".debug_info", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfLineSection =
- getELFSection(".debug_line", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfFrameSection =
- getELFSection(".debug_frame", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfPubNamesSection =
- getELFSection(".debug_pubnames", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfPubTypesSection =
- getELFSection(".debug_pubtypes", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfStrSection =
- getELFSection(".debug_str", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfLocSection =
- getELFSection(".debug_loc", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfARangesSection =
- getELFSection(".debug_aranges", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfRangesSection =
- getELFSection(".debug_ranges", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
- DwarfMacroInfoSection =
- getELFSection(".debug_macinfo", MCSectionELF::SHT_PROGBITS, 0,
- SectionKind::getMetadata());
-}
-
-
-static SectionKind
-getELFKindForNamedSection(StringRef Name, SectionKind K) {
- if (Name.empty() || Name[0] != '.') return K;
-
- // Some lame default implementation based on some magic section names.
- if (Name == ".bss" ||
- Name.startswith(".bss.") ||
- Name.startswith(".gnu.linkonce.b.") ||
- Name.startswith(".llvm.linkonce.b.") ||
- Name == ".sbss" ||
- Name.startswith(".sbss.") ||
- Name.startswith(".gnu.linkonce.sb.") ||
- Name.startswith(".llvm.linkonce.sb."))
- return SectionKind::getBSS();
-
- if (Name == ".tdata" ||
- Name.startswith(".tdata.") ||
- Name.startswith(".gnu.linkonce.td.") ||
- Name.startswith(".llvm.linkonce.td."))
- return SectionKind::getThreadData();
-
- if (Name == ".tbss" ||
- Name.startswith(".tbss.") ||
- Name.startswith(".gnu.linkonce.tb.") ||
- Name.startswith(".llvm.linkonce.tb."))
- return SectionKind::getThreadBSS();
-
- return K;
-}
-
-
-static unsigned getELFSectionType(StringRef Name, SectionKind K) {
-
- if (Name == ".init_array")
- return MCSectionELF::SHT_INIT_ARRAY;
-
- if (Name == ".fini_array")
- return MCSectionELF::SHT_FINI_ARRAY;
+ const MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
- if (Name == ".preinit_array")
- return MCSectionELF::SHT_PREINIT_ARRAY;
-
- if (K.isBSS() || K.isThreadBSS())
- return MCSectionELF::SHT_NOBITS;
-
- return MCSectionELF::SHT_PROGBITS;
-}
-
-
-static unsigned
-getELFSectionFlags(SectionKind K) {
- unsigned Flags = 0;
-
- if (!K.isMetadata())
- Flags |= MCSectionELF::SHF_ALLOC;
-
- if (K.isText())
- Flags |= MCSectionELF::SHF_EXECINSTR;
-
- if (K.isWriteable())
- Flags |= MCSectionELF::SHF_WRITE;
-
- if (K.isThreadLocal())
- Flags |= MCSectionELF::SHF_TLS;
-
- // K.isMergeableConst() is left out to honour PR4650
- if (K.isMergeableCString() || K.isMergeableConst4() ||
- K.isMergeableConst8() || K.isMergeableConst16())
- Flags |= MCSectionELF::SHF_MERGE;
-
- if (K.isMergeableCString())
- Flags |= MCSectionELF::SHF_STRINGS;
-
- return Flags;
-}
-
-
-const MCSection *TargetLoweringObjectFileELF::
-getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
- StringRef SectionName = GV->getSection();
-
- // Infer section flags from the section name if we can.
- Kind = getELFKindForNamedSection(SectionName, Kind);
-
- return getELFSection(SectionName,
- getELFSectionType(SectionName, Kind),
- getELFSectionFlags(Kind), Kind, true);
-}
-
-static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
- if (Kind.isText()) return ".gnu.linkonce.t.";
- if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
-
- if (Kind.isThreadData()) return ".gnu.linkonce.td.";
- if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
-
- if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
- if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
- if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
- if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
-
- assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
- return ".gnu.linkonce.d.rel.ro.";
+ return getSymbolForDwarfReference(Sym, MMI, Encoding);
}
-const MCSection *TargetLoweringObjectFileELF::
-SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
-
- // If this global is linkonce/weak and the target handles this by emitting it
- // into a 'uniqued' section name, create and return the section now.
- if (GV->isWeakForLinker() && !Kind.isCommon() && !Kind.isBSS()) {
- const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
- SmallString<128> Name;
- Name.append(Prefix, Prefix+strlen(Prefix));
- Mang->getNameWithPrefix(Name, GV, false);
- return getELFSection(Name.str(), getELFSectionType(Name.str(), Kind),
- getELFSectionFlags(Kind), Kind);
- }
-
- if (Kind.isText()) return TextSection;
-
- if (Kind.isMergeable1ByteCString() ||
- Kind.isMergeable2ByteCString() ||
- Kind.isMergeable4ByteCString()) {
-
- // We also need alignment here.
- // FIXME: this is getting the alignment of the character, not the
- // alignment of the global!
- unsigned Align =
- TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV));
-
- const char *SizeSpec = ".rodata.str1.";
- if (Kind.isMergeable2ByteCString())
- SizeSpec = ".rodata.str2.";
- else if (Kind.isMergeable4ByteCString())
- SizeSpec = ".rodata.str4.";
- else
- assert(Kind.isMergeable1ByteCString() && "unknown string width");
-
-
- std::string Name = SizeSpec + utostr(Align);
- return getELFSection(Name, MCSectionELF::SHT_PROGBITS,
- MCSectionELF::SHF_ALLOC |
- MCSectionELF::SHF_MERGE |
- MCSectionELF::SHF_STRINGS,
- Kind);
- }
-
- if (Kind.isMergeableConst()) {
- if (Kind.isMergeableConst4() && MergeableConst4Section)
- return MergeableConst4Section;
- if (Kind.isMergeableConst8() && MergeableConst8Section)
- return MergeableConst8Section;
- if (Kind.isMergeableConst16() && MergeableConst16Section)
- return MergeableConst16Section;
- return ReadOnlySection; // .const
- }
-
- if (Kind.isReadOnly()) return ReadOnlySection;
-
- if (Kind.isThreadData()) return TLSDataSection;
- if (Kind.isThreadBSS()) return TLSBSSSection;
-
- // Note: we claim that common symbols are put in BSSSection, but they are
- // really emitted with the magic .comm directive, which creates a symbol table
- // entry but not a section.
- if (Kind.isBSS() || Kind.isCommon()) return BSSSection;
-
- if (Kind.isDataNoRel()) return DataSection;
- if (Kind.isDataRelLocal()) return DataRelLocalSection;
- if (Kind.isDataRel()) return DataRelSection;
- if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
-
- assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
- return DataRelROSection;
-}
-
-/// getSectionForConstant - Given a mergeable constant with the
-/// specified size and relocation information, return a section that it
-/// should be placed in.
-const MCSection *TargetLoweringObjectFileELF::
-getSectionForConstant(SectionKind Kind) const {
- if (Kind.isMergeableConst4() && MergeableConst4Section)
- return MergeableConst4Section;
- if (Kind.isMergeableConst8() && MergeableConst8Section)
- return MergeableConst8Section;
- if (Kind.isMergeableConst16() && MergeableConst16Section)
- return MergeableConst16Section;
- if (Kind.isReadOnly())
- return ReadOnlySection;
-
- if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
- assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
- return DataRelROSection;
-}
-
-//===----------------------------------------------------------------------===//
-// MachO
-//===----------------------------------------------------------------------===//
-
-typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
-
-TargetLoweringObjectFileMachO::~TargetLoweringObjectFileMachO() {
- // If we have the MachO uniquing map, free it.
- delete (MachOUniqueMapTy*)UniquingMap;
-}
-
-
-const MCSectionMachO *TargetLoweringObjectFileMachO::
-getMachOSection(StringRef Segment, StringRef Section,
- unsigned TypeAndAttributes,
- unsigned Reserved2, SectionKind Kind) const {
- // We unique sections by their segment/section pair. The returned section
- // may not have the same flags as the requested section, if so this should be
- // diagnosed by the client as an error.
-
- // Create the map if it doesn't already exist.
- if (UniquingMap == 0)
- UniquingMap = new MachOUniqueMapTy();
- MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)UniquingMap;
-
- // Form the name to look up.
- SmallString<64> Name;
- Name += Segment;
- Name.push_back(',');
- Name += Section;
-
- // Do the lookup, if we have a hit, return it.
- const MCSectionMachO *&Entry = Map[Name.str()];
- if (Entry) return Entry;
-
- // Otherwise, return a new section.
- return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes,
- Reserved2, Kind, getContext());
-}
-
-
-void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
- const TargetMachine &TM) {
- if (UniquingMap != 0)
- ((MachOUniqueMapTy*)UniquingMap)->clear();
- TargetLoweringObjectFile::Initialize(Ctx, TM);
-
- TextSection // .text
- = getMachOSection("__TEXT", "__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- SectionKind::getText());
- DataSection // .data
- = getMachOSection("__DATA", "__data", 0, SectionKind::getDataRel());
-
- CStringSection // .cstring
- = getMachOSection("__TEXT", "__cstring", MCSectionMachO::S_CSTRING_LITERALS,
- SectionKind::getMergeable1ByteCString());
- UStringSection
- = getMachOSection("__TEXT","__ustring", 0,
- SectionKind::getMergeable2ByteCString());
- FourByteConstantSection // .literal4
- = getMachOSection("__TEXT", "__literal4", MCSectionMachO::S_4BYTE_LITERALS,
- SectionKind::getMergeableConst4());
- EightByteConstantSection // .literal8
- = getMachOSection("__TEXT", "__literal8", MCSectionMachO::S_8BYTE_LITERALS,
- SectionKind::getMergeableConst8());
-
- // ld_classic doesn't support .literal16 in 32-bit mode, and ld64 falls back
- // to using it in -static mode.
- SixteenByteConstantSection = 0;
- if (TM.getRelocationModel() != Reloc::Static &&
- TM.getTargetData()->getPointerSize() == 32)
- SixteenByteConstantSection = // .literal16
- getMachOSection("__TEXT", "__literal16",MCSectionMachO::S_16BYTE_LITERALS,
- SectionKind::getMergeableConst16());
-
- ReadOnlySection // .const
- = getMachOSection("__TEXT", "__const", 0, SectionKind::getReadOnly());
-
- TextCoalSection
- = getMachOSection("__TEXT", "__textcoal_nt",
- MCSectionMachO::S_COALESCED |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- SectionKind::getText());
- ConstTextCoalSection
- = getMachOSection("__TEXT", "__const_coal", MCSectionMachO::S_COALESCED,
- SectionKind::getText());
- ConstDataCoalSection
- = getMachOSection("__DATA","__const_coal", MCSectionMachO::S_COALESCED,
- SectionKind::getText());
- ConstDataSection // .const_data
- = getMachOSection("__DATA", "__const", 0,
- SectionKind::getReadOnlyWithRel());
- DataCoalSection
- = getMachOSection("__DATA","__datacoal_nt", MCSectionMachO::S_COALESCED,
- SectionKind::getDataRel());
- DataCommonSection
- = getMachOSection("__DATA","__common", MCSectionMachO::S_ZEROFILL,
- SectionKind::getBSS());
- DataBSSSection
- = getMachOSection("__DATA","__bss", MCSectionMachO::S_ZEROFILL,
- SectionKind::getBSS());
-
-
- LazySymbolPointerSection
- = getMachOSection("__DATA", "__la_symbol_ptr",
- MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
- SectionKind::getMetadata());
- NonLazySymbolPointerSection
- = getMachOSection("__DATA", "__nl_symbol_ptr",
- MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
- SectionKind::getMetadata());
-
- if (TM.getRelocationModel() == Reloc::Static) {
- StaticCtorSection
- = getMachOSection("__TEXT", "__constructor", 0,SectionKind::getDataRel());
- StaticDtorSection
- = getMachOSection("__TEXT", "__destructor", 0, SectionKind::getDataRel());
- } else {
- StaticCtorSection
- = getMachOSection("__DATA", "__mod_init_func",
- MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
- SectionKind::getDataRel());
- StaticDtorSection
- = getMachOSection("__DATA", "__mod_term_func",
- MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
- SectionKind::getDataRel());
- }
-
- // Exception Handling.
- LSDASection = getMachOSection("__DATA", "__gcc_except_tab", 0,
- SectionKind::getDataRel());
- EHFrameSection =
- getMachOSection("__TEXT", "__eh_frame",
- MCSectionMachO::S_COALESCED |
- MCSectionMachO::S_ATTR_NO_TOC |
- MCSectionMachO::S_ATTR_STRIP_STATIC_SYMS |
- MCSectionMachO::S_ATTR_LIVE_SUPPORT,
- SectionKind::getReadOnly());
-
- // Debug Information.
- DwarfAbbrevSection =
- getMachOSection("__DWARF", "__debug_abbrev", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfInfoSection =
- getMachOSection("__DWARF", "__debug_info", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfLineSection =
- getMachOSection("__DWARF", "__debug_line", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfFrameSection =
- getMachOSection("__DWARF", "__debug_frame", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfPubNamesSection =
- getMachOSection("__DWARF", "__debug_pubnames", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfPubTypesSection =
- getMachOSection("__DWARF", "__debug_pubtypes", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfStrSection =
- getMachOSection("__DWARF", "__debug_str", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfLocSection =
- getMachOSection("__DWARF", "__debug_loc", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfARangesSection =
- getMachOSection("__DWARF", "__debug_aranges", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfRangesSection =
- getMachOSection("__DWARF", "__debug_ranges", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfMacroInfoSection =
- getMachOSection("__DWARF", "__debug_macinfo", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
- DwarfDebugInlineSection =
- getMachOSection("__DWARF", "__debug_inlined", MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
-}
-
-const MCSection *TargetLoweringObjectFileMachO::
-getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
- // Parse the section specifier and create it if valid.
- StringRef Segment, Section;
- unsigned TAA, StubSize;
- std::string ErrorCode =
- MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section,
- TAA, StubSize);
- if (!ErrorCode.empty()) {
- // If invalid, report the error with llvm_report_error.
- llvm_report_error("Global variable '" + GV->getNameStr() +
- "' has an invalid section specifier '" + GV->getSection()+
- "': " + ErrorCode + ".");
- // Fall back to dropping it into the data section.
- return DataSection;
- }
-
- // Get the section.
- const MCSectionMachO *S =
- getMachOSection(Segment, Section, TAA, StubSize, Kind);
-
- // Okay, now that we got the section, verify that the TAA & StubSize agree.
- // If the user declared multiple globals with different section flags, we need
- // to reject it here.
- if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) {
- // If invalid, report the error with llvm_report_error.
- llvm_report_error("Global variable '" + GV->getNameStr() +
- "' section type or attributes does not match previous"
- " section specifier");
- }
-
- return S;
-}
-
-const MCSection *TargetLoweringObjectFileMachO::
-SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
- assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS");
-
- if (Kind.isText())
- return GV->isWeakForLinker() ? TextCoalSection : TextSection;
-
- // If this is weak/linkonce, put this in a coalescable section, either in text
- // or data depending on if it is writable.
- if (GV->isWeakForLinker()) {
- if (Kind.isReadOnly())
- return ConstTextCoalSection;
- return DataCoalSection;
- }
-
- // FIXME: Alignment check should be handled by section classifier.
- if (Kind.isMergeable1ByteCString() ||
- Kind.isMergeable2ByteCString()) {
- if (TM.getTargetData()->getPreferredAlignment(
- cast<GlobalVariable>(GV)) < 32) {
- if (Kind.isMergeable1ByteCString())
- return CStringSection;
- assert(Kind.isMergeable2ByteCString());
- return UStringSection;
- }
- }
-
- if (Kind.isMergeableConst()) {
- if (Kind.isMergeableConst4())
- return FourByteConstantSection;
- if (Kind.isMergeableConst8())
- return EightByteConstantSection;
- if (Kind.isMergeableConst16() && SixteenByteConstantSection)
- return SixteenByteConstantSection;
- }
-
- // Otherwise, if it is readonly, but not something we can specially optimize,
- // just drop it in .const.
- if (Kind.isReadOnly())
- return ReadOnlySection;
-
- // If this is marked const, put it into a const section. But if the dynamic
- // linker needs to write to it, put it in the data segment.
- if (Kind.isReadOnlyWithRel())
- return ConstDataSection;
-
- // Put zero initialized globals with strong external linkage in the
- // DATA, __common section with the .zerofill directive.
- if (Kind.isBSSExtern())
- return DataCommonSection;
-
- // Put zero initialized globals with local linkage in __DATA,__bss directive
- // with the .zerofill directive (aka .lcomm).
- if (Kind.isBSSLocal())
- return DataBSSSection;
-
- // Otherwise, just drop the variable in the normal data section.
- return DataSection;
-}
-
-const MCSection *
-TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind) const {
- // If this constant requires a relocation, we have to put it in the data
- // segment, not in the text segment.
- if (Kind.isDataRel() || Kind.isReadOnlyWithRel())
- return ConstDataSection;
-
- if (Kind.isMergeableConst4())
- return FourByteConstantSection;
- if (Kind.isMergeableConst8())
- return EightByteConstantSection;
- if (Kind.isMergeableConst16() && SixteenByteConstantSection)
- return SixteenByteConstantSection;
- return ReadOnlySection; // .const
-}
-
-/// shouldEmitUsedDirectiveFor - This hook allows targets to selectively decide
-/// not to emit the UsedDirective for some symbols in llvm.used.
-// FIXME: REMOVE this (rdar://7071300)
-bool TargetLoweringObjectFileMachO::
-shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const {
- /// On Darwin, internally linked data beginning with "L" or "l" does not have
- /// the directive emitted (this occurs in ObjC metadata).
- if (!GV) return false;
-
- // Check whether the mangled name has the "Private" or "LinkerPrivate" prefix.
- if (GV->hasLocalLinkage() && !isa<Function>(GV)) {
- // FIXME: ObjC metadata is currently emitted as internal symbols that have
- // \1L and \0l prefixes on them. Fix them to be Private/LinkerPrivate and
- // this horrible hack can go away.
- SmallString<64> Name;
- Mang->getNameWithPrefix(Name, GV, false);
- if (Name[0] == 'L' || Name[0] == 'l')
- return false;
+const MCExpr *TargetLoweringObjectFile::
+getSymbolForDwarfReference(const MCSymbol *Sym, MachineModuleInfo *MMI,
+ unsigned Encoding) const {
+ const MCExpr *Res = MCSymbolRefExpr::Create(Sym, getContext());
+
+ switch (Encoding & 0xF0) {
+ default:
+ llvm_report_error("Do not support this DWARF encoding yet!");
+ break;
+ case dwarf::DW_EH_PE_absptr:
+ // Do nothing special
+ break;
+ case dwarf::DW_EH_PE_pcrel:
+ // FIXME: PCSymbol
+ const MCExpr *PC = MCSymbolRefExpr::Create(".", getContext());
+ Res = MCBinaryExpr::CreateSub(Res, PC, getContext());
+ break;
}
- return true;
+ return Res;
}
-const MCExpr *TargetLoweringObjectFileMachO::
-getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const {
- // The mach-o version of this method defaults to returning a stub reference.
- IsIndirect = true;
- IsPCRel = false;
-
- SmallString<128> Name;
- Mang->getNameWithPrefix(Name, GV, true);
- Name += "$non_lazy_ptr";
- return MCSymbolRefExpr::Create(Name.str(), getContext());
+unsigned TargetLoweringObjectFile::getPersonalityEncoding() const {
+ return dwarf::DW_EH_PE_absptr;
}
-
-//===----------------------------------------------------------------------===//
-// COFF
-//===----------------------------------------------------------------------===//
-
-typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
-
-TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() {
- delete (COFFUniqueMapTy*)UniquingMap;
+unsigned TargetLoweringObjectFile::getLSDAEncoding() const {
+ return dwarf::DW_EH_PE_absptr;
}
-
-const MCSection *TargetLoweringObjectFileCOFF::
-getCOFFSection(StringRef Name, bool isDirective, SectionKind Kind) const {
- // Create the map if it doesn't already exist.
- if (UniquingMap == 0)
- UniquingMap = new MachOUniqueMapTy();
- COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)UniquingMap;
-
- // Do the lookup, if we have a hit, return it.
- const MCSectionCOFF *&Entry = Map[Name];
- if (Entry) return Entry;
-
- return Entry = MCSectionCOFF::Create(Name, isDirective, Kind, getContext());
+unsigned TargetLoweringObjectFile::getFDEEncoding() const {
+ return dwarf::DW_EH_PE_absptr;
}
-void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
- const TargetMachine &TM) {
- if (UniquingMap != 0)
- ((COFFUniqueMapTy*)UniquingMap)->clear();
- TargetLoweringObjectFile::Initialize(Ctx, TM);
- TextSection = getCOFFSection("\t.text", true, SectionKind::getText());
- DataSection = getCOFFSection("\t.data", true, SectionKind::getDataRel());
- StaticCtorSection =
- getCOFFSection(".ctors", false, SectionKind::getDataRel());
- StaticDtorSection =
- getCOFFSection(".dtors", false, SectionKind::getDataRel());
-
- // FIXME: We're emitting LSDA info into a readonly section on COFF, even
- // though it contains relocatable pointers. In PIC mode, this is probably a
- // big runtime hit for C++ apps. Either the contents of the LSDA need to be
- // adjusted or this should be a data section.
- LSDASection =
- getCOFFSection(".gcc_except_table", false, SectionKind::getReadOnly());
- EHFrameSection =
- getCOFFSection(".eh_frame", false, SectionKind::getDataRel());
-
- // Debug info.
- // FIXME: Don't use 'directive' mode here.
- DwarfAbbrevSection =
- getCOFFSection("\t.section\t.debug_abbrev,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfInfoSection =
- getCOFFSection("\t.section\t.debug_info,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfLineSection =
- getCOFFSection("\t.section\t.debug_line,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfFrameSection =
- getCOFFSection("\t.section\t.debug_frame,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfPubNamesSection =
- getCOFFSection("\t.section\t.debug_pubnames,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfPubTypesSection =
- getCOFFSection("\t.section\t.debug_pubtypes,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfStrSection =
- getCOFFSection("\t.section\t.debug_str,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfLocSection =
- getCOFFSection("\t.section\t.debug_loc,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfARangesSection =
- getCOFFSection("\t.section\t.debug_aranges,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfRangesSection =
- getCOFFSection("\t.section\t.debug_ranges,\"dr\"",
- true, SectionKind::getMetadata());
- DwarfMacroInfoSection =
- getCOFFSection("\t.section\t.debug_macinfo,\"dr\"",
- true, SectionKind::getMetadata());
-}
-
-const MCSection *TargetLoweringObjectFileCOFF::
-getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
- return getCOFFSection(GV->getSection(), false, Kind);
-}
-
-static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
- if (Kind.isText())
- return ".text$linkonce";
- if (Kind.isWriteable())
- return ".data$linkonce";
- return ".rdata$linkonce";
-}
-
-
-const MCSection *TargetLoweringObjectFileCOFF::
-SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const {
- assert(!Kind.isThreadLocal() && "Doesn't support TLS");
-
- // If this global is linkonce/weak and the target handles this by emitting it
- // into a 'uniqued' section name, create and return the section now.
- if (GV->isWeakForLinker()) {
- const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind);
- SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
- Mang->getNameWithPrefix(Name, GV, false);
- return getCOFFSection(Name.str(), false, Kind);
- }
-
- if (Kind.isText())
- return getTextSection();
-
- return getDataSection();
+unsigned TargetLoweringObjectFile::getTTypeEncoding() const {
+ return dwarf::DW_EH_PE_absptr;
}
diff --git a/lib/Target/TargetMachOWriterInfo.cpp b/lib/Target/TargetMachOWriterInfo.cpp
deleted file mode 100644
index d608119..0000000
--- a/lib/Target/TargetMachOWriterInfo.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-//===-- llvm/Target/TargetMachOWriterInfo.h - MachO Writer Info -*- 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 TargetMachOWriterInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Target/TargetMachOWriterInfo.h"
-#include "llvm/CodeGen/MachineRelocation.h"
-using namespace llvm;
-
-TargetMachOWriterInfo::~TargetMachOWriterInfo() {}
-
-MachineRelocation
-TargetMachOWriterInfo::GetJTRelocation(unsigned Offset,
- MachineBasicBlock *MBB) const {
- // FIXME: do something about PIC
- return MachineRelocation::getBB(Offset, MachineRelocation::VANILLA, MBB);
-}
diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp
index fec59b5..88871e3 100644
--- a/lib/Target/TargetMachine.cpp
+++ b/lib/Target/TargetMachine.cpp
@@ -40,7 +40,7 @@ namespace llvm {
bool UnwindTablesMandatory;
Reloc::Model RelocationModel;
CodeModel::Model CMModel;
- bool PerformTailCallOpt;
+ bool GuaranteedTailCallOpt;
unsigned StackAlignment;
bool RealignStack;
bool DisableJumpTables;
@@ -173,9 +173,9 @@ DefCodeModel("code-model",
"Large code model"),
clEnumValEnd));
static cl::opt<bool, true>
-EnablePerformTailCallOpt("tailcallopt",
- cl::desc("Turn on tail call optimization."),
- cl::location(PerformTailCallOpt),
+EnableGuaranteedTailCallOpt("tailcallopt",
+ cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."),
+ cl::location(GuaranteedTailCallOpt),
cl::init(false));
static cl::opt<unsigned, true>
OverrideStackAlignment("stack-alignment",
diff --git a/lib/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp
index fac67e2..52983ff 100644
--- a/lib/Target/TargetRegisterInfo.cpp
+++ b/lib/Target/TargetRegisterInfo.cpp
@@ -86,9 +86,10 @@ BitVector TargetRegisterInfo::getAllocatableSet(const MachineFunction &MF,
/// getFrameIndexOffset - Returns the displacement from the frame register to
/// the stack frame of the specified index. This is the default implementation
/// which is overridden for some targets.
-int TargetRegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
+int TargetRegisterInfo::getFrameIndexOffset(const MachineFunction &MF,
+ int FI) const {
const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
- MachineFrameInfo *MFI = MF.getFrameInfo();
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
return MFI->getObjectOffset(FI) + MFI->getStackSize() -
TFI.getOffsetOfLocalArea() + MFI->getOffsetAdjustment();
}
@@ -96,7 +97,7 @@ int TargetRegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
/// getInitialFrameState - Returns a list of machine moves that are assumed
/// on entry to a function.
void
-TargetRegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves) const {
+TargetRegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves) const{
// Default is to do nothing.
}
diff --git a/lib/Target/X86/AsmParser/Makefile b/lib/Target/X86/AsmParser/Makefile
index 288b985..25fb0a2 100644
--- a/lib/Target/X86/AsmParser/Makefile
+++ b/lib/Target/X86/AsmParser/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMX86AsmParser
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' x86 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/AsmParser/X86AsmLexer.cpp b/lib/Target/X86/AsmParser/X86AsmLexer.cpp
index 1a62044..a58f58e 100644
--- a/lib/Target/X86/AsmParser/X86AsmLexer.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmLexer.cpp
@@ -7,8 +7,11 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Target/TargetAsmLexer.h"
#include "llvm/Target/TargetRegistry.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "X86.h"
@@ -19,18 +22,119 @@ namespace {
class X86AsmLexer : public TargetAsmLexer {
const MCAsmInfo &AsmInfo;
+
+ bool tentativeIsValid;
+ AsmToken tentativeToken;
+
+ const AsmToken &lexTentative() {
+ tentativeToken = getLexer()->Lex();
+ tentativeIsValid = true;
+ return tentativeToken;
+ }
+
+ const AsmToken &lexDefinite() {
+ if(tentativeIsValid) {
+ tentativeIsValid = false;
+ return tentativeToken;
+ }
+ else {
+ return getLexer()->Lex();
+ }
+ }
+
+ AsmToken LexTokenATT();
+ AsmToken LexTokenIntel();
protected:
- AsmToken LexToken();
+ AsmToken LexToken() {
+ if (!Lexer) {
+ SetError(SMLoc(), "No MCAsmLexer installed");
+ return AsmToken(AsmToken::Error, "", 0);
+ }
+
+ switch (AsmInfo.getAssemblerDialect()) {
+ default:
+ SetError(SMLoc(), "Unhandled dialect");
+ return AsmToken(AsmToken::Error, "", 0);
+ case 0:
+ return LexTokenATT();
+ case 1:
+ return LexTokenIntel();
+ }
+ }
public:
X86AsmLexer(const Target &T, const MCAsmInfo &MAI)
- : TargetAsmLexer(T), AsmInfo(MAI) {
+ : TargetAsmLexer(T), AsmInfo(MAI), tentativeIsValid(false) {
}
};
}
-AsmToken X86AsmLexer::LexToken() {
- return AsmToken(AsmToken::Error, "", 0);
+static unsigned MatchRegisterName(StringRef Name);
+
+AsmToken X86AsmLexer::LexTokenATT() {
+ const AsmToken lexedToken = lexDefinite();
+
+ switch (lexedToken.getKind()) {
+ default:
+ return AsmToken(lexedToken);
+ case AsmToken::Error:
+ SetError(Lexer->getErrLoc(), Lexer->getErr());
+ return AsmToken(lexedToken);
+ case AsmToken::Percent:
+ {
+ const AsmToken &nextToken = lexTentative();
+ if (nextToken.getKind() == AsmToken::Identifier) {
+ unsigned regID = MatchRegisterName(nextToken.getString());
+
+ if (regID) {
+ lexDefinite();
+
+ StringRef regStr(lexedToken.getString().data(),
+ lexedToken.getString().size() +
+ nextToken.getString().size());
+
+ return AsmToken(AsmToken::Register,
+ regStr,
+ static_cast<int64_t>(regID));
+ }
+ else {
+ return AsmToken(lexedToken);
+ }
+ }
+ else {
+ return AsmToken(lexedToken);
+ }
+ }
+ }
+}
+
+AsmToken X86AsmLexer::LexTokenIntel() {
+ const AsmToken &lexedToken = lexDefinite();
+
+ switch(lexedToken.getKind()) {
+ default:
+ return AsmToken(lexedToken);
+ case AsmToken::Error:
+ SetError(Lexer->getErrLoc(), Lexer->getErr());
+ return AsmToken(lexedToken);
+ case AsmToken::Identifier:
+ {
+ std::string upperCase = lexedToken.getString().str();
+ std::string lowerCase = LowercaseString(upperCase);
+ StringRef lowerRef(lowerCase);
+
+ unsigned regID = MatchRegisterName(lowerRef);
+
+ if (regID) {
+ return AsmToken(AsmToken::Register,
+ lexedToken.getString(),
+ static_cast<int64_t>(regID));
+ }
+ else {
+ return AsmToken(lexedToken);
+ }
+ }
+ }
}
extern "C" void LLVMInitializeX86AsmLexer() {
@@ -38,6 +142,6 @@ extern "C" void LLVMInitializeX86AsmLexer() {
RegisterAsmLexer<X86AsmLexer> Y(TheX86_64Target);
}
-//#define REGISTERS_ONLY
-//#include "../X86GenAsmMatcher.inc"
-//#undef REGISTERS_ONLY
+#define REGISTERS_ONLY
+#include "X86GenAsmMatcher.inc"
+#undef REGISTERS_ONLY
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 7a9218e..84d7bb7 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -10,6 +10,7 @@
#include "llvm/Target/TargetAsmParser.h"
#include "X86.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
@@ -67,7 +68,7 @@ public:
/// @name Auto-generated Match Functions
/// {
-static unsigned MatchRegisterName(const StringRef &Name);
+static unsigned MatchRegisterName(StringRef Name);
/// }
@@ -172,8 +173,25 @@ struct X86Operand : public MCParsedAsmOperand {
bool isMem() const { return Kind == Memory; }
+ bool isAbsMem() const {
+ return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
+ !getMemIndexReg() && getMemScale() == 1;
+ }
+
+ bool isNoSegMem() const {
+ return Kind == Memory && !getMemSegReg();
+ }
+
bool isReg() const { return Kind == Register; }
+ void addExpr(MCInst &Inst, const MCExpr *Expr) const {
+ // Add as immediates when possible.
+ if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
+ Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
+ else
+ Inst.addOperand(MCOperand::CreateExpr(Expr));
+ }
+
void addRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateReg(getReg()));
@@ -181,26 +199,35 @@ struct X86Operand : public MCParsedAsmOperand {
void addImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateExpr(getImm()));
+ addExpr(Inst, getImm());
}
void addImmSExt8Operands(MCInst &Inst, unsigned N) const {
// FIXME: Support user customization of the render method.
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateExpr(getImm()));
+ addExpr(Inst, getImm());
}
void addMemOperands(MCInst &Inst, unsigned N) const {
- assert((N == 4 || N == 5) && "Invalid number of operands!");
-
+ assert((N == 5) && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
Inst.addOperand(MCOperand::CreateImm(getMemScale()));
Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
+ addExpr(Inst, getMemDisp());
+ Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
+ }
+
+ void addAbsMemOperands(MCInst &Inst, unsigned N) const {
+ assert((N == 1) && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
+ }
- // FIXME: What a hack.
- if (N == 5)
- Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
+ void addNoSegMemOperands(MCInst &Inst, unsigned N) const {
+ assert((N == 4) && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
+ Inst.addOperand(MCOperand::CreateImm(getMemScale()));
+ Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
+ addExpr(Inst, getMemDisp());
}
static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
@@ -222,10 +249,24 @@ struct X86Operand : public MCParsedAsmOperand {
return Res;
}
+ /// Create an absolute memory operand.
+ static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
+ SMLoc EndLoc) {
+ X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
+ Res->Mem.SegReg = 0;
+ Res->Mem.Disp = Disp;
+ Res->Mem.BaseReg = 0;
+ Res->Mem.IndexReg = 0;
+ Res->Mem.Scale = 1;
+ return Res;
+ }
+
+ /// Create a generalized memory operand.
static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
unsigned BaseReg, unsigned IndexReg,
unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
- // We should never just have a displacement, that would be an immediate.
+ // We should never just have a displacement, that should be parsed as an
+ // absolute memory operand.
assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
// The scale should always be one of {1,2,4,8}.
@@ -259,6 +300,42 @@ bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
// FIXME: Validate register for the current architecture; we have to do
// validation later, so maybe there is no need for this here.
RegNo = MatchRegisterName(Tok.getString());
+
+ // Parse %st(1) and "%st" as "%st(0)"
+ if (RegNo == 0 && Tok.getString() == "st") {
+ RegNo = X86::ST0;
+ EndLoc = Tok.getLoc();
+ Parser.Lex(); // Eat 'st'
+
+ // Check to see if we have '(4)' after %st.
+ if (getLexer().isNot(AsmToken::LParen))
+ return false;
+ // Lex the paren.
+ getParser().Lex();
+
+ const AsmToken &IntTok = Parser.getTok();
+ if (IntTok.isNot(AsmToken::Integer))
+ return Error(IntTok.getLoc(), "expected stack index");
+ switch (IntTok.getIntVal()) {
+ case 0: RegNo = X86::ST0; break;
+ case 1: RegNo = X86::ST1; break;
+ case 2: RegNo = X86::ST2; break;
+ case 3: RegNo = X86::ST3; break;
+ case 4: RegNo = X86::ST4; break;
+ case 5: RegNo = X86::ST5; break;
+ case 6: RegNo = X86::ST6; break;
+ case 7: RegNo = X86::ST7; break;
+ default: return Error(IntTok.getLoc(), "invalid stack index");
+ }
+
+ if (getParser().Lex().isNot(AsmToken::RParen))
+ return Error(Parser.getTok().getLoc(), "expected ')'");
+
+ EndLoc = Tok.getLoc();
+ Parser.Lex(); // Eat ')'
+ return false;
+ }
+
if (RegNo == 0)
return Error(Tok.getLoc(), "invalid register name");
@@ -300,8 +377,8 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() {
// We have to disambiguate a parenthesized expression "(4+5)" from the start
// of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
- // only way to do this without lookahead is to eat the ( and see what is after
- // it.
+ // only way to do this without lookahead is to eat the '(' and see what is
+ // after it.
const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
if (getLexer().isNot(AsmToken::LParen)) {
SMLoc ExprEnd;
@@ -312,7 +389,7 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() {
if (getLexer().isNot(AsmToken::LParen)) {
// Unless we have a segment register, treat this as an immediate.
if (SegReg == 0)
- return X86Operand::CreateImm(Disp, MemStart, ExprEnd);
+ return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
}
@@ -339,7 +416,7 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() {
if (getLexer().isNot(AsmToken::LParen)) {
// Unless we have a segment register, treat this as an immediate.
if (SegReg == 0)
- return X86Operand::CreateImm(Disp, LParenLoc, ExprEnd);
+ return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
}
@@ -424,8 +501,20 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() {
bool X86ATTAsmParser::
ParseInstruction(const StringRef &Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
-
- Operands.push_back(X86Operand::CreateToken(Name, NameLoc));
+ // FIXME: Hack to recognize "sal..." and "rep..." for now. We need a way to
+ // represent alternative syntaxes in the .td file, without requiring
+ // instruction duplication.
+ StringRef PatchedName = StringSwitch<StringRef>(Name)
+ .Case("sal", "shl")
+ .Case("salb", "shlb")
+ .Case("sall", "shll")
+ .Case("salq", "shlq")
+ .Case("salw", "shlw")
+ .Case("repe", "rep")
+ .Case("repz", "rep")
+ .Case("repnz", "repne")
+ .Default(Name);
+ Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
if (getLexer().isNot(AsmToken::EndOfStatement)) {
diff --git a/lib/Target/X86/AsmPrinter/Makefile b/lib/Target/X86/AsmPrinter/Makefile
index 326a22f..2368761 100644
--- a/lib/Target/X86/AsmPrinter/Makefile
+++ b/lib/Target/X86/AsmPrinter/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMX86AsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' x86 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
index 804dbb9..1a35a49 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
@@ -18,17 +18,22 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include "X86GenInstrNames.inc"
using namespace llvm;
// Include the auto-generated portion of the assembly writer.
#define MachineInstr MCInst
-#define NO_ASM_WRITER_BOILERPLATE
+#define GET_INSTRUCTION_NAME
#include "X86GenAsmWriter.inc"
#undef MachineInstr
void X86ATTInstPrinter::printInst(const MCInst *MI) { printInstruction(MI); }
+StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const {
+ return getInstructionName(Opcode);
+}
+
void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op) {
switch (MI->getOperand(Op).getImm()) {
@@ -66,6 +71,10 @@ void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo) {
O << '%' << getRegisterName(Op.getReg());
} else if (Op.isImm()) {
O << '$' << Op.getImm();
+
+ if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256))
+ *CommentStream << format("imm = 0x%X\n", Op.getImm());
+
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
O << '$' << *Op.getExpr();
diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h
index 3180618..d109a07 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h
@@ -26,11 +26,12 @@ public:
virtual void printInst(const MCInst *MI);
-
+ virtual StringRef getOpcodeName(unsigned Opcode) const;
+
// Autogenerated by tblgen.
void printInstruction(const MCInst *MI);
static const char *getRegisterName(unsigned RegNo);
-
+ static const char *getInstructionName(unsigned Opcode);
void printOperand(const MCInst *MI, unsigned OpNo);
void printMemReference(const MCInst *MI, unsigned Op);
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
index 2ffa18f..8cab24c 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
@@ -8,12 +8,10 @@
//===----------------------------------------------------------------------===//
//
// 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'.
+// of machine-dependent LLVM code to X86 machine code.
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "asm-printer"
#include "X86AsmPrinter.h"
#include "X86ATTInstPrinter.h"
#include "X86IntelInstPrinter.h"
@@ -29,169 +27,70 @@
#include "llvm/Type.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/Statistic.h"
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
//===----------------------------------------------------------------------===//
// Primitive Helper Functions.
//===----------------------------------------------------------------------===//
-void X86AsmPrinter::printMCInst(const MCInst *MI) {
- if (MAI->getAssemblerDialect() == 0)
- X86ATTInstPrinter(O, *MAI).printInstruction(MI);
- else
- X86IntelInstPrinter(O, *MAI).printInstruction(MI);
-}
-
void X86AsmPrinter::PrintPICBaseSymbol() const {
- // FIXME: Gross const cast hack.
- X86AsmPrinter *AP = const_cast<X86AsmPrinter*>(this);
- O << *X86MCInstLower(OutContext, 0, *AP).GetPICBaseSymbol();
+ const TargetLowering *TLI = TM.getTargetLowering();
+ O << *static_cast<const X86TargetLowering*>(TLI)->getPICBaseSymbol(MF,
+ OutContext);
}
-void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
- unsigned FnAlign = MF.getAlignment();
- const Function *F = MF.getFunction();
+MCSymbol *X86AsmPrinter::GetGlobalValueSymbol(const GlobalValue *GV) const {
+ SmallString<60> NameStr;
+ Mang->getNameWithPrefix(NameStr, GV, false);
+ MCSymbol *Symb = OutContext.GetOrCreateSymbol(NameStr.str());
if (Subtarget->isTargetCygMing()) {
- X86COFFMachineModuleInfo &COFFMMI =
+ X86COFFMachineModuleInfo &COFFMMI =
MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(CurrentFnSym, OutContext, F,
- *TM.getTargetData());
- }
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
- EmitAlignment(FnAlign, F);
-
- switch (F->getLinkage()) {
- default: llvm_unreachable("Unknown linkage type!");
- case Function::InternalLinkage: // Symbols default to internal.
- case Function::PrivateLinkage:
- break;
- case Function::DLLExportLinkage:
- case Function::ExternalLinkage:
- OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
- break;
- case Function::LinkerPrivateLinkage:
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- if (Subtarget->isTargetDarwin()) {
- OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
- O << MAI->getWeakDefDirective() << *CurrentFnSym << '\n';
- } else if (Subtarget->isTargetCygMing()) {
- OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
- O << "\t.linkonce discard\n";
- } else {
- O << "\t.weak\t" << *CurrentFnSym << '\n';
- }
- break;
- }
+ COFFMMI.DecorateCygMingName(Symb, OutContext, GV, *TM.getTargetData());
- printVisibility(CurrentFnSym, F->getVisibility());
+ // Save function name for later type emission.
+ if (const Function *F = dyn_cast<Function>(GV))
+ if (F->isDeclaration())
+ COFFMMI.addExternalFunction(Symb->getName());
- if (Subtarget->isTargetELF()) {
- O << "\t.type\t" << *CurrentFnSym << ",@function\n";
- } else if (Subtarget->isTargetCygMing()) {
- O << "\t.def\t " << *CurrentFnSym;
- O << ";\t.scl\t" <<
- (F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT)
- << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
- << ";\t.endef\n";
}
- O << *CurrentFnSym << ':';
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, F, /*PrintType=*/false, F->getParent());
- }
- O << '\n';
-
- // Add some workaround for linkonce linkage on Cygwin\MinGW
- if (Subtarget->isTargetCygMing() &&
- (F->hasLinkOnceLinkage() || F->hasWeakLinkage()))
- O << "Lllvm$workaround$fake$stub$" << *CurrentFnSym << ":\n";
+ return Symb;
}
-/// runOnMachineFunction - This uses the printMachineInstruction()
-/// method to print assembly for each instruction.
+/// runOnMachineFunction - Emit the function body.
///
bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
- const Function *F = MF.getFunction();
- this->MF = &MF;
- CallingConv::ID CC = F->getCallingConv();
-
SetupMachineFunction(MF);
- O << "\n\n";
if (Subtarget->isTargetCOFF()) {
- X86COFFMachineModuleInfo &COFFMMI =
- MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
-
- // Populate function information map. Don't want to populate
- // non-stdcall or non-fastcall functions' information right now.
- if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall)
- COFFMMI.AddFunctionInfo(F, *MF.getInfo<X86MachineFunctionInfo>());
- }
-
- // Print out constants referenced by the function
- EmitConstantPool(MF.getConstantPool());
-
- // Print the 'header' of function
- emitFunctionHeader(MF);
-
- // Emit pre-function debug and/or EH information.
- if (MAI->doesSupportDebugInformation() || MAI->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.
- EmitBasicBlockStart(I);
- 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";
+ const Function *F = MF.getFunction();
+ O << "\t.def\t " << *CurrentFnSym << ";\t.scl\t" <<
+ (F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT)
+ << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
+ << ";\t.endef\n";
}
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
+ // Have common code print out the function header with linkage info etc.
+ EmitFunctionHeader();
- // Emit post-function debug information.
- if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
- DW->EndFunction(&MF);
-
- // Print out jump tables referenced by the function.
- EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
+ // Emit the rest of the function body.
+ EmitFunctionBody();
// We didn't modify anything.
return false;
@@ -223,12 +122,6 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
else
GVSym = GetGlobalValueSymbol(GV);
- if (Subtarget->isTargetCygMing()) {
- X86COFFMachineModuleInfo &COFFMMI =
- MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(GVSym, OutContext, GV, *TM.getTargetData());
- }
-
// Handle dllimport linkage.
if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName());
@@ -237,20 +130,20 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
- const MCSymbol *&StubSym =
+ MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
if (StubSym == 0)
StubSym = GetGlobalValueSymbol(GV);
} else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
- const MCSymbol *&StubSym =
+ MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(Sym);
if (StubSym == 0)
StubSym = GetGlobalValueSymbol(GV);
} else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
- const MCSymbol *&StubSym =
+ MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
if (StubSym == 0)
StubSym = GetGlobalValueSymbol(GV);
@@ -272,8 +165,8 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
TempNameStr += StringRef(MO.getSymbolName());
TempNameStr += StringRef("$stub");
- const MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
- const MCSymbol *&StubSym =
+ MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
+ MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
if (StubSym == 0) {
TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end());
@@ -338,7 +231,7 @@ void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
return;
case MachineOperand::MO_GlobalAddress:
case MachineOperand::MO_ExternalSymbol:
@@ -451,30 +344,6 @@ void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
printLeaMemReference(MI, Op, Modifier);
}
-void X86AsmPrinter::printPICJumpTableSetLabel(unsigned uid,
- const MachineBasicBlock *MBB) const {
- if (!MAI->getSetDirective())
- return;
-
- // We don't need .set machinery if we have GOT-style relocations
- if (Subtarget->isPICStyleGOT())
- return;
-
- O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix()
- << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ',';
-
- O << *GetMBBSymbol(MBB->getNumber());
-
- if (Subtarget->isPICStyleRIPRel())
- O << '-' << *GetJTISymbol(uid) << '\n';
- else {
- O << '-';
- PrintPICBaseSymbol();
- O << '\n';
- }
-}
-
-
void X86AsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
PrintPICBaseSymbol();
O << '\n';
@@ -482,23 +351,6 @@ void X86AsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
O << ':';
}
-void X86AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
- const MachineBasicBlock *MBB,
- unsigned uid) const {
- const char *JTEntryDirective = MJTI->getEntrySize() == 4 ?
- MAI->getData32bitsDirective() : MAI->getData64bitsDirective();
-
- O << JTEntryDirective << ' ';
-
- if (Subtarget->isPICStyleRIPRel() || Subtarget->isPICStyleStubPIC()) {
- O << MAI->getPrivateGlobalPrefix() << getFunctionNumber()
- << '_' << uid << "_set_" << MBB->getNumber();
- } else if (Subtarget->isPICStyleGOT())
- O << *GetMBBSymbol(MBB->getNumber()) << "@GOTOFF";
- else
- O << *GetMBBSymbol(MBB->getNumber());
-}
-
bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode) {
unsigned Reg = MO.getReg();
switch (Mode) {
@@ -625,24 +477,6 @@ bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
}
-
-/// printMachineInstruction -- Print out a single X86 LLVM instruction MI in
-/// AT&T syntax to the current output stream.
-///
-void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
- ++EmittedInsts;
-
- processDebugLoc(MI, true);
-
- printInstructionThroughMCStreamer(MI);
-
- if (VerboseAsm)
- EmitComments(*MI);
- O << '\n';
-
- processDebugLoc(MI, false);
-}
-
void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
if (Subtarget->isTargetDarwin()) {
// All darwin targets use mach-o.
@@ -666,14 +500,17 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
OutStreamer.SwitchSection(TheSection);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- O << *Stubs[i].first << ":\n";
- // Get the MCSymbol without the $stub suffix.
- O << "\t.indirect_symbol " << *Stubs[i].second;
- O << "\n\thlt ; hlt ; hlt ; hlt ; hlt\n";
+ // L_foo$stub:
+ OutStreamer.EmitLabel(Stubs[i].first);
+ // .indirect_symbol _foo
+ OutStreamer.EmitSymbolAttribute(Stubs[i].second, MCSA_IndirectSymbol);
+ // hlt; hlt; hlt; hlt; hlt hlt = 0xf4 = -12.
+ const char HltInsts[] = { -12, -12, -12, -12, -12 };
+ OutStreamer.EmitBytes(StringRef(HltInsts, 5), 0/*addrspace*/);
}
- O << '\n';
Stubs.clear();
+ OutStreamer.AddBlankLine();
}
// Output stubs for external and common global variables.
@@ -686,10 +523,15 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
OutStreamer.SwitchSection(TheSection);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- O << *Stubs[i].first << ":\n\t.indirect_symbol " << *Stubs[i].second;
- O << "\n\t.long\t0\n";
+ // L_foo$non_lazy_ptr:
+ OutStreamer.EmitLabel(Stubs[i].first);
+ // .indirect_symbol _foo
+ OutStreamer.EmitSymbolAttribute(Stubs[i].second, MCSA_IndirectSymbol);
+ // .long 0
+ OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
}
Stubs.clear();
+ OutStreamer.AddBlankLine();
}
Stubs = MMIMacho.GetHiddenGVStubList();
@@ -698,10 +540,15 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
EmitAlignment(2);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- O << *Stubs[i].first << ":\n" << MAI->getData32bitsDirective();
- O << *Stubs[i].second << '\n';
+ // L_foo$non_lazy_ptr:
+ OutStreamer.EmitLabel(Stubs[i].first);
+ // .long _foo
+ OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second,
+ OutContext),
+ 4/*size*/, 0/*addrspace*/);
}
Stubs.clear();
+ OutStreamer.AddBlankLine();
}
// Funny Darwin hack: This flag tells the linker that no global symbols
@@ -735,7 +582,6 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
if (I->hasDLLExportLinkage()) {
MCSymbol *Sym = GetGlobalValueSymbol(I);
- COFFMMI.DecorateCygMingName(Sym, OutContext, I, *TM.getTargetData());
DLLExportedFns.push_back(Sym);
}
@@ -757,6 +603,28 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
}
}
}
+
+ if (Subtarget->isTargetELF()) {
+ TargetLoweringObjectFileELF &TLOFELF =
+ static_cast<TargetLoweringObjectFileELF &>(getObjFileLowering());
+
+ MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
+
+ // Output stubs for external and common global variables.
+ MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
+ if (!Stubs.empty()) {
+ OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
+ const TargetData *TD = TM.getTargetData();
+
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i)
+ O << *Stubs[i].first << ":\n"
+ << (TD->getPointerSize() == 8 ?
+ MAI->getData64bitsDirective() : MAI->getData32bitsDirective())
+ << *Stubs[i].second << '\n';
+
+ Stubs.clear();
+ }
+ }
}
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
index 6a9262d..039214a 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
@@ -36,8 +36,9 @@ class VISIBILITY_HIDDEN X86AsmPrinter : public AsmPrinter {
const X86Subtarget *Subtarget;
public:
explicit X86AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V)
- : AsmPrinter(O, TM, T, V) {
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+ : AsmPrinter(O, TM, Ctx, Streamer, T) {
Subtarget = &TM.getSubtarget<X86Subtarget>();
}
@@ -57,14 +58,10 @@ class VISIBILITY_HIDDEN X86AsmPrinter : public AsmPrinter {
virtual void EmitEndOfAsmFile(Module &M);
- void printInstructionThroughMCStreamer(const MachineInstr *MI);
-
-
- void printMCInst(const MCInst *MI);
-
- void printSymbolOperand(const MachineOperand &MO);
-
+ virtual void EmitInstruction(const MachineInstr *MI);
+ void printSymbolOperand(const MachineOperand &MO);
+ virtual MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
// These methods are used by the tablegen'erated instruction printer.
void printOperand(const MachineInstr *MI, unsigned OpNo,
@@ -124,24 +121,12 @@ class VISIBILITY_HIDDEN X86AsmPrinter : public AsmPrinter {
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 PrintPICBaseSymbol() const;
bool runOnMachineFunction(MachineFunction &F);
-
- void emitFunctionHeader(const MachineFunction &MF);
-
};
} // end namespace llvm
diff --git a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
index 4efb529..610beb5 100644
--- a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
@@ -24,11 +24,14 @@ using namespace llvm;
// Include the auto-generated portion of the assembly writer.
#define MachineInstr MCInst
-#define NO_ASM_WRITER_BOILERPLATE
+#define GET_INSTRUCTION_NAME
#include "X86GenAsmWriter1.inc"
#undef MachineInstr
void X86IntelInstPrinter::printInst(const MCInst *MI) { printInstruction(MI); }
+StringRef X86IntelInstPrinter::getOpcodeName(unsigned Opcode) const {
+ return getInstructionName(Opcode);
+}
void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op) {
switch (MI->getOperand(Op).getImm()) {
diff --git a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
index 1976177..545bf84 100644
--- a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
@@ -26,10 +26,12 @@ public:
: MCInstPrinter(O, MAI) {}
virtual void printInst(const MCInst *MI);
+ virtual StringRef getOpcodeName(unsigned Opcode) const;
// Autogenerated by tblgen.
void printInstruction(const MCInst *MI);
static const char *getRegisterName(unsigned RegNo);
+ static const char *getInstructionName(unsigned Opcode);
void printOperand(const MCInst *MI, unsigned OpNo,
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
index b970d46..fa8d13d 100644
--- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
+++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
@@ -14,8 +14,9 @@
#include "X86MCInstLower.h"
#include "X86AsmPrinter.h"
-#include "X86MCAsmInfo.h"
#include "X86COFFMachineModuleInfo.h"
+#include "X86MCAsmInfo.h"
+#include "X86MCTargetExpr.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCContext.h"
@@ -25,6 +26,7 @@
#include "llvm/Target/Mangler.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Type.h"
using namespace llvm;
@@ -39,37 +41,45 @@ MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const {
MCSymbol *X86MCInstLower::GetPICBaseSymbol() const {
- return Ctx.GetOrCreateSymbol(Twine(AsmPrinter.MAI->getPrivateGlobalPrefix())+
- Twine(AsmPrinter.getFunctionNumber())+"$pb");
+ const TargetLowering *TLI = AsmPrinter.TM.getTargetLowering();
+ return static_cast<const X86TargetLowering*>(TLI)->
+ getPICBaseSymbol(AsmPrinter.MF, Ctx);
}
-/// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an
-/// MCOperand.
+/// GetSymbolFromOperand - Lower an MO_GlobalAddress or MO_ExternalSymbol
+/// operand to an MCSymbol.
MCSymbol *X86MCInstLower::
-GetGlobalAddressSymbol(const MachineOperand &MO) const {
- const GlobalValue *GV = MO.getGlobal();
-
- bool isImplicitlyPrivate = false;
- if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB ||
- MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
- MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
- MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
- isImplicitlyPrivate = true;
-
+GetSymbolFromOperand(const MachineOperand &MO) const {
+ assert((MO.isGlobal() || MO.isSymbol()) && "Isn't a symbol reference");
+
SmallString<128> Name;
- Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
- if (getSubtarget().isTargetCygMing()) {
- X86COFFMachineModuleInfo &COFFMMI =
- AsmPrinter.MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(Name, GV, *AsmPrinter.TM.getTargetData());
- }
+ if (MO.isGlobal()) {
+ bool isImplicitlyPrivate = false;
+ if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB ||
+ MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
+ MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
+ MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
+ isImplicitlyPrivate = true;
+
+ const GlobalValue *GV = MO.getGlobal();
+ Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
+ if (getSubtarget().isTargetCygMing()) {
+ X86COFFMachineModuleInfo &COFFMMI =
+ AsmPrinter.MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
+ COFFMMI.DecorateCygMingName(Name, GV, *AsmPrinter.TM.getTargetData());
+ }
+ } else {
+ assert(MO.isSymbol());
+ Name += AsmPrinter.MAI->getGlobalPrefix();
+ Name += MO.getSymbolName();
+ }
+
+ // If the target flags on the operand changes the name of the symbol, do that
+ // before we return the symbol.
switch (MO.getTargetFlags()) {
- default: llvm_unreachable("Unknown target flag on GV operand");
- case X86II::MO_NO_FLAG: // No flag.
- case X86II::MO_PIC_BASE_OFFSET: // Doesn't modify symbol name.
- break;
+ default: break;
case X86II::MO_DLLIMPORT: {
// Handle dllimport linkage.
const char *Prefix = "__imp_";
@@ -81,190 +91,72 @@ GetGlobalAddressSymbol(const MachineOperand &MO) const {
Name += "$non_lazy_ptr";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
- const MCSymbol *&StubSym = getMachOMMI().getGVStubEntry(Sym);
- if (StubSym == 0)
- StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
+ MCSymbol *&StubSym = getMachOMMI().getGVStubEntry(Sym);
+ if (StubSym == 0) {
+ assert(MO.isGlobal() && "Extern symbol not handled yet");
+ StubSym = AsmPrinter.GetGlobalValueSymbol(MO.getGlobal());
+ }
return Sym;
}
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
Name += "$non_lazy_ptr";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
- const MCSymbol *&StubSym = getMachOMMI().getHiddenGVStubEntry(Sym);
- if (StubSym == 0)
- StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
+ MCSymbol *&StubSym = getMachOMMI().getHiddenGVStubEntry(Sym);
+ if (StubSym == 0) {
+ assert(MO.isGlobal() && "Extern symbol not handled yet");
+ StubSym = AsmPrinter.GetGlobalValueSymbol(MO.getGlobal());
+ }
return Sym;
}
case X86II::MO_DARWIN_STUB: {
Name += "$stub";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
- const MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym);
- if (StubSym == 0)
- StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
- return Sym;
- }
- // FIXME: These probably should be a modifier on the symbol or something??
- case X86II::MO_TLSGD: Name += "@TLSGD"; break;
- case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break;
- case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break;
- case X86II::MO_TPOFF: Name += "@TPOFF"; break;
- case X86II::MO_NTPOFF: Name += "@NTPOFF"; break;
- case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break;
- case X86II::MO_GOT: Name += "@GOT"; break;
- case X86II::MO_GOTOFF: Name += "@GOTOFF"; break;
- case X86II::MO_PLT: Name += "@PLT"; break;
- }
-
- return Ctx.GetOrCreateSymbol(Name.str());
-}
-
-MCSymbol *X86MCInstLower::
-GetExternalSymbolSymbol(const MachineOperand &MO) const {
- SmallString<128> Name;
- Name += AsmPrinter.MAI->getGlobalPrefix();
- Name += MO.getSymbolName();
-
- switch (MO.getTargetFlags()) {
- default: llvm_unreachable("Unknown target flag on GV operand");
- case X86II::MO_NO_FLAG: // No flag.
- case X86II::MO_GOT_ABSOLUTE_ADDRESS: // Doesn't modify symbol name.
- case X86II::MO_PIC_BASE_OFFSET: // Doesn't modify symbol name.
- break;
- case X86II::MO_DLLIMPORT: {
- // Handle dllimport linkage.
- const char *Prefix = "__imp_";
- Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix));
- break;
- }
- case X86II::MO_DARWIN_STUB: {
- Name += "$stub";
- MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
- const MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym);
-
- if (StubSym == 0) {
+ MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym);
+ if (StubSym)
+ return Sym;
+
+ if (MO.isGlobal()) {
+ StubSym = AsmPrinter.GetGlobalValueSymbol(MO.getGlobal());
+ } else {
Name.erase(Name.end()-5, Name.end());
StubSym = Ctx.GetOrCreateSymbol(Name.str());
}
return Sym;
}
- // FIXME: These probably should be a modifier on the symbol or something??
- case X86II::MO_TLSGD: Name += "@TLSGD"; break;
- case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break;
- case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break;
- case X86II::MO_TPOFF: Name += "@TPOFF"; break;
- case X86II::MO_NTPOFF: Name += "@NTPOFF"; break;
- case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break;
- case X86II::MO_GOT: Name += "@GOT"; break;
- case X86II::MO_GOTOFF: Name += "@GOTOFF"; break;
- case X86II::MO_PLT: Name += "@PLT"; break;
- }
-
- return Ctx.GetOrCreateSymbol(Name.str());
-}
-
-MCSymbol *X86MCInstLower::GetJumpTableSymbol(const MachineOperand &MO) const {
- SmallString<256> Name;
- // FIXME: Use AsmPrinter.GetJTISymbol. @TLSGD shouldn't be part of the symbol
- // name!
- raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "JTI"
- << AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
-
- switch (MO.getTargetFlags()) {
- default:
- llvm_unreachable("Unknown target flag on GV operand");
- case X86II::MO_NO_FLAG: // No flag.
- case X86II::MO_PIC_BASE_OFFSET:
- case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
- case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
- break;
- // FIXME: These probably should be a modifier on the symbol or something??
- case X86II::MO_TLSGD: Name += "@TLSGD"; break;
- case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break;
- case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break;
- case X86II::MO_TPOFF: Name += "@TPOFF"; break;
- case X86II::MO_NTPOFF: Name += "@NTPOFF"; break;
- case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break;
- case X86II::MO_GOT: Name += "@GOT"; break;
- case X86II::MO_GOTOFF: Name += "@GOTOFF"; break;
- case X86II::MO_PLT: Name += "@PLT"; break;
}
-
- // Create a symbol for the name.
- return Ctx.GetOrCreateSymbol(Name.str());
-}
-
-MCSymbol *X86MCInstLower::
-GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
- SmallString<256> Name;
- // FIXME: USe AsmPrinter.GetCPISymbol. @TLSGD shouldn't be part of the symbol
- // name!
- raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "CPI"
- << AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
-
- switch (MO.getTargetFlags()) {
- default:
- llvm_unreachable("Unknown target flag on GV operand");
- case X86II::MO_NO_FLAG: // No flag.
- case X86II::MO_PIC_BASE_OFFSET:
- case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
- case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
- break;
- // FIXME: These probably should be a modifier on the symbol or something??
- case X86II::MO_TLSGD: Name += "@TLSGD"; break;
- case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break;
- case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break;
- case X86II::MO_TPOFF: Name += "@TPOFF"; break;
- case X86II::MO_NTPOFF: Name += "@NTPOFF"; break;
- case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break;
- case X86II::MO_GOT: Name += "@GOT"; break;
- case X86II::MO_GOTOFF: Name += "@GOTOFF"; break;
- case X86II::MO_PLT: Name += "@PLT"; break;
- }
-
- // Create a symbol for the name.
return Ctx.GetOrCreateSymbol(Name.str());
}
-MCSymbol *X86MCInstLower::
-GetBlockAddressSymbol(const MachineOperand &MO) const {
- const char *Suffix = "";
- switch (MO.getTargetFlags()) {
- default: llvm_unreachable("Unknown target flag on BA operand");
- case X86II::MO_NO_FLAG: break; // No flag.
- case X86II::MO_PIC_BASE_OFFSET: break; // Doesn't modify symbol name.
- case X86II::MO_GOTOFF: Suffix = "@GOTOFF"; break;
- }
-
- return AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress(), Suffix);
-}
-
MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
MCSymbol *Sym) const {
// FIXME: We would like an efficient form for this, so we don't have to do a
// lot of extra uniquing.
- const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
+ const MCExpr *Expr = 0;
+ X86MCTargetExpr::VariantKind RefKind = X86MCTargetExpr::Invalid;
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
case X86II::MO_NO_FLAG: // No flag.
-
// These affect the name of the symbol, not any suffix.
case X86II::MO_DARWIN_NONLAZY:
case X86II::MO_DLLIMPORT:
case X86II::MO_DARWIN_STUB:
- case X86II::MO_TLSGD:
- case X86II::MO_GOTTPOFF:
- case X86II::MO_INDNTPOFF:
- case X86II::MO_TPOFF:
- case X86II::MO_NTPOFF:
- case X86II::MO_GOTPCREL:
- case X86II::MO_GOT:
- case X86II::MO_GOTOFF:
- case X86II::MO_PLT:
break;
+
+ case X86II::MO_TLSGD: RefKind = X86MCTargetExpr::TLSGD; break;
+ case X86II::MO_GOTTPOFF: RefKind = X86MCTargetExpr::GOTTPOFF; break;
+ case X86II::MO_INDNTPOFF: RefKind = X86MCTargetExpr::INDNTPOFF; break;
+ case X86II::MO_TPOFF: RefKind = X86MCTargetExpr::TPOFF; break;
+ case X86II::MO_NTPOFF: RefKind = X86MCTargetExpr::NTPOFF; break;
+ case X86II::MO_GOTPCREL: RefKind = X86MCTargetExpr::GOTPCREL; break;
+ case X86II::MO_GOT: RefKind = X86MCTargetExpr::GOT; break;
+ case X86II::MO_GOTOFF: RefKind = X86MCTargetExpr::GOTOFF; break;
+ case X86II::MO_PLT: RefKind = X86MCTargetExpr::PLT; break;
case X86II::MO_PIC_BASE_OFFSET:
case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
+ Expr = MCSymbolRefExpr::Create(Sym, Ctx);
// Subtract the pic base.
Expr = MCBinaryExpr::CreateSub(Expr,
MCSymbolRefExpr::Create(GetPICBaseSymbol(), Ctx),
@@ -272,6 +164,13 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
break;
}
+ if (Expr == 0) {
+ if (RefKind == X86MCTargetExpr::Invalid)
+ Expr = MCSymbolRefExpr::Create(Sym, Ctx);
+ else
+ Expr = X86MCTargetExpr::Create(Sym, RefKind, Ctx);
+ }
+
if (!MO.isJTI() && MO.getOffset())
Expr = MCBinaryExpr::CreateAdd(Expr,
MCConstantExpr::Create(MO.getOffset(), Ctx),
@@ -300,6 +199,17 @@ static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) {
}
}
+/// LowerSubReg32_Op0 - Things like MOVZX16rr8 -> MOVZX32rr8.
+static void LowerSubReg32_Op0(MCInst &OutMI, unsigned NewOpc) {
+ OutMI.setOpcode(NewOpc);
+ lower_subreg32(&OutMI, 0);
+}
+/// LowerUnaryToTwoAddr - R = setb -> R = sbb R, R
+static void LowerUnaryToTwoAddr(MCInst &OutMI, unsigned NewOpc) {
+ OutMI.setOpcode(NewOpc);
+ OutMI.addOperand(OutMI.getOperand(0));
+ OutMI.addOperand(OutMI.getOperand(0));
+}
void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
@@ -323,22 +233,23 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
- AsmPrinter.GetMBBSymbol(MO.getMBB()->getNumber()), Ctx));
+ MO.getMBB()->getSymbol(Ctx), Ctx));
break;
case MachineOperand::MO_GlobalAddress:
- MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
+ MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
break;
case MachineOperand::MO_ExternalSymbol:
- MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
+ MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
break;
case MachineOperand::MO_JumpTableIndex:
- MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
+ MCOp = LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));
break;
case MachineOperand::MO_ConstantPoolIndex:
- MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
+ MCOp = LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));
break;
case MachineOperand::MO_BlockAddress:
- MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
+ MCOp = LowerSymbolOperand(MO,
+ AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));
break;
}
@@ -350,72 +261,48 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand.
lower_lea64_32mem(&OutMI, 1);
break;
- case X86::MOVZX16rr8:
- OutMI.setOpcode(X86::MOVZX32rr8);
- lower_subreg32(&OutMI, 0);
- break;
- case X86::MOVZX16rm8:
- OutMI.setOpcode(X86::MOVZX32rm8);
- lower_subreg32(&OutMI, 0);
- break;
- case X86::MOVSX16rr8:
- OutMI.setOpcode(X86::MOVSX32rr8);
- lower_subreg32(&OutMI, 0);
- break;
- case X86::MOVSX16rm8:
- OutMI.setOpcode(X86::MOVSX32rm8);
- lower_subreg32(&OutMI, 0);
- break;
- case X86::MOVZX64rr32:
- OutMI.setOpcode(X86::MOV32rr);
- lower_subreg32(&OutMI, 0);
- break;
- case X86::MOVZX64rm32:
- OutMI.setOpcode(X86::MOV32rm);
- lower_subreg32(&OutMI, 0);
- break;
- case X86::MOV64ri64i32:
- OutMI.setOpcode(X86::MOV32ri);
- lower_subreg32(&OutMI, 0);
- break;
- case X86::MOVZX64rr8:
- OutMI.setOpcode(X86::MOVZX32rr8);
- lower_subreg32(&OutMI, 0);
- break;
- case X86::MOVZX64rm8:
- OutMI.setOpcode(X86::MOVZX32rm8);
- lower_subreg32(&OutMI, 0);
- break;
- case X86::MOVZX64rr16:
- OutMI.setOpcode(X86::MOVZX32rr16);
- lower_subreg32(&OutMI, 0);
- break;
- case X86::MOVZX64rm16:
- OutMI.setOpcode(X86::MOVZX32rm16);
- lower_subreg32(&OutMI, 0);
- break;
+ case X86::MOVZX16rr8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr8); break;
+ case X86::MOVZX16rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break;
+ case X86::MOVSX16rr8: LowerSubReg32_Op0(OutMI, X86::MOVSX32rr8); break;
+ case X86::MOVSX16rm8: LowerSubReg32_Op0(OutMI, X86::MOVSX32rm8); break;
+ case X86::MOVZX64rr32: LowerSubReg32_Op0(OutMI, X86::MOV32rr); break;
+ case X86::MOVZX64rm32: LowerSubReg32_Op0(OutMI, X86::MOV32rm); break;
+ case X86::MOV64ri64i32: LowerSubReg32_Op0(OutMI, X86::MOV32ri); break;
+ case X86::MOVZX64rr8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr8); break;
+ case X86::MOVZX64rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break;
+ case X86::MOVZX64rr16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr16); break;
+ case X86::MOVZX64rm16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm16); break;
+ case X86::SETB_C8r: LowerUnaryToTwoAddr(OutMI, X86::SBB8rr); break;
+ case X86::SETB_C16r: LowerUnaryToTwoAddr(OutMI, X86::SBB16rr); break;
+ case X86::SETB_C32r: LowerUnaryToTwoAddr(OutMI, X86::SBB32rr); break;
+ case X86::SETB_C64r: LowerUnaryToTwoAddr(OutMI, X86::SBB64rr); break;
+ case X86::MOV8r0: LowerUnaryToTwoAddr(OutMI, X86::XOR8rr); break;
+ case X86::MOV32r0: LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); break;
+ case X86::MMX_V_SET0: LowerUnaryToTwoAddr(OutMI, X86::MMX_PXORrr); break;
+ case X86::MMX_V_SETALLONES:
+ LowerUnaryToTwoAddr(OutMI, X86::MMX_PCMPEQDrr); break;
+ case X86::FsFLD0SS: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break;
+ case X86::FsFLD0SD: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break;
+ case X86::V_SET0: LowerUnaryToTwoAddr(OutMI, X86::XORPSrr); break;
+ case X86::V_SETALLONES: LowerUnaryToTwoAddr(OutMI, X86::PCMPEQDrr); break;
+
case X86::MOV16r0:
- OutMI.setOpcode(X86::MOV32r0);
- lower_subreg32(&OutMI, 0);
+ LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV16r0 -> MOV32r0
+ LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr
break;
case X86::MOV64r0:
- OutMI.setOpcode(X86::MOV32r0);
- lower_subreg32(&OutMI, 0);
+ LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV64r0 -> MOV32r0
+ LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr
break;
}
}
-void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
+void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
X86MCInstLower MCInstLowering(OutContext, Mang, *this);
switch (MI->getOpcode()) {
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
- case TargetInstrInfo::GC_LABEL:
- printLabel(MI);
- return;
- case TargetInstrInfo::DEBUG_VALUE: {
+ case TargetOpcode::DBG_VALUE: {
// FIXME: if this is implemented for another target before it goes
// away completely, the common part should be moved into AsmPrinter.
if (!VerboseAsm)
@@ -427,9 +314,35 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
O << V.getName();
O << " <- ";
if (NOps==3) {
- // Variable is in register
- assert(MI->getOperand(0).getType()==MachineOperand::MO_Register);
- printOperand(MI, 0);
+ // Register or immediate value. Register 0 means undef.
+ assert(MI->getOperand(0).getType()==MachineOperand::MO_Register ||
+ MI->getOperand(0).getType()==MachineOperand::MO_Immediate ||
+ MI->getOperand(0).getType()==MachineOperand::MO_FPImmediate);
+ if (MI->getOperand(0).getType()==MachineOperand::MO_Register &&
+ MI->getOperand(0).getReg()==0) {
+ // Suppress offset in this case, it is not meaningful.
+ O << "undef";
+ OutStreamer.AddBlankLine();
+ return;
+ } else if (MI->getOperand(0).getType()==MachineOperand::MO_FPImmediate) {
+ // This is more naturally done in printOperand, but since the only use
+ // of such an operand is in this comment and that is temporary (and it's
+ // ugly), we prefer to keep this localized.
+ // The include of Type.h may be removable when this code is.
+ if (MI->getOperand(0).getFPImm()->getType()->isFloatTy() ||
+ MI->getOperand(0).getFPImm()->getType()->isDoubleTy())
+ MI->getOperand(0).print(O, &TM);
+ else {
+ // There is no good way to print long double. Convert a copy to
+ // double. Ah well, it's only a comment.
+ bool ignored;
+ APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF());
+ APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
+ &ignored);
+ O << "(long double) " << APF.convertToDouble();
+ }
+ } else
+ printOperand(MI, 0);
} else {
// Frame address. Currently handles register +- offset only.
assert(MI->getOperand(0).getType()==MachineOperand::MO_Register);
@@ -438,17 +351,9 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
}
O << "+";
printOperand(MI, NOps-2);
+ OutStreamer.AddBlankLine();
return;
}
- case TargetInstrInfo::INLINEASM:
- printInlineAsm(MI);
- return;
- case TargetInstrInfo::IMPLICIT_DEF:
- printImplicitDef(MI);
- return;
- case TargetInstrInfo::KILL:
- printKill(MI);
- return;
case X86::MOVPC32r: {
MCInst TmpInst;
// This is a pseudo op for a two instruction sequence with a label, which
@@ -464,8 +369,7 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
// lot of extra uniquing.
TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase,
OutContext)));
- printMCInst(&TmpInst);
- O << '\n';
+ OutStreamer.EmitInstruction(TmpInst);
// Emit the label.
OutStreamer.EmitLabel(PICBase);
@@ -473,7 +377,7 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
// popl $reg
TmpInst.setOpcode(X86::POP32r);
TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg());
- printMCInst(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
return;
}
@@ -495,7 +399,7 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
OutStreamer.EmitLabel(DotSym);
// Now that we have emitted the label, lower the complex operand expression.
- MCSymbol *OpSym = MCInstLowering.GetExternalSymbolSymbol(MI->getOperand(2));
+ MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2));
const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
const MCExpr *PICBase =
@@ -510,7 +414,7 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
TmpInst.addOperand(MCOperand::CreateExpr(DotExpr));
- printMCInst(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
return;
}
}
@@ -518,7 +422,6 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
MCInst TmpInst;
MCInstLowering.Lower(MI, TmpInst);
-
- printMCInst(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
}
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.h b/lib/Target/X86/AsmPrinter/X86MCInstLower.h
index 94f8bfc..ebd23f6 100644
--- a/lib/Target/X86/AsmPrinter/X86MCInstLower.h
+++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.h
@@ -39,11 +39,7 @@ public:
MCSymbol *GetPICBaseSymbol() const;
- MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const;
- MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const;
- MCSymbol *GetJumpTableSymbol(const MachineOperand &MO) const;
- MCSymbol *GetConstantPoolIndexSymbol(const MachineOperand &MO) const;
- MCSymbol *GetBlockAddressSymbol(const MachineOperand &MO) const;
+ MCSymbol *GetSymbolFromOperand(const MachineOperand &MO) const;
MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
private:
diff --git a/lib/Target/X86/CMakeLists.txt b/lib/Target/X86/CMakeLists.txt
index 4186fec..61f26a7 100644
--- a/lib/Target/X86/CMakeLists.txt
+++ b/lib/Target/X86/CMakeLists.txt
@@ -25,6 +25,8 @@ set(sources
X86InstrInfo.cpp
X86JITInfo.cpp
X86MCAsmInfo.cpp
+ X86MCCodeEmitter.cpp
+ X86MCTargetExpr.cpp
X86RegisterInfo.cpp
X86Subtarget.cpp
X86TargetMachine.cpp
diff --git a/lib/Target/X86/Disassembler/Makefile b/lib/Target/X86/Disassembler/Makefile
index 6c26853..b289647 100644
--- a/lib/Target/X86/Disassembler/Makefile
+++ b/lib/Target/X86/Disassembler/Makefile
@@ -9,7 +9,6 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMX86Disassembler
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' x86 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/Makefile b/lib/Target/X86/Makefile
index 5e625dc..f4ff894 100644
--- a/lib/Target/X86/Makefile
+++ b/lib/Target/X86/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMX86CodeGen
TARGET = X86
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \
@@ -19,6 +18,7 @@ BUILT_SOURCES = X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \
X86GenAsmWriter1.inc X86GenDAGISel.inc \
X86GenDisassemblerTables.inc X86GenFastISel.inc \
X86GenCallingConv.inc X86GenSubtarget.inc \
+ X86GenEDInfo.inc
DIRS = AsmPrinter AsmParser Disassembler TargetInfo
diff --git a/lib/Target/X86/README-SSE.txt b/lib/Target/X86/README-SSE.txt
index 0f3e44b..19eb05e 100644
--- a/lib/Target/X86/README-SSE.txt
+++ b/lib/Target/X86/README-SSE.txt
@@ -376,7 +376,7 @@ ret
... saving two instructions.
The basic idea is that a reload from a spill slot, can, if only one 4-byte
-chunk is used, bring in 3 zeros the the one element instead of 4 elements.
+chunk is used, bring in 3 zeros the one element instead of 4 elements.
This can be used to simplify a variety of shuffle operations, where the
elements are fixed zeros.
@@ -936,3 +936,54 @@ Also, the 'ret's should be shared. This is PR6032.
//===---------------------------------------------------------------------===//
+These should compile into the same code (PR6214): Perhaps instcombine should
+canonicalize the former into the later?
+
+define float @foo(float %x) nounwind {
+ %t = bitcast float %x to i32
+ %s = and i32 %t, 2147483647
+ %d = bitcast i32 %s to float
+ ret float %d
+}
+
+declare float @fabsf(float %n)
+define float @bar(float %x) nounwind {
+ %d = call float @fabsf(float %x)
+ ret float %d
+}
+
+//===---------------------------------------------------------------------===//
+
+This IR (from PR6194):
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin10.0.0"
+
+%0 = type { double, double }
+%struct.float3 = type { float, float, float }
+
+define void @test(%0, %struct.float3* nocapture %res) nounwind noinline ssp {
+entry:
+ %tmp18 = extractvalue %0 %0, 0 ; <double> [#uses=1]
+ %tmp19 = bitcast double %tmp18 to i64 ; <i64> [#uses=1]
+ %tmp20 = zext i64 %tmp19 to i128 ; <i128> [#uses=1]
+ %tmp10 = lshr i128 %tmp20, 32 ; <i128> [#uses=1]
+ %tmp11 = trunc i128 %tmp10 to i32 ; <i32> [#uses=1]
+ %tmp12 = bitcast i32 %tmp11 to float ; <float> [#uses=1]
+ %tmp5 = getelementptr inbounds %struct.float3* %res, i64 0, i32 1 ; <float*> [#uses=1]
+ store float %tmp12, float* %tmp5
+ ret void
+}
+
+Compiles to:
+
+_test: ## @test
+ movd %xmm0, %rax
+ shrq $32, %rax
+ movl %eax, 4(%rdi)
+ ret
+
+This would be better kept in the SSE unit by treating XMM0 as a 4xfloat and
+doing a shuffle from v[1] to v[0] then a float store.
+
+//===---------------------------------------------------------------------===//
diff --git a/lib/Target/X86/README-UNIMPLEMENTED.txt b/lib/Target/X86/README-UNIMPLEMENTED.txt
index 69dc8ee..c26c75a 100644
--- a/lib/Target/X86/README-UNIMPLEMENTED.txt
+++ b/lib/Target/X86/README-UNIMPLEMENTED.txt
@@ -11,4 +11,4 @@ which would be great.
2) vector comparisons
3) vector fp<->int conversions: PR2683, PR2684, PR2685, PR2686, PR2688
4) bitcasts from vectors to scalars: PR2804
-
+5) llvm.atomic.cmp.swap.i128.p0i128: PR3462
diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt
index aa7bb3d..3c6138b 100644
--- a/lib/Target/X86/README.txt
+++ b/lib/Target/X86/README.txt
@@ -1868,3 +1868,69 @@ carried over to machine instructions. Asm printer (or JIT) can use this
information to add the "lock" prefix.
//===---------------------------------------------------------------------===//
+
+_Bool bar(int *x) { return *x & 1; }
+
+define zeroext i1 @bar(i32* nocapture %x) nounwind readonly {
+entry:
+ %tmp1 = load i32* %x ; <i32> [#uses=1]
+ %and = and i32 %tmp1, 1 ; <i32> [#uses=1]
+ %tobool = icmp ne i32 %and, 0 ; <i1> [#uses=1]
+ ret i1 %tobool
+}
+
+bar: # @bar
+# BB#0: # %entry
+ movl 4(%esp), %eax
+ movb (%eax), %al
+ andb $1, %al
+ movzbl %al, %eax
+ ret
+
+Missed optimization: should be movl+andl.
+
+//===---------------------------------------------------------------------===//
+
+Consider the following two functions compiled with clang:
+_Bool foo(int *x) { return !(*x & 4); }
+unsigned bar(int *x) { return !(*x & 4); }
+
+foo:
+ movl 4(%esp), %eax
+ testb $4, (%eax)
+ sete %al
+ movzbl %al, %eax
+ ret
+
+bar:
+ movl 4(%esp), %eax
+ movl (%eax), %eax
+ shrl $2, %eax
+ andl $1, %eax
+ xorl $1, %eax
+ ret
+
+The second function generates more code even though the two functions are
+are functionally identical.
+
+//===---------------------------------------------------------------------===//
+
+Take the following C code:
+int x(int y) { return (y & 63) << 14; }
+
+Code produced by gcc:
+ andl $63, %edi
+ sall $14, %edi
+ movl %edi, %eax
+ ret
+
+Code produced by clang:
+ shll $14, %edi
+ movl %edi, %eax
+ andl $1032192, %eax
+ ret
+
+The code produced by gcc is 3 bytes shorter. This sort of construct often
+shows up with bitfields.
+
+//===---------------------------------------------------------------------===//
diff --git a/lib/Target/X86/TargetInfo/Makefile b/lib/Target/X86/TargetInfo/Makefile
index 211607f..9858e6a 100644
--- a/lib/Target/X86/TargetInfo/Makefile
+++ b/lib/Target/X86/TargetInfo/Makefile
@@ -9,7 +9,6 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMX86Info
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
index 684c61f..1a1e447 100644
--- a/lib/Target/X86/X86.h
+++ b/lib/Target/X86/X86.h
@@ -23,6 +23,7 @@ class X86TargetMachine;
class FunctionPass;
class MachineCodeEmitter;
class MCCodeEmitter;
+class MCContext;
class JITCodeEmitter;
class Target;
class formatted_raw_ostream;
@@ -46,15 +47,13 @@ FunctionPass *createX87FPRegKillInserterPass();
/// createX86CodeEmitterPass - Return a pass that emits the collected X86 code
/// to the specified MCE object.
-
-FunctionPass *createX86CodeEmitterPass(X86TargetMachine &TM,
- MachineCodeEmitter &MCE);
FunctionPass *createX86JITCodeEmitterPass(X86TargetMachine &TM,
JITCodeEmitter &JCE);
-FunctionPass *createX86ObjectCodeEmitterPass(X86TargetMachine &TM,
- ObjectCodeEmitter &OCE);
-MCCodeEmitter *createX86MCCodeEmitter(const Target &, TargetMachine &TM);
+MCCodeEmitter *createX86_32MCCodeEmitter(const Target &, TargetMachine &TM,
+ MCContext &Ctx);
+MCCodeEmitter *createX86_64MCCodeEmitter(const Target &, TargetMachine &TM,
+ MCContext &Ctx);
/// createX86EmitCodeToMemory - Returns a pass that converts a register
/// allocated function into raw machine code in a dynamically
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.cpp b/lib/Target/X86/X86COFFMachineModuleInfo.cpp
index ea52795..ab67acb 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.cpp
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.cpp
@@ -27,90 +27,55 @@ X86COFFMachineModuleInfo::X86COFFMachineModuleInfo(const MachineModuleInfo &) {
X86COFFMachineModuleInfo::~X86COFFMachineModuleInfo() {
}
-void X86COFFMachineModuleInfo::AddFunctionInfo(const Function *F,
- const X86MachineFunctionInfo &Val) {
- FunctionInfoMap[F] = Val;
+void X86COFFMachineModuleInfo::addExternalFunction(const StringRef& Name) {
+ CygMingStubs.insert(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;
-}
-
-
-/// DecorateCygMingName - Query FunctionInfoMap and use this information for
-/// various name decorations for Cygwin and MingW.
+/// DecorateCygMingName - Apply various name decorations if the function uses
+/// stdcall or fastcall calling convention.
void X86COFFMachineModuleInfo::DecorateCygMingName(SmallVectorImpl<char> &Name,
const GlobalValue *GV,
const TargetData &TD) {
const Function *F = dyn_cast<Function>(GV);
if (!F) return;
-
- // Save function name for later type emission.
- if (F->isDeclaration())
- CygMingStubs.insert(StringRef(Name.data(), Name.size()));
-
+
// We don't want to decorate non-stdcall or non-fastcall functions right now
CallingConv::ID CC = F->getCallingConv();
if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
return;
-
- const X86MachineFunctionInfo *Info;
-
- FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
- if (info_item == FunctionInfoMap.end()) {
- // Calculate apropriate function info and populate map
- FunctionInfoMap[F] = calculateFunctionInfo(F, TD);
- Info = &FunctionInfoMap[F];
- } else {
- Info = &info_item->second;
- }
-
- if (Info->getDecorationStyle() == None) return;
+
+ unsigned ArgWords = 0;
+ DenseMap<const Function*, unsigned>::const_iterator item = FnArgWords.find(F);
+ if (item == FnArgWords.end()) {
+ // Calculate arguments sizes
+ for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+ AI != AE; ++AI) {
+ const Type* Ty = AI->getType();
+
+ // 'Dereference' type in case of byval parameter attribute
+ if (AI->hasByValAttr())
+ Ty = cast<PointerType>(Ty)->getElementType();
+
+ // Size should be aligned to DWORD boundary
+ ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
+ }
+
+ FnArgWords[F] = ArgWords;
+ } else
+ ArgWords = item->second;
+
const FunctionType *FT = F->getFunctionType();
-
// "Pure" variadic functions do not receive @0 suffix.
if (!FT->isVarArg() || FT->getNumParams() == 0 ||
(FT->getNumParams() == 1 && F->hasStructRetAttr()))
- raw_svector_ostream(Name) << '@' << Info->getBytesToPopOnReturn();
-
- if (Info->getDecorationStyle() == FastCall) {
+ raw_svector_ostream(Name) << '@' << ArgWords;
+
+ if (CC == CallingConv::X86_FastCall) {
if (Name[0] == '_')
Name[0] = '@';
else
Name.insert(Name.begin(), '@');
- }
+ }
}
/// DecorateCygMingName - Query FunctionInfoMap and use this information for
@@ -121,6 +86,6 @@ void X86COFFMachineModuleInfo::DecorateCygMingName(MCSymbol *&Name,
const TargetData &TD) {
SmallString<128> NameStr(Name->getName().begin(), Name->getName().end());
DecorateCygMingName(NameStr, GV, TD);
-
+
Name = Ctx.GetOrCreateSymbol(NameStr.str());
}
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.h b/lib/Target/X86/X86COFFMachineModuleInfo.h
index 0e2009e..9de3dcd 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.h
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.h
@@ -21,44 +21,25 @@
namespace llvm {
class X86MachineFunctionInfo;
class TargetData;
-
+
/// X86COFFMachineModuleInfo - This is a MachineModuleInfoImpl implementation
/// for X86 COFF targets.
class X86COFFMachineModuleInfo : public MachineModuleInfoImpl {
StringSet<> CygMingStubs;
-
- // 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;
-
+ DenseMap<const Function*, unsigned> FnArgWords;
public:
X86COFFMachineModuleInfo(const MachineModuleInfo &);
~X86COFFMachineModuleInfo();
-
-
+
void DecorateCygMingName(MCSymbol* &Name, MCContext &Ctx,
const GlobalValue *GV, const TargetData &TD);
void DecorateCygMingName(SmallVectorImpl<char> &Name, const GlobalValue *GV,
const TargetData &TD);
-
- void AddFunctionInfo(const Function *F, const X86MachineFunctionInfo &Val);
-
+ void addExternalFunction(const StringRef& Name);
typedef StringSet<>::const_iterator stub_iterator;
stub_iterator stub_begin() const { return CygMingStubs.begin(); }
stub_iterator stub_end() const { return CygMingStubs.end(); }
-
-
};
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index 828e872..8deadf6 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -21,9 +21,7 @@
#include "X86.h"
#include "llvm/LLVMContext.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
-#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -110,19 +108,10 @@ template<class CodeEmitter>
/// createX86CodeEmitterPass - Return a pass that emits the collected X86 code
/// to the specified templated MachineCodeEmitter object.
-
-FunctionPass *llvm::createX86CodeEmitterPass(X86TargetMachine &TM,
- MachineCodeEmitter &MCE) {
- return new Emitter<MachineCodeEmitter>(TM, MCE);
-}
FunctionPass *llvm::createX86JITCodeEmitterPass(X86TargetMachine &TM,
JITCodeEmitter &JCE) {
return new Emitter<JITCodeEmitter>(TM, JCE);
}
-FunctionPass *llvm::createX86ObjectCodeEmitterPass(X86TargetMachine &TM,
- ObjectCodeEmitter &OCE) {
- return new Emitter<ObjectCodeEmitter>(TM, OCE);
-}
template<class CodeEmitter>
bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
@@ -202,8 +191,15 @@ template<class CodeEmitter>
void Emitter<CodeEmitter>::emitExternalSymbolAddress(const char *ES,
unsigned Reloc) {
intptr_t RelocCST = (Reloc == X86::reloc_picrel_word) ? PICBaseOffset : 0;
+
+ // X86 never needs stubs because instruction selection will always pick
+ // an instruction sequence that is large enough to hold any address
+ // to a symbol.
+ // (see X86ISelLowering.cpp, near 2039: X86TargetLowering::LowerCall)
+ bool NeedStub = false;
MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
- Reloc, ES, RelocCST));
+ Reloc, ES, RelocCST,
+ 0, NeedStub));
if (Reloc == X86::reloc_absolute_dword)
MCE.emitDWordLE(0);
else
@@ -253,7 +249,7 @@ void Emitter<CodeEmitter>::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
template<class CodeEmitter>
unsigned Emitter<CodeEmitter>::getX86RegNum(unsigned RegNo) const {
- return II->getRegisterInfo().getX86RegNum(RegNo);
+ return X86RegisterInfo::getX86RegNum(RegNo);
}
inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode,
@@ -391,86 +387,103 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
// If no BaseReg, issue a RIP relative instruction only if the MCE can
// resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
// 2-7) and absolute references.
- if ((!Is64BitMode || DispForReloc || BaseReg != 0) &&
+ unsigned BaseRegNo = -1U;
+ if (BaseReg != 0 && BaseReg != X86::RIP)
+ BaseRegNo = getX86RegNum(BaseReg);
+
+ if (// The SIB byte must be used if there is an index register.
IndexReg.getReg() == 0 &&
- ((BaseReg == 0 && MCE.earlyResolveAddresses()) || BaseReg == X86::RIP ||
- (BaseReg != 0 && getX86RegNum(BaseReg) != N86::ESP))) {
- if (BaseReg == 0 || BaseReg == X86::RIP) { // Just a displacement?
- // Emit special case [disp32] encoding
+ // The SIB byte must be used if the base is ESP/RSP/R12, all of which
+ // encode to an R/M value of 4, which indicates that a SIB byte is
+ // present.
+ BaseRegNo != N86::ESP &&
+ // If there is no base register and we're in 64-bit mode, we need a SIB
+ // byte to emit an addr that is just 'disp32' (the non-RIP relative form).
+ (!Is64BitMode || BaseReg != 0)) {
+ if (BaseReg == 0 || // [disp32] in X86-32 mode
+ BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode
MCE.emitByte(ModRMByte(0, RegOpcodeField, 5));
emitDisplacementField(DispForReloc, DispVal, PCAdj, true);
- } else {
- unsigned BaseRegNo = getX86RegNum(BaseReg);
- if (!DispForReloc && DispVal == 0 && BaseRegNo != N86::EBP) {
- // Emit simple indirect register encoding... [EAX] f.e.
- MCE.emitByte(ModRMByte(0, RegOpcodeField, BaseRegNo));
- } else if (!DispForReloc && isDisp8(DispVal)) {
- // Emit the disp8 encoding... [REG+disp8]
- MCE.emitByte(ModRMByte(1, RegOpcodeField, BaseRegNo));
- emitConstant(DispVal, 1);
- } else {
- // Emit the most general non-SIB encoding: [REG+disp32]
- MCE.emitByte(ModRMByte(2, RegOpcodeField, BaseRegNo));
- emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
- }
+ return;
}
-
- } else { // We need a SIB byte, so start by outputting the ModR/M byte first
- assert(IndexReg.getReg() != X86::ESP &&
- IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!");
-
- bool ForceDisp32 = false;
- bool ForceDisp8 = false;
- if (BaseReg == 0) {
- // If there is no base register, we emit the special case SIB byte with
- // MOD=0, BASE=5, to JUST get the index, scale, and displacement.
- MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
- ForceDisp32 = true;
- } else if (DispForReloc) {
- // Emit the normal disp32 encoding.
- MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
- ForceDisp32 = true;
- } else if (DispVal == 0 && getX86RegNum(BaseReg) != N86::EBP) {
- // Emit no displacement ModR/M byte
- MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
- } else if (isDisp8(DispVal)) {
- // Emit the disp8 encoding...
- MCE.emitByte(ModRMByte(1, RegOpcodeField, 4));
- ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
- } else {
- // Emit the normal disp32 encoding...
- MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
- }
-
- // Calculate what the SS field value should be...
- static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 };
- unsigned SS = SSTable[Scale.getImm()];
-
- if (BaseReg == 0) {
- // Handle the SIB byte for the case where there is no base, see Intel
- // Manual 2A, table 2-7. The displacement has already been output.
- unsigned IndexRegNo;
- if (IndexReg.getReg())
- IndexRegNo = getX86RegNum(IndexReg.getReg());
- else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
- IndexRegNo = 4;
- emitSIBByte(SS, IndexRegNo, 5);
- } else {
- unsigned BaseRegNo = getX86RegNum(BaseReg);
- unsigned IndexRegNo;
- if (IndexReg.getReg())
- IndexRegNo = getX86RegNum(IndexReg.getReg());
- else
- IndexRegNo = 4; // For example [ESP+1*<noreg>+4]
- emitSIBByte(SS, IndexRegNo, BaseRegNo);
+
+ // If the base is not EBP/ESP and there is no displacement, use simple
+ // indirect register encoding, this handles addresses like [EAX]. The
+ // encoding for [EBP] with no displacement means [disp32] so we handle it
+ // by emitting a displacement of 0 below.
+ if (!DispForReloc && DispVal == 0 && BaseRegNo != N86::EBP) {
+ MCE.emitByte(ModRMByte(0, RegOpcodeField, BaseRegNo));
+ return;
}
-
- // Do we need to output a displacement?
- if (ForceDisp8) {
+
+ // Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
+ if (!DispForReloc && isDisp8(DispVal)) {
+ MCE.emitByte(ModRMByte(1, RegOpcodeField, BaseRegNo));
emitConstant(DispVal, 1);
- } else if (DispVal != 0 || ForceDisp32) {
- emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
+ return;
}
+
+ // Otherwise, emit the most general non-SIB encoding: [REG+disp32]
+ MCE.emitByte(ModRMByte(2, RegOpcodeField, BaseRegNo));
+ emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
+ return;
+ }
+
+ // Otherwise we need a SIB byte, so start by outputting the ModR/M byte first.
+ assert(IndexReg.getReg() != X86::ESP &&
+ IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!");
+
+ bool ForceDisp32 = false;
+ bool ForceDisp8 = false;
+ if (BaseReg == 0) {
+ // If there is no base register, we emit the special case SIB byte with
+ // MOD=0, BASE=4, to JUST get the index, scale, and displacement.
+ MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
+ ForceDisp32 = true;
+ } else if (DispForReloc) {
+ // Emit the normal disp32 encoding.
+ MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
+ ForceDisp32 = true;
+ } else if (DispVal == 0 && getX86RegNum(BaseReg) != N86::EBP) {
+ // Emit no displacement ModR/M byte
+ MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
+ } else if (isDisp8(DispVal)) {
+ // Emit the disp8 encoding...
+ MCE.emitByte(ModRMByte(1, RegOpcodeField, 4));
+ ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
+ } else {
+ // Emit the normal disp32 encoding...
+ MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
+ }
+
+ // Calculate what the SS field value should be...
+ static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 };
+ unsigned SS = SSTable[Scale.getImm()];
+
+ if (BaseReg == 0) {
+ // Handle the SIB byte for the case where there is no base, see Intel
+ // Manual 2A, table 2-7. The displacement has already been output.
+ unsigned IndexRegNo;
+ if (IndexReg.getReg())
+ IndexRegNo = getX86RegNum(IndexReg.getReg());
+ else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
+ IndexRegNo = 4;
+ emitSIBByte(SS, IndexRegNo, 5);
+ } else {
+ unsigned BaseRegNo = getX86RegNum(BaseReg);
+ unsigned IndexRegNo;
+ if (IndexReg.getReg())
+ IndexRegNo = getX86RegNum(IndexReg.getReg());
+ else
+ IndexRegNo = 4; // For example [ESP+1*<noreg>+4]
+ emitSIBByte(SS, IndexRegNo, BaseRegNo);
+ }
+
+ // Do we need to output a displacement?
+ if (ForceDisp8) {
+ emitConstant(DispVal, 1);
+ } else if (DispVal != 0 || ForceDisp32) {
+ emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
}
}
@@ -570,7 +583,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
// Skip the last source operand that is tied_to the dest reg. e.g. LXADD32
--NumOps;
- unsigned char BaseOpcode = II->getBaseOpcodeFor(Desc);
+ unsigned char BaseOpcode = X86II::getBaseOpcodeFor(Desc->TSFlags);
switch (Desc->TSFlags & X86II::FormMask) {
default:
llvm_unreachable("Unknown FormMask value in X86 MachineCodeEmitter!");
@@ -582,25 +595,25 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
llvm_unreachable("psuedo instructions should be removed before code"
" emission");
break;
- case TargetInstrInfo::INLINEASM:
+ case TargetOpcode::INLINEASM:
// We allow inline assembler nodes with empty bodies - they can
// implicitly define registers, which is ok for JIT.
if (MI.getOperand(0).getSymbolName()[0])
llvm_report_error("JIT does not support inline asm!");
break;
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
- case TargetInstrInfo::GC_LABEL:
+ case TargetOpcode::DBG_LABEL:
+ case TargetOpcode::EH_LABEL:
+ case TargetOpcode::GC_LABEL:
MCE.emitLabel(MI.getOperand(0).getImm());
break;
- case TargetInstrInfo::IMPLICIT_DEF:
- case TargetInstrInfo::KILL:
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
case X86::FP_REG_KILL:
break;
case X86::MOVPC32r: {
// This emits the "call" portion of this pseudo instruction.
MCE.emitByte(BaseOpcode);
- emitConstant(0, X86InstrInfo::sizeOfImm(Desc));
+ emitConstant(0, X86II::getSizeOfImm(Desc->TSFlags));
// Remember PIC base.
PICBaseOffset = (intptr_t) MCE.getCurrentPCOffset();
X86JITInfo *JTI = TM.getJITInfo();
@@ -639,15 +652,21 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
emitExternalSymbolAddress(MO.getSymbolName(), X86::reloc_pcrel_word);
break;
}
+
+ // FIXME: Only used by hackish MCCodeEmitter, remove when dead.
+ if (MO.isJTI()) {
+ emitJumpTableAddress(MO.getIndex(), X86::reloc_pcrel_word);
+ break;
+ }
assert(MO.isImm() && "Unknown RawFrm operand!");
if (Opcode == X86::CALLpcrel32 || Opcode == X86::CALL64pcrel32) {
// Fix up immediate operand for pc relative calls.
intptr_t Imm = (intptr_t)MO.getImm();
Imm = Imm - MCE.getCurrentPCValue() - 4;
- emitConstant(Imm, X86InstrInfo::sizeOfImm(Desc));
+ emitConstant(Imm, X86II::getSizeOfImm(Desc->TSFlags));
} else
- emitConstant(MO.getImm(), X86InstrInfo::sizeOfImm(Desc));
+ emitConstant(MO.getImm(), X86II::getSizeOfImm(Desc->TSFlags));
break;
}
@@ -658,7 +677,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
break;
const MachineOperand &MO1 = MI.getOperand(CurOp++);
- unsigned Size = X86InstrInfo::sizeOfImm(Desc);
+ unsigned Size = X86II::getSizeOfImm(Desc->TSFlags);
if (MO1.isImm()) {
emitConstant(MO1.getImm(), Size);
break;
@@ -691,7 +710,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
CurOp += 2;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
- X86InstrInfo::sizeOfImm(Desc));
+ X86II::getSizeOfImm(Desc->TSFlags));
break;
}
case X86II::MRMDestMem: {
@@ -702,7 +721,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
CurOp += X86AddrNumOperands + 1;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
- X86InstrInfo::sizeOfImm(Desc));
+ X86II::getSizeOfImm(Desc->TSFlags));
break;
}
@@ -713,7 +732,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
CurOp += 2;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
- X86InstrInfo::sizeOfImm(Desc));
+ X86II::getSizeOfImm(Desc->TSFlags));
break;
case X86II::MRMSrcMem: {
@@ -726,7 +745,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
AddrOperands = X86AddrNumOperands;
intptr_t PCAdj = (CurOp + AddrOperands + 1 != NumOps) ?
- X86InstrInfo::sizeOfImm(Desc) : 0;
+ X86II::getSizeOfImm(Desc->TSFlags) : 0;
MCE.emitByte(BaseOpcode);
emitMemModRMByte(MI, CurOp+1, getX86RegNum(MI.getOperand(CurOp).getReg()),
@@ -734,7 +753,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
CurOp += AddrOperands + 1;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
- X86InstrInfo::sizeOfImm(Desc));
+ X86II::getSizeOfImm(Desc->TSFlags));
break;
}
@@ -743,33 +762,14 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
case X86II::MRM4r: case X86II::MRM5r:
case X86II::MRM6r: case X86II::MRM7r: {
MCE.emitByte(BaseOpcode);
-
- // Special handling of lfence, mfence, monitor, and mwait.
- if (Desc->getOpcode() == X86::LFENCE ||
- Desc->getOpcode() == X86::MFENCE ||
- Desc->getOpcode() == X86::MONITOR ||
- Desc->getOpcode() == X86::MWAIT) {
- emitRegModRMByte((Desc->TSFlags & X86II::FormMask)-X86II::MRM0r);
-
- switch (Desc->getOpcode()) {
- default: break;
- case X86::MONITOR:
- MCE.emitByte(0xC8);
- break;
- case X86::MWAIT:
- MCE.emitByte(0xC9);
- break;
- }
- } else {
- emitRegModRMByte(MI.getOperand(CurOp++).getReg(),
- (Desc->TSFlags & X86II::FormMask)-X86II::MRM0r);
- }
+ emitRegModRMByte(MI.getOperand(CurOp++).getReg(),
+ (Desc->TSFlags & X86II::FormMask)-X86II::MRM0r);
if (CurOp == NumOps)
break;
const MachineOperand &MO1 = MI.getOperand(CurOp++);
- unsigned Size = X86InstrInfo::sizeOfImm(Desc);
+ unsigned Size = X86II::getSizeOfImm(Desc->TSFlags);
if (MO1.isImm()) {
emitConstant(MO1.getImm(), Size);
break;
@@ -798,7 +798,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
case X86II::MRM6m: case X86II::MRM7m: {
intptr_t PCAdj = (CurOp + X86AddrNumOperands != NumOps) ?
(MI.getOperand(CurOp+X86AddrNumOperands).isImm() ?
- X86InstrInfo::sizeOfImm(Desc) : 4) : 0;
+ X86II::getSizeOfImm(Desc->TSFlags) : 4) : 0;
MCE.emitByte(BaseOpcode);
emitMemModRMByte(MI, CurOp, (Desc->TSFlags & X86II::FormMask)-X86II::MRM0m,
@@ -809,7 +809,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
break;
const MachineOperand &MO = MI.getOperand(CurOp++);
- unsigned Size = X86InstrInfo::sizeOfImm(Desc);
+ unsigned Size = X86II::getSizeOfImm(Desc->TSFlags);
if (MO.isImm()) {
emitConstant(MO.getImm(), Size);
break;
@@ -839,6 +839,27 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
getX86RegNum(MI.getOperand(CurOp).getReg()));
++CurOp;
break;
+
+ case X86II::MRM_C1:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xC1);
+ break;
+ case X86II::MRM_C8:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xC8);
+ break;
+ case X86II::MRM_C9:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xC9);
+ break;
+ case X86II::MRM_E8:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xE8);
+ break;
+ case X86II::MRM_F0:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xF0);
+ break;
}
if (!Desc->isVariadic() && CurOp != NumOps) {
@@ -850,256 +871,3 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
MCE.processDebugLoc(MI.getDebugLoc(), false);
}
-
-// Adapt the Emitter / CodeEmitter interfaces to MCCodeEmitter.
-//
-// FIXME: This is a total hack designed to allow work on llvm-mc to proceed
-// without being blocked on various cleanups needed to support a clean interface
-// to instruction encoding.
-//
-// Look away!
-
-#include "llvm/DerivedTypes.h"
-
-namespace {
-class MCSingleInstructionCodeEmitter : public MachineCodeEmitter {
- uint8_t Data[256];
-
-public:
- MCSingleInstructionCodeEmitter() { reset(); }
-
- void reset() {
- BufferBegin = Data;
- BufferEnd = array_endof(Data);
- CurBufferPtr = Data;
- }
-
- StringRef str() {
- return StringRef(reinterpret_cast<char*>(BufferBegin),
- CurBufferPtr - BufferBegin);
- }
-
- virtual void startFunction(MachineFunction &F) {}
- virtual bool finishFunction(MachineFunction &F) { return false; }
- virtual void emitLabel(uint64_t LabelID) {}
- virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {}
- virtual bool earlyResolveAddresses() const { return false; }
- virtual void addRelocation(const MachineRelocation &MR) { }
- virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
- return 0;
- }
- virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
- return 0;
- }
- virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
- return 0;
- }
- virtual uintptr_t getLabelAddress(uint64_t LabelID) const {
- return 0;
- }
- virtual void setModuleInfo(MachineModuleInfo* Info) {}
-};
-
-class X86MCCodeEmitter : public MCCodeEmitter {
- X86MCCodeEmitter(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
- void operator=(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
-
-private:
- X86TargetMachine &TM;
- llvm::Function *DummyF;
- TargetData *DummyTD;
- mutable llvm::MachineFunction *DummyMF;
- llvm::MachineBasicBlock *DummyMBB;
-
- MCSingleInstructionCodeEmitter *InstrEmitter;
- Emitter<MachineCodeEmitter> *Emit;
-
-public:
- X86MCCodeEmitter(X86TargetMachine &_TM) : TM(_TM) {
- // Verily, thou shouldst avert thine eyes.
- const llvm::FunctionType *FTy =
- FunctionType::get(llvm::Type::getVoidTy(getGlobalContext()), false);
- DummyF = Function::Create(FTy, GlobalValue::InternalLinkage);
- DummyTD = new TargetData("");
- DummyMF = new MachineFunction(DummyF, TM);
- DummyMBB = DummyMF->CreateMachineBasicBlock();
-
- InstrEmitter = new MCSingleInstructionCodeEmitter();
- Emit = new Emitter<MachineCodeEmitter>(TM, *InstrEmitter,
- *TM.getInstrInfo(),
- *DummyTD, false);
- }
- ~X86MCCodeEmitter() {
- delete Emit;
- delete InstrEmitter;
- delete DummyMF;
- delete DummyF;
- }
-
- bool AddRegToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- if (Start + 1 > MI.getNumOperands())
- return false;
-
- const MCOperand &Op = MI.getOperand(Start);
- if (!Op.isReg()) return false;
-
- Instr->addOperand(MachineOperand::CreateReg(Op.getReg(), false));
- return true;
- }
-
- bool AddImmToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- if (Start + 1 > MI.getNumOperands())
- return false;
-
- const MCOperand &Op = MI.getOperand(Start);
- if (Op.isImm()) {
- Instr->addOperand(MachineOperand::CreateImm(Op.getImm()));
- return true;
- }
- if (!Op.isExpr())
- return false;
-
- const MCExpr *Expr = Op.getExpr();
- if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) {
- Instr->addOperand(MachineOperand::CreateImm(CE->getValue()));
- return true;
- }
-
- // FIXME: Relocation / fixup.
- Instr->addOperand(MachineOperand::CreateImm(0));
- return true;
- }
-
- bool AddLMemToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- return (AddRegToInstr(MI, Instr, Start + 0) &&
- AddImmToInstr(MI, Instr, Start + 1) &&
- AddRegToInstr(MI, Instr, Start + 2) &&
- AddImmToInstr(MI, Instr, Start + 3));
- }
-
- bool AddMemToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- return (AddRegToInstr(MI, Instr, Start + 0) &&
- AddImmToInstr(MI, Instr, Start + 1) &&
- AddRegToInstr(MI, Instr, Start + 2) &&
- AddImmToInstr(MI, Instr, Start + 3) &&
- AddRegToInstr(MI, Instr, Start + 4));
- }
-
- void EncodeInstruction(const MCInst &MI, raw_ostream &OS) const {
- // Don't look yet!
-
- // Convert the MCInst to a MachineInstr so we can (ab)use the regular
- // emitter.
- const X86InstrInfo &II = *TM.getInstrInfo();
- const TargetInstrDesc &Desc = II.get(MI.getOpcode());
- MachineInstr *Instr = DummyMF->CreateMachineInstr(Desc, DebugLoc());
- DummyMBB->push_back(Instr);
-
- unsigned Opcode = MI.getOpcode();
- unsigned NumOps = MI.getNumOperands();
- unsigned CurOp = 0;
- if (NumOps > 1 && Desc.getOperandConstraint(1, TOI::TIED_TO) != -1) {
- Instr->addOperand(MachineOperand::CreateReg(0, false));
- ++CurOp;
- } else if (NumOps > 2 &&
- Desc.getOperandConstraint(NumOps-1, TOI::TIED_TO)== 0)
- // Skip the last source operand that is tied_to the dest reg. e.g. LXADD32
- --NumOps;
-
- bool OK = true;
- switch (Desc.TSFlags & X86II::FormMask) {
- case X86II::MRMDestReg:
- case X86II::MRMSrcReg:
- // Matching doesn't fill this in completely, we have to choose operand 0
- // for a tied register.
- OK &= AddRegToInstr(MI, Instr, 0); CurOp++;
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::RawFrm:
- if (CurOp < NumOps) {
- // Hack to make branches work.
- if (!(Desc.TSFlags & X86II::ImmMask) &&
- MI.getOperand(0).isExpr() &&
- isa<MCSymbolRefExpr>(MI.getOperand(0).getExpr()))
- Instr->addOperand(MachineOperand::CreateMBB(DummyMBB));
- else
- OK &= AddImmToInstr(MI, Instr, CurOp);
- }
- break;
-
- case X86II::AddRegFrm:
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRM0r: case X86II::MRM1r:
- case X86II::MRM2r: case X86II::MRM3r:
- case X86II::MRM4r: case X86II::MRM5r:
- case X86II::MRM6r: case X86II::MRM7r:
- // Matching doesn't fill this in completely, we have to choose operand 0
- // for a tied register.
- OK &= AddRegToInstr(MI, Instr, 0); CurOp++;
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRM0m: case X86II::MRM1m:
- case X86II::MRM2m: case X86II::MRM3m:
- case X86II::MRM4m: case X86II::MRM5m:
- case X86II::MRM6m: case X86II::MRM7m:
- OK &= AddMemToInstr(MI, Instr, CurOp); CurOp += 5;
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRMSrcMem:
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r ||
- Opcode == X86::LEA16r || Opcode == X86::LEA32r)
- OK &= AddLMemToInstr(MI, Instr, CurOp);
- else
- OK &= AddMemToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRMDestMem:
- OK &= AddMemToInstr(MI, Instr, CurOp); CurOp += 5;
- OK &= AddRegToInstr(MI, Instr, CurOp);
- break;
-
- default:
- case X86II::MRMInitReg:
- case X86II::Pseudo:
- OK = false;
- break;
- }
-
- if (!OK) {
- dbgs() << "couldn't convert inst '";
- MI.dump();
- dbgs() << "' to machine instr:\n";
- Instr->dump();
- }
-
- InstrEmitter->reset();
- if (OK)
- Emit->emitInstruction(*Instr, &Desc);
- OS << InstrEmitter->str();
-
- Instr->eraseFromParent();
- }
-};
-}
-
-// Ok, now you can look.
-MCCodeEmitter *llvm::createX86MCCodeEmitter(const Target &,
- TargetMachine &TM) {
- return new X86MCCodeEmitter(static_cast<X86TargetMachine&>(TM));
-}
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index d5ad61b..69a9d60 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -786,8 +786,8 @@ bool X86FastISel::X86SelectCmp(Instruction *I) {
bool X86FastISel::X86SelectZExt(Instruction *I) {
// Handle zero-extension from i1 to i8, which is common.
- if (I->getType()->isInteger(8) &&
- I->getOperand(0)->getType()->isInteger(1)) {
+ if (I->getType()->isIntegerTy(8) &&
+ I->getOperand(0)->getType()->isIntegerTy(1)) {
unsigned ResultReg = getRegForValue(I->getOperand(0));
if (ResultReg == 0) return false;
// Set the high bits to zero.
@@ -828,30 +828,30 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
std::swap(TrueMBB, FalseMBB);
Predicate = CmpInst::FCMP_UNE;
// FALL THROUGH
- case CmpInst::FCMP_UNE: SwapArgs = false; BranchOpc = X86::JNE; break;
- case CmpInst::FCMP_OGT: SwapArgs = false; BranchOpc = X86::JA; break;
- case CmpInst::FCMP_OGE: SwapArgs = false; BranchOpc = X86::JAE; break;
- case CmpInst::FCMP_OLT: SwapArgs = true; BranchOpc = X86::JA; break;
- case CmpInst::FCMP_OLE: SwapArgs = true; BranchOpc = X86::JAE; break;
- case CmpInst::FCMP_ONE: SwapArgs = false; BranchOpc = X86::JNE; break;
- case CmpInst::FCMP_ORD: SwapArgs = false; BranchOpc = X86::JNP; break;
- case CmpInst::FCMP_UNO: SwapArgs = false; BranchOpc = X86::JP; break;
- case CmpInst::FCMP_UEQ: SwapArgs = false; BranchOpc = X86::JE; break;
- case CmpInst::FCMP_UGT: SwapArgs = true; BranchOpc = X86::JB; break;
- case CmpInst::FCMP_UGE: SwapArgs = true; BranchOpc = X86::JBE; break;
- case CmpInst::FCMP_ULT: SwapArgs = false; BranchOpc = X86::JB; break;
- case CmpInst::FCMP_ULE: SwapArgs = false; BranchOpc = X86::JBE; break;
+ case CmpInst::FCMP_UNE: SwapArgs = false; BranchOpc = X86::JNE_4; break;
+ case CmpInst::FCMP_OGT: SwapArgs = false; BranchOpc = X86::JA_4; break;
+ case CmpInst::FCMP_OGE: SwapArgs = false; BranchOpc = X86::JAE_4; break;
+ case CmpInst::FCMP_OLT: SwapArgs = true; BranchOpc = X86::JA_4; break;
+ case CmpInst::FCMP_OLE: SwapArgs = true; BranchOpc = X86::JAE_4; break;
+ case CmpInst::FCMP_ONE: SwapArgs = false; BranchOpc = X86::JNE_4; break;
+ case CmpInst::FCMP_ORD: SwapArgs = false; BranchOpc = X86::JNP_4; break;
+ case CmpInst::FCMP_UNO: SwapArgs = false; BranchOpc = X86::JP_4; break;
+ case CmpInst::FCMP_UEQ: SwapArgs = false; BranchOpc = X86::JE_4; break;
+ case CmpInst::FCMP_UGT: SwapArgs = true; BranchOpc = X86::JB_4; break;
+ case CmpInst::FCMP_UGE: SwapArgs = true; BranchOpc = X86::JBE_4; break;
+ case CmpInst::FCMP_ULT: SwapArgs = false; BranchOpc = X86::JB_4; break;
+ case CmpInst::FCMP_ULE: SwapArgs = false; BranchOpc = X86::JBE_4; break;
- case CmpInst::ICMP_EQ: SwapArgs = false; BranchOpc = X86::JE; break;
- case CmpInst::ICMP_NE: SwapArgs = false; BranchOpc = X86::JNE; break;
- case CmpInst::ICMP_UGT: SwapArgs = false; BranchOpc = X86::JA; break;
- case CmpInst::ICMP_UGE: SwapArgs = false; BranchOpc = X86::JAE; break;
- case CmpInst::ICMP_ULT: SwapArgs = false; BranchOpc = X86::JB; break;
- case CmpInst::ICMP_ULE: SwapArgs = false; BranchOpc = X86::JBE; break;
- case CmpInst::ICMP_SGT: SwapArgs = false; BranchOpc = X86::JG; break;
- case CmpInst::ICMP_SGE: SwapArgs = false; BranchOpc = X86::JGE; break;
- case CmpInst::ICMP_SLT: SwapArgs = false; BranchOpc = X86::JL; break;
- case CmpInst::ICMP_SLE: SwapArgs = false; BranchOpc = X86::JLE; break;
+ case CmpInst::ICMP_EQ: SwapArgs = false; BranchOpc = X86::JE_4; break;
+ case CmpInst::ICMP_NE: SwapArgs = false; BranchOpc = X86::JNE_4; break;
+ case CmpInst::ICMP_UGT: SwapArgs = false; BranchOpc = X86::JA_4; break;
+ case CmpInst::ICMP_UGE: SwapArgs = false; BranchOpc = X86::JAE_4; break;
+ case CmpInst::ICMP_ULT: SwapArgs = false; BranchOpc = X86::JB_4; break;
+ case CmpInst::ICMP_ULE: SwapArgs = false; BranchOpc = X86::JBE_4; break;
+ case CmpInst::ICMP_SGT: SwapArgs = false; BranchOpc = X86::JG_4; break;
+ case CmpInst::ICMP_SGE: SwapArgs = false; BranchOpc = X86::JGE_4; break;
+ case CmpInst::ICMP_SLT: SwapArgs = false; BranchOpc = X86::JL_4; break;
+ case CmpInst::ICMP_SLE: SwapArgs = false; BranchOpc = X86::JLE_4; break;
default:
return false;
}
@@ -869,7 +869,7 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
if (Predicate == CmpInst::FCMP_UNE) {
// X86 requires a second branch to handle UNE (and OEQ,
// which is mapped to UNE above).
- BuildMI(MBB, DL, TII.get(X86::JP)).addMBB(TrueMBB);
+ BuildMI(MBB, DL, TII.get(X86::JP_4)).addMBB(TrueMBB);
}
FastEmitBranch(FalseMBB);
@@ -923,7 +923,8 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
unsigned OpCode = SetMI->getOpcode();
if (OpCode == X86::SETOr || OpCode == X86::SETBr) {
- BuildMI(MBB, DL, TII.get(OpCode == X86::SETOr ? X86::JO : X86::JB))
+ BuildMI(MBB, DL, TII.get(OpCode == X86::SETOr ?
+ X86::JO_4 : X86::JB_4))
.addMBB(TrueMBB);
FastEmitBranch(FalseMBB);
MBB->addSuccessor(TrueMBB);
@@ -939,7 +940,7 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
if (OpReg == 0) return false;
BuildMI(MBB, DL, TII.get(X86::TEST8rr)).addReg(OpReg).addReg(OpReg);
- BuildMI(MBB, DL, TII.get(X86::JNE)).addMBB(TrueMBB);
+ BuildMI(MBB, DL, TII.get(X86::JNE_4)).addMBB(TrueMBB);
FastEmitBranch(FalseMBB);
MBB->addSuccessor(TrueMBB);
return true;
@@ -948,7 +949,7 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
bool X86FastISel::X86SelectShift(Instruction *I) {
unsigned CReg = 0, OpReg = 0, OpImm = 0;
const TargetRegisterClass *RC = NULL;
- if (I->getType()->isInteger(8)) {
+ if (I->getType()->isIntegerTy(8)) {
CReg = X86::CL;
RC = &X86::GR8RegClass;
switch (I->getOpcode()) {
@@ -957,7 +958,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) {
case Instruction::Shl: OpReg = X86::SHL8rCL; OpImm = X86::SHL8ri; break;
default: return false;
}
- } else if (I->getType()->isInteger(16)) {
+ } else if (I->getType()->isIntegerTy(16)) {
CReg = X86::CX;
RC = &X86::GR16RegClass;
switch (I->getOpcode()) {
@@ -966,7 +967,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) {
case Instruction::Shl: OpReg = X86::SHL16rCL; OpImm = X86::SHL16ri; break;
default: return false;
}
- } else if (I->getType()->isInteger(32)) {
+ } else if (I->getType()->isIntegerTy(32)) {
CReg = X86::ECX;
RC = &X86::GR32RegClass;
switch (I->getOpcode()) {
@@ -975,7 +976,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) {
case Instruction::Shl: OpReg = X86::SHL32rCL; OpImm = X86::SHL32ri; break;
default: return false;
}
- } else if (I->getType()->isInteger(64)) {
+ } else if (I->getType()->isIntegerTy(64)) {
CReg = X86::RCX;
RC = &X86::GR64RegClass;
switch (I->getOpcode()) {
@@ -1012,7 +1013,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) {
// of X86::CL, emit an EXTRACT_SUBREG to precisely describe what
// we're doing here.
if (CReg != X86::CL)
- BuildMI(MBB, DL, TII.get(TargetInstrInfo::EXTRACT_SUBREG), X86::CL)
+ BuildMI(MBB, DL, TII.get(TargetOpcode::EXTRACT_SUBREG), X86::CL)
.addReg(CReg).addImm(X86::SUBREG_8BIT);
unsigned ResultReg = createResultReg(RC);
@@ -1153,6 +1154,17 @@ bool X86FastISel::X86VisitIntrinsicCall(IntrinsicInst &I) {
// FIXME: Handle more intrinsics.
switch (I.getIntrinsicID()) {
default: return false;
+ case Intrinsic::dbg_declare: {
+ DbgDeclareInst *DI = cast<DbgDeclareInst>(&I);
+ X86AddressMode AM;
+ assert(DI->getAddress() && "Null address should be checked earlier!");
+ if (!X86SelectAddress(DI->getAddress(), AM))
+ return false;
+ const TargetInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE);
+ addFullAddress(BuildMI(MBB, DL, II), AM).addImm(0).
+ addMetadata(DI->getVariable());
+ return true;
+ }
case Intrinsic::trap: {
BuildMI(MBB, DL, TII.get(X86::TRAP));
return true;
@@ -1236,7 +1248,7 @@ bool X86FastISel::X86SelectCall(Instruction *I) {
// fastcc with -tailcallopt is intended to provide a guaranteed
// tail call optimization. Fastisel doesn't know how to do that.
- if (CC == CallingConv::Fast && PerformTailCallOpt)
+ if (CC == CallingConv::Fast && GuaranteedTailCallOpt)
return false;
// Let SDISel handle vararg functions.
diff --git a/lib/Target/X86/X86FixupKinds.h b/lib/Target/X86/X86FixupKinds.h
new file mode 100644
index 0000000..c8dac3c
--- /dev/null
+++ b/lib/Target/X86/X86FixupKinds.h
@@ -0,0 +1,25 @@
+//===-- X86/X86FixupKinds.h - X86 Specific Fixup Entries --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_X86_X86FIXUPKINDS_H
+#define LLVM_X86_X86FIXUPKINDS_H
+
+#include "llvm/MC/MCFixup.h"
+
+namespace llvm {
+namespace X86 {
+enum Fixups {
+ reloc_pcrel_4byte = FirstTargetFixupKind, // 32-bit pcrel, e.g. a branch.
+ reloc_pcrel_1byte, // 8-bit pcrel, e.g. branch_1
+ reloc_riprel_4byte // 32-bit rip-relative
+};
+}
+}
+
+#endif
diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp
index 503ac14..6d6fe77 100644
--- a/lib/Target/X86/X86FloatingPoint.cpp
+++ b/lib/Target/X86/X86FloatingPoint.cpp
@@ -235,7 +235,7 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
unsigned Flags = MI->getDesc().TSFlags;
unsigned FPInstClass = Flags & X86II::FPTypeMask;
- if (MI->getOpcode() == TargetInstrInfo::INLINEASM)
+ if (MI->isInlineAsm())
FPInstClass = X86II::SpecialFP;
if (FPInstClass == X86II::NotFP)
@@ -1083,7 +1083,7 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
}
}
break;
- case TargetInstrInfo::INLINEASM: {
+ case TargetOpcode::INLINEASM: {
// The inline asm MachineInstr currently only *uses* FP registers for the
// 'f' constraint. These should be turned into the current ST(x) register
// in the machine instr. Also, any kills should be explicitly popped after
diff --git a/lib/Target/X86/X86FloatingPointRegKill.cpp b/lib/Target/X86/X86FloatingPointRegKill.cpp
index 34a0045..6a117dd 100644
--- a/lib/Target/X86/X86FloatingPointRegKill.cpp
+++ b/lib/Target/X86/X86FloatingPointRegKill.cpp
@@ -118,7 +118,7 @@ bool FPRegKiller::runOnMachineFunction(MachineFunction &MF) {
for (BasicBlock::const_iterator II = SI->begin();
(PN = dyn_cast<PHINode>(II)); ++II) {
if (PN->getType()==Type::getX86_FP80Ty(LLVMBB->getContext()) ||
- (!Subtarget.hasSSE1() && PN->getType()->isFloatingPoint()) ||
+ (!Subtarget.hasSSE1() && PN->getType()->isFloatingPointTy()) ||
(!Subtarget.hasSSE2() &&
PN->getType()==Type::getDoubleTy(LLVMBB->getContext()))) {
ContainsFPCode = true;
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 91e0483..7b349f6 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -183,8 +183,9 @@ namespace {
virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
- virtual
- bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const;
+ virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const;
+
+ virtual bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const;
// Include the pieces autogenerated from the target description.
#include "X86GenDAGISel.inc"
@@ -303,11 +304,18 @@ namespace {
}
-bool X86DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const {
+bool
+X86DAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const {
if (OptLevel == CodeGenOpt::None) return false;
- if (U == Root)
+ if (!N.hasOneUse())
+ return false;
+
+ if (N.getOpcode() != ISD::LOAD)
+ return true;
+
+ // If N is a load, do additional profitability checks.
+ if (U == Root) {
switch (U->getOpcode()) {
default: break;
case X86ISD::ADD:
@@ -354,9 +362,17 @@ bool X86DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
}
}
}
+ }
+
+ return true;
+}
+
+
+bool X86DAGToDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const {
+ if (OptLevel == CodeGenOpt::None) return false;
// Proceed to 'generic' cycle finder code
- return SelectionDAGISel::IsLegalAndProfitableToFold(N, U, Root);
+ return SelectionDAGISel::IsLegalToFold(N, U, Root);
}
/// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand
@@ -652,9 +668,10 @@ void X86DAGToDAGISel::PreprocessForFPConvert() {
// FIXME: optimize the case where the src/dest is a load or store?
SDValue Store = CurDAG->getTruncStore(CurDAG->getEntryNode(), dl,
N->getOperand(0),
- MemTmp, NULL, 0, MemVT);
+ MemTmp, NULL, 0, MemVT,
+ false, false, 0);
SDValue Result = CurDAG->getExtLoad(ISD::EXTLOAD, dl, DstVT, Store, MemTmp,
- NULL, 0, MemVT);
+ NULL, 0, MemVT, false, false, 0);
// We're about to replace all uses of the FP_ROUND/FP_EXTEND with the
// extload we created. This will cause general havok on the dag because
@@ -1310,8 +1327,8 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDNode *Op, SDValue Pred,
InChain = N.getOperand(0).getValue(1);
if (ISD::isNON_EXTLoad(InChain.getNode()) &&
InChain.getValue(0).hasOneUse() &&
- N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), Pred.getNode(), Op)) {
+ IsProfitableToFold(N, Pred.getNode(), Op) &&
+ IsLegalToFold(N, Pred.getNode(), Op)) {
LoadSDNode *LD = cast<LoadSDNode>(InChain);
if (!SelectAddr(Op, LD->getBasePtr(), Base, Scale, Index, Disp, Segment))
return false;
@@ -1435,8 +1452,8 @@ bool X86DAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
SDValue &Index, SDValue &Disp,
SDValue &Segment) {
if (ISD::isNON_EXTLoad(N.getNode()) &&
- N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), P, P))
+ IsProfitableToFold(N, P, P) &&
+ IsLegalToFold(N, P, P))
return SelectAddr(P, N.getOperand(1), Base, Scale, Index, Disp, Segment);
return false;
}
@@ -1606,7 +1623,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) {
}
DebugLoc dl = Node->getDebugLoc();
- SDValue Undef = SDValue(CurDAG->getMachineNode(TargetInstrInfo::IMPLICIT_DEF,
+ SDValue Undef = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
dl, NVT), 0);
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
MemOp[0] = cast<MemSDNode>(Node)->getMemOperand();
@@ -1652,8 +1669,8 @@ static bool HasNoSignedComparisonUses(SDNode *N) {
case X86::SETEr: case X86::SETNEr: case X86::SETPr: case X86::SETNPr:
case X86::SETAm: case X86::SETAEm: case X86::SETBm: case X86::SETBEm:
case X86::SETEm: case X86::SETNEm: case X86::SETPm: case X86::SETNPm:
- case X86::JA: case X86::JAE: case X86::JB: case X86::JBE:
- case X86::JE: case X86::JNE: case X86::JP: case X86::JNP:
+ case X86::JA_4: case X86::JAE_4: case X86::JB_4: case X86::JBE_4:
+ case X86::JE_4: case X86::JNE_4: case X86::JP_4: case X86::JNP_4:
case X86::CMOVA16rr: case X86::CMOVA16rm:
case X86::CMOVA32rr: case X86::CMOVA32rm:
case X86::CMOVA64rr: case X86::CMOVA64rm:
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 11e07df..9974d8c 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -12,9 +12,11 @@
//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "x86-isel"
#include "X86.h"
#include "X86InstrBuilder.h"
#include "X86ISelLowering.h"
+#include "X86MCTargetExpr.h"
#include "X86TargetMachine.h"
#include "X86TargetObjectFile.h"
#include "llvm/CallingConv.h"
@@ -26,24 +28,30 @@
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/LLVMContext.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/VectorExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetOptions.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+STATISTIC(NumTailCalls, "Number of tail calls");
+
static cl::opt<bool>
DisableMMX("disable-mmx", cl::Hidden, cl::desc("Disable use of MMX"));
@@ -67,13 +75,14 @@ static TargetLoweringObjectFile *createTLOF(X86TargetMachine &TM) {
return new X8664_MachoTargetObjectFile();
return new X8632_MachoTargetObjectFile();
case X86Subtarget::isELF:
- return new TargetLoweringObjectFileELF();
+ if (TM.getSubtarget<X86Subtarget>().is64Bit())
+ return new X8664_ELFTargetObjectFile(TM);
+ return new X8632_ELFTargetObjectFile(TM);
case X86Subtarget::isMingw:
case X86Subtarget::isCygwin:
case X86Subtarget::isWindows:
return new TargetLoweringObjectFileCOFF();
}
-
}
X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
@@ -747,6 +756,12 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Custom);
setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Custom);
+ setOperationAction(ISD::CONCAT_VECTORS, MVT::v2f64, Custom);
+ setOperationAction(ISD::CONCAT_VECTORS, MVT::v2i64, Custom);
+ setOperationAction(ISD::CONCAT_VECTORS, MVT::v16i8, Custom);
+ setOperationAction(ISD::CONCAT_VECTORS, MVT::v8i16, Custom);
+ setOperationAction(ISD::CONCAT_VECTORS, MVT::v4i32, Custom);
+
// Custom lower build_vector, vector_shuffle, and extract_vector_elt.
for (unsigned i = (unsigned)MVT::v16i8; i != (unsigned)MVT::v2i64; ++i) {
EVT VT = (MVT::SimpleValueType)i;
@@ -987,19 +1002,6 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
computeRegisterProperties();
- // Divide and reminder operations have no vector equivalent and can
- // trap. Do a custom widening for these operations in which we never
- // generate more divides/remainder than the original vector width.
- for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
- VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
- if (!isTypeLegal((MVT::SimpleValueType)VT)) {
- setOperationAction(ISD::SDIV, (MVT::SimpleValueType) VT, Custom);
- setOperationAction(ISD::UDIV, (MVT::SimpleValueType) VT, Custom);
- setOperationAction(ISD::SREM, (MVT::SimpleValueType) VT, Custom);
- setOperationAction(ISD::UREM, (MVT::SimpleValueType) VT, Custom);
- }
- }
-
// FIXME: These should be based on subtarget info. Plus, the values should
// be smaller when we are in optimizing for size mode.
maxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores
@@ -1084,12 +1086,46 @@ X86TargetLowering::getOptimalMemOpType(uint64_t Size, unsigned Align,
return MVT::i32;
}
+/// getJumpTableEncoding - Return the entry encoding for a jump table in the
+/// current function. The returned value is a member of the
+/// MachineJumpTableInfo::JTEntryKind enum.
+unsigned X86TargetLowering::getJumpTableEncoding() const {
+ // In GOT pic mode, each entry in the jump table is emitted as a @GOTOFF
+ // symbol.
+ if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+ Subtarget->isPICStyleGOT())
+ return MachineJumpTableInfo::EK_Custom32;
+
+ // Otherwise, use the normal jump table encoding heuristics.
+ return TargetLowering::getJumpTableEncoding();
+}
+
+/// getPICBaseSymbol - Return the X86-32 PIC base.
+MCSymbol *
+X86TargetLowering::getPICBaseSymbol(const MachineFunction *MF,
+ MCContext &Ctx) const {
+ const MCAsmInfo &MAI = *getTargetMachine().getMCAsmInfo();
+ return Ctx.GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix())+
+ Twine(MF->getFunctionNumber())+"$pb");
+}
+
+
+const MCExpr *
+X86TargetLowering::LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
+ const MachineBasicBlock *MBB,
+ unsigned uid,MCContext &Ctx) const{
+ assert(getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+ Subtarget->isPICStyleGOT());
+ // In 32-bit ELF systems, our jump table entries are formed with @GOTOFF
+ // entries.
+ return X86MCTargetExpr::Create(MBB->getSymbol(Ctx),
+ X86MCTargetExpr::GOTOFF, Ctx);
+}
+
/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
/// jumptable.
SDValue X86TargetLowering::getPICJumpTableRelocBase(SDValue Table,
- SelectionDAG &DAG) const {
- if (usesGlobalOffsetTable())
- return DAG.getGLOBAL_OFFSET_TABLE(getPointerTy());
+ SelectionDAG &DAG) const {
if (!Subtarget->is64Bit())
// This doesn't have DebugLoc associated with it, but is not really the
// same as a Register.
@@ -1098,6 +1134,20 @@ SDValue X86TargetLowering::getPICJumpTableRelocBase(SDValue Table,
return Table;
}
+/// getPICJumpTableRelocBaseExpr - This returns the relocation base for the
+/// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an
+/// MCExpr.
+const MCExpr *X86TargetLowering::
+getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI,
+ MCContext &Ctx) const {
+ // X86-64 uses RIP relative addressing based on the jump table label.
+ if (Subtarget->isPICStyleRIPRel())
+ return TargetLowering::getPICJumpTableRelocBaseExpr(MF, JTI, Ctx);
+
+ // Otherwise, the reference is relative to the PIC base.
+ return MCSymbolRefExpr::Create(getPICBaseSymbol(MF, Ctx), Ctx);
+}
+
/// getFunctionAlignment - Return the Log2 alignment of this function.
unsigned X86TargetLowering::getFunctionAlignment(const Function *F) const {
return F->hasFnAttr(Attribute::OptimizeForSize) ? 0 : 4;
@@ -1131,13 +1181,11 @@ X86TargetLowering::LowerReturn(SDValue Chain,
RVLocs, *DAG.getContext());
CCInfo.AnalyzeReturn(Outs, RetCC_X86);
- // If this is the first return lowered for this function, add the regs to the
- // liveout set for the function.
- if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
- for (unsigned i = 0; i != RVLocs.size(); ++i)
- if (RVLocs[i].isRegLoc())
- DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
- }
+ // Add the regs to the liveout set for the function.
+ MachineRegisterInfo &MRI = DAG.getMachineFunction().getRegInfo();
+ for (unsigned i = 0; i != RVLocs.size(); ++i)
+ if (RVLocs[i].isRegLoc() && !MRI.isLiveOut(RVLocs[i].getLocReg()))
+ MRI.addLiveOut(RVLocs[i].getLocReg());
SDValue Flag;
@@ -1190,7 +1238,7 @@ X86TargetLowering::LowerReturn(SDValue Chain,
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
unsigned Reg = FuncInfo->getSRetReturnReg();
if (!Reg) {
- Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));
+ Reg = MRI.createVirtualRegister(getRegClassFor(MVT::i64));
FuncInfo->setSRetReturnReg(Reg);
}
SDValue Val = DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy());
@@ -1199,7 +1247,7 @@ X86TargetLowering::LowerReturn(SDValue Chain,
Flag = Chain.getValue(1);
// RAX now acts like a return value.
- MF.getRegInfo().addLiveOut(X86::RAX);
+ MRI.addLiveOut(X86::RAX);
}
RetOps[0] = Chain; // Update chain.
@@ -1329,7 +1377,7 @@ bool X86TargetLowering::IsCalleePop(bool IsVarArg, CallingConv::ID CallingConv){
case CallingConv::X86_FastCall:
return !Subtarget->is64Bit();
case CallingConv::Fast:
- return PerformTailCallOpt;
+ return GuaranteedTailCallOpt;
}
}
@@ -1351,18 +1399,6 @@ CCAssignFn *X86TargetLowering::CCAssignFnForNode(CallingConv::ID CC) const {
return CC_X86_32_C;
}
-/// NameDecorationForCallConv - Selects the appropriate decoration to
-/// apply to a MachineFunction containing a given calling convention.
-NameDecorationStyle
-X86TargetLowering::NameDecorationForCallConv(CallingConv::ID CallConv) {
- if (CallConv == CallingConv::X86_FastCall)
- return FastCall;
- else if (CallConv == CallingConv::X86_StdCall)
- return StdCall;
- return None;
-}
-
-
/// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
/// by "Src" to address "Dst" with size and alignment information specified by
/// the specific parameter attribute. The copy will be passed as a byval
@@ -1376,6 +1412,12 @@ CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain,
/*AlwaysInline=*/true, NULL, 0, NULL, 0);
}
+/// FuncIsMadeTailCallSafe - Return true if the function is being made into
+/// a tailcall target by changing its ABI.
+static bool FuncIsMadeTailCallSafe(CallingConv::ID CC) {
+ return GuaranteedTailCallOpt && CC == CallingConv::Fast;
+}
+
SDValue
X86TargetLowering::LowerMemArgument(SDValue Chain,
CallingConv::ID CallConv,
@@ -1384,10 +1426,9 @@ X86TargetLowering::LowerMemArgument(SDValue Chain,
const CCValAssign &VA,
MachineFrameInfo *MFI,
unsigned i) {
-
// Create the nodes corresponding to a load from this parameter slot.
ISD::ArgFlagsTy Flags = Ins[i].Flags;
- bool AlwaysUseMutable = (CallConv==CallingConv::Fast) && PerformTailCallOpt;
+ bool AlwaysUseMutable = FuncIsMadeTailCallSafe(CallConv);
bool isImmutable = !AlwaysUseMutable && !Flags.isByVal();
EVT ValVT;
@@ -1402,13 +1443,18 @@ X86TargetLowering::LowerMemArgument(SDValue Chain,
// changed with more analysis.
// In case of tail call optimization mark all arguments mutable. Since they
// could be overwritten by lowering of arguments in case of a tail call.
- int FI = MFI->CreateFixedObject(ValVT.getSizeInBits()/8,
- VA.getLocMemOffset(), isImmutable, false);
- SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
- if (Flags.isByVal())
- return FIN;
- return DAG.getLoad(ValVT, dl, Chain, FIN,
- PseudoSourceValue::getFixedStack(FI), 0);
+ if (Flags.isByVal()) {
+ int FI = MFI->CreateFixedObject(Flags.getByValSize(),
+ VA.getLocMemOffset(), isImmutable, false);
+ return DAG.getFrameIndex(FI, getPointerTy());
+ } else {
+ int FI = MFI->CreateFixedObject(ValVT.getSizeInBits()/8,
+ VA.getLocMemOffset(), isImmutable, false);
+ SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
+ return DAG.getLoad(ValVT, dl, Chain, FIN,
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0);
+ }
}
SDValue
@@ -1429,9 +1475,6 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
Fn->getName() == "main")
FuncInfo->setForceFramePointer(true);
- // Decorate the function name.
- FuncInfo->setDecorationStyle(NameDecorationForCallConv(CallConv));
-
MachineFrameInfo *MFI = MF.getFrameInfo();
bool Is64Bit = Subtarget->is64Bit();
bool IsWin64 = Subtarget->isTargetWin64();
@@ -1504,7 +1547,8 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
// If value is passed via pointer - do a load.
if (VA.getLocInfo() == CCValAssign::Indirect)
- ArgValue = DAG.getLoad(VA.getValVT(), dl, Chain, ArgValue, NULL, 0);
+ ArgValue = DAG.getLoad(VA.getValVT(), dl, Chain, ArgValue, NULL, 0,
+ false, false, 0);
InVals.push_back(ArgValue);
}
@@ -1524,8 +1568,8 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
}
unsigned StackSize = CCInfo.getNextStackOffset();
- // align stack specially for tail calls
- if (PerformTailCallOpt && CallConv == CallingConv::Fast)
+ // Align stack specially for tail calls.
+ if (FuncIsMadeTailCallSafe(CallConv))
StackSize = GetAlignedArgumentStackSize(StackSize, DAG);
// If the function takes variable number of arguments, make a frame index for
@@ -1599,7 +1643,7 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
SDValue Store =
DAG.getStore(Val.getValue(1), dl, Val, FIN,
PseudoSourceValue::getFixedStack(RegSaveFrameIndex),
- Offset);
+ Offset, false, false, 0);
MemOps.push_back(Store);
Offset += 8;
}
@@ -1636,13 +1680,11 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
// Some CCs need callee pop.
if (IsCalleePop(isVarArg, CallConv)) {
BytesToPopOnReturn = StackSize; // Callee pops everything.
- BytesCallerReserves = 0;
} else {
BytesToPopOnReturn = 0; // Callee pops nothing.
// If this is an sret function, the return should pop the hidden pointer.
if (!Is64Bit && CallConv != CallingConv::Fast && ArgsAreStructReturn(Ins))
BytesToPopOnReturn = 4;
- BytesCallerReserves = StackSize;
}
if (!Is64Bit) {
@@ -1670,27 +1712,23 @@ X86TargetLowering::LowerMemOpCallTo(SDValue Chain,
return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG, dl);
}
return DAG.getStore(Chain, dl, Arg, PtrOff,
- PseudoSourceValue::getStack(), LocMemOffset);
+ PseudoSourceValue::getStack(), LocMemOffset,
+ false, false, 0);
}
/// EmitTailCallLoadRetAddr - Emit a load of return address if tail call
/// optimization is performed and it is required.
SDValue
X86TargetLowering::EmitTailCallLoadRetAddr(SelectionDAG &DAG,
- SDValue &OutRetAddr,
- SDValue Chain,
- bool IsTailCall,
- bool Is64Bit,
- int FPDiff,
- DebugLoc dl) {
- if (!IsTailCall || FPDiff==0) return Chain;
-
+ SDValue &OutRetAddr, SDValue Chain,
+ bool IsTailCall, bool Is64Bit,
+ int FPDiff, DebugLoc dl) {
// Adjust the Return address stack slot.
EVT VT = getPointerTy();
OutRetAddr = getReturnAddressFrameIndex(DAG);
// Load the "old" Return address.
- OutRetAddr = DAG.getLoad(VT, dl, Chain, OutRetAddr, NULL, 0);
+ OutRetAddr = DAG.getLoad(VT, dl, Chain, OutRetAddr, NULL, 0, false, false, 0);
return SDValue(OutRetAddr.getNode(), 1);
}
@@ -1705,31 +1743,42 @@ EmitTailCallStoreRetAddr(SelectionDAG & DAG, MachineFunction &MF,
// Calculate the new stack slot for the return address.
int SlotSize = Is64Bit ? 8 : 4;
int NewReturnAddrFI =
- MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize,
- true, false);
+ MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize, true,false);
EVT VT = Is64Bit ? MVT::i64 : MVT::i32;
SDValue NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT);
Chain = DAG.getStore(Chain, dl, RetAddrFrIdx, NewRetAddrFrIdx,
- PseudoSourceValue::getFixedStack(NewReturnAddrFI), 0);
+ PseudoSourceValue::getFixedStack(NewReturnAddrFI), 0,
+ false, false, 0);
return Chain;
}
SDValue
X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
-
MachineFunction &MF = DAG.getMachineFunction();
bool Is64Bit = Subtarget->is64Bit();
bool IsStructRet = CallIsStructReturn(Outs);
+ bool IsSibcall = false;
+
+ if (isTailCall) {
+ // Check if it's really possible to do a tail call.
+ isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg,
+ Outs, Ins, DAG);
+
+ // Sibcalls are automatically detected tailcalls which do not require
+ // ABI changes.
+ if (!GuaranteedTailCallOpt && isTailCall)
+ IsSibcall = true;
+
+ if (isTailCall)
+ ++NumTailCalls;
+ }
- assert((!isTailCall ||
- (CallConv == CallingConv::Fast && PerformTailCallOpt)) &&
- "IsEligibleForTailCallOptimization missed a case!");
assert(!(isVarArg && CallConv == CallingConv::Fast) &&
"Var args not supported with calling convention fastcc");
@@ -1741,11 +1790,15 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// Get a count of how many bytes are to be pushed on the stack.
unsigned NumBytes = CCInfo.getNextStackOffset();
- if (PerformTailCallOpt && CallConv == CallingConv::Fast)
+ if (IsSibcall)
+ // This is a sibcall. The memory operands are available in caller's
+ // own caller's stack.
+ NumBytes = 0;
+ else if (GuaranteedTailCallOpt && CallConv == CallingConv::Fast)
NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);
int FPDiff = 0;
- if (isTailCall) {
+ if (isTailCall && !IsSibcall) {
// Lower arguments at fp - stackoffset + fpdiff.
unsigned NumBytesCallerPushed =
MF.getInfo<X86MachineFunctionInfo>()->getBytesToPopOnReturn();
@@ -1757,12 +1810,14 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
MF.getInfo<X86MachineFunctionInfo>()->setTCReturnAddrDelta(FPDiff);
}
- Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true));
+ if (!IsSibcall)
+ Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true));
SDValue RetAddrFrIdx;
// Load return adress for tail calls.
- Chain = EmitTailCallLoadRetAddr(DAG, RetAddrFrIdx, Chain, isTailCall, Is64Bit,
- FPDiff, dl);
+ if (isTailCall && FPDiff)
+ Chain = EmitTailCallLoadRetAddr(DAG, RetAddrFrIdx, Chain, isTailCall,
+ Is64Bit, FPDiff, dl);
SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
SmallVector<SDValue, 8> MemOpChains;
@@ -1804,7 +1859,8 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
SDValue SpillSlot = DAG.CreateStackTemporary(VA.getValVT());
int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
Chain = DAG.getStore(Chain, dl, Arg, SpillSlot,
- PseudoSourceValue::getFixedStack(FI), 0);
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0);
Arg = SpillSlot;
break;
}
@@ -1812,15 +1868,12 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (VA.isRegLoc()) {
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
- } else {
- if (!isTailCall || (isTailCall && isByVal)) {
- assert(VA.isMemLoc());
- if (StackPtr.getNode() == 0)
- StackPtr = DAG.getCopyFromReg(Chain, dl, X86StackPtr, getPointerTy());
-
- MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg,
- dl, DAG, VA, Flags));
- }
+ } else if (!IsSibcall && (!isTailCall || isByVal)) {
+ assert(VA.isMemLoc());
+ if (StackPtr.getNode() == 0)
+ StackPtr = DAG.getCopyFromReg(Chain, dl, X86StackPtr, getPointerTy());
+ MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg,
+ dl, DAG, VA, Flags));
}
}
@@ -1840,7 +1893,6 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
InFlag = Chain.getValue(1);
}
-
if (Subtarget->isPICStyleGOT()) {
// ELF / PIC requires GOT in the EBX register before function calls via PLT
// GOT pointer.
@@ -1910,9 +1962,11 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
int FI = 0;
// Do not flag preceeding copytoreg stuff together with the following stuff.
InFlag = SDValue();
- for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
- CCValAssign &VA = ArgLocs[i];
- if (!VA.isRegLoc()) {
+ if (GuaranteedTailCallOpt) {
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ CCValAssign &VA = ArgLocs[i];
+ if (VA.isRegLoc())
+ continue;
assert(VA.isMemLoc());
SDValue Arg = Outs[i].Val;
ISD::ArgFlagsTy Flags = Outs[i].Flags;
@@ -1937,7 +1991,8 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// Store relative to framepointer.
MemOpChains2.push_back(
DAG.getStore(ArgChain, dl, Arg, FIN,
- PseudoSourceValue::getFixedStack(FI), 0));
+ PseudoSourceValue::getFixedStack(FI), 0,
+ false, false, 0));
}
}
}
@@ -2020,21 +2075,22 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
}
if (isTailCall && !WasGlobalOrExternal) {
- unsigned Opc = Is64Bit ? X86::R11 : X86::EAX;
-
+ // Force the address into a (call preserved) caller-saved register since
+ // tailcall must happen after callee-saved registers are poped.
+ // FIXME: Give it a special register class that contains caller-saved
+ // register instead?
+ unsigned TCReg = Is64Bit ? X86::R11 : X86::EAX;
Chain = DAG.getCopyToReg(Chain, dl,
- DAG.getRegister(Opc, getPointerTy()),
+ DAG.getRegister(TCReg, getPointerTy()),
Callee,InFlag);
- Callee = DAG.getRegister(Opc, getPointerTy());
- // Add register as live out.
- MF.getRegInfo().addLiveOut(Opc);
+ Callee = DAG.getRegister(TCReg, getPointerTy());
}
// Returns a chain & a flag for retval copy to use.
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
SmallVector<SDValue, 8> Ops;
- if (isTailCall) {
+ if (!IsSibcall && isTailCall) {
Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true),
DAG.getIntPtrConstant(0, true), InFlag);
InFlag = Chain.getValue(1);
@@ -2095,7 +2151,7 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (IsCalleePop(isVarArg, CallConv))
NumBytesForCalleeToPush = NumBytes; // Callee pops everything
else if (!Is64Bit && CallConv != CallingConv::Fast && IsStructRet)
- // If this is is a call to a struct-return function, the callee
+ // If this is a call to a struct-return function, the callee
// pops the hidden struct pointer, so we have to push it back.
// This is common for Darwin/X86, Linux & Mingw32 targets.
NumBytesForCalleeToPush = 4;
@@ -2103,12 +2159,14 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
NumBytesForCalleeToPush = 0; // Callee pops nothing.
// Returns a flag for retval copy to use.
- Chain = DAG.getCALLSEQ_END(Chain,
- DAG.getIntPtrConstant(NumBytes, true),
- DAG.getIntPtrConstant(NumBytesForCalleeToPush,
- true),
- InFlag);
- InFlag = Chain.getValue(1);
+ if (!IsSibcall) {
+ Chain = DAG.getCALLSEQ_END(Chain,
+ DAG.getIntPtrConstant(NumBytes, true),
+ DAG.getIntPtrConstant(NumBytesForCalleeToPush,
+ true),
+ InFlag);
+ InFlag = Chain.getValue(1);
+ }
// Handle result values, copying them out of physregs into vregs that we
// return.
@@ -2170,6 +2228,50 @@ unsigned X86TargetLowering::GetAlignedArgumentStackSize(unsigned StackSize,
return Offset;
}
+/// MatchingStackOffset - Return true if the given stack call argument is
+/// already available in the same position (relatively) of the caller's
+/// incoming argument stack.
+static
+bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
+ MachineFrameInfo *MFI, const MachineRegisterInfo *MRI,
+ const X86InstrInfo *TII) {
+ int FI;
+ if (Arg.getOpcode() == ISD::CopyFromReg) {
+ unsigned VR = cast<RegisterSDNode>(Arg.getOperand(1))->getReg();
+ if (!VR || TargetRegisterInfo::isPhysicalRegister(VR))
+ return false;
+ MachineInstr *Def = MRI->getVRegDef(VR);
+ if (!Def)
+ return false;
+ if (!Flags.isByVal()) {
+ if (!TII->isLoadFromStackSlot(Def, FI))
+ return false;
+ } else {
+ unsigned Opcode = Def->getOpcode();
+ if ((Opcode == X86::LEA32r || Opcode == X86::LEA64r) &&
+ Def->getOperand(1).isFI()) {
+ FI = Def->getOperand(1).getIndex();
+ if (MFI->getObjectSize(FI) != Flags.getByValSize())
+ return false;
+ } else
+ return false;
+ }
+ } else {
+ LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg);
+ if (!Ld)
+ return false;
+ SDValue Ptr = Ld->getBasePtr();
+ FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(Ptr);
+ if (!FINode)
+ return false;
+ FI = FINode->getIndex();
+ }
+
+ if (!MFI->isFixedObjectIndex(FI))
+ return false;
+ return Offset == MFI->getObjectOffset(FI);
+}
+
/// IsEligibleForTailCallOptimization - Check whether the call is eligible
/// for tail call optimization. Targets which want to do tail call
/// optimization should implement this function.
@@ -2177,23 +2279,79 @@ bool
X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
CallingConv::ID CalleeCC,
bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
SelectionDAG& DAG) const {
- MachineFunction &MF = DAG.getMachineFunction();
- CallingConv::ID CallerCC = MF.getFunction()->getCallingConv();
- return CalleeCC == CallingConv::Fast && CallerCC == CalleeCC;
+ if (CalleeCC != CallingConv::Fast &&
+ CalleeCC != CallingConv::C)
+ return false;
+
+ // If -tailcallopt is specified, make fastcc functions tail-callable.
+ const Function *CallerF = DAG.getMachineFunction().getFunction();
+ if (GuaranteedTailCallOpt) {
+ if (CalleeCC == CallingConv::Fast &&
+ CallerF->getCallingConv() == CalleeCC)
+ return true;
+ return false;
+ }
+
+ // Look for obvious safe cases to perform tail call optimization that does not
+ // requite ABI changes. This is what gcc calls sibcall.
+
+ // Do not tail call optimize vararg calls for now.
+ if (isVarArg)
+ return false;
+
+ // If the callee takes no arguments then go on to check the results of the
+ // call.
+ if (!Outs.empty()) {
+ // Check if stack adjustment is needed. For now, do not do this if any
+ // argument is passed on the stack.
+ SmallVector<CCValAssign, 16> ArgLocs;
+ CCState CCInfo(CalleeCC, isVarArg, getTargetMachine(),
+ ArgLocs, *DAG.getContext());
+ CCInfo.AnalyzeCallOperands(Outs, CCAssignFnForNode(CalleeCC));
+ if (CCInfo.getNextStackOffset()) {
+ MachineFunction &MF = DAG.getMachineFunction();
+ if (MF.getInfo<X86MachineFunctionInfo>()->getBytesToPopOnReturn())
+ return false;
+ if (Subtarget->isTargetWin64())
+ // Win64 ABI has additional complications.
+ return false;
+
+ // Check if the arguments are already laid out in the right way as
+ // the caller's fixed stack objects.
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ const MachineRegisterInfo *MRI = &MF.getRegInfo();
+ const X86InstrInfo *TII =
+ ((X86TargetMachine&)getTargetMachine()).getInstrInfo();
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ CCValAssign &VA = ArgLocs[i];
+ EVT RegVT = VA.getLocVT();
+ SDValue Arg = Outs[i].Val;
+ ISD::ArgFlagsTy Flags = Outs[i].Flags;
+ if (VA.getLocInfo() == CCValAssign::Indirect)
+ return false;
+ if (!VA.isRegLoc()) {
+ if (!MatchingStackOffset(Arg, VA.getLocMemOffset(), Flags,
+ MFI, MRI, TII))
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
}
FastISel *
-X86TargetLowering::createFastISel(MachineFunction &mf,
- MachineModuleInfo *mmo,
- DwarfWriter *dw,
- DenseMap<const Value *, unsigned> &vm,
- DenseMap<const BasicBlock *,
- MachineBasicBlock *> &bm,
- DenseMap<const AllocaInst *, int> &am
+X86TargetLowering::createFastISel(MachineFunction &mf, MachineModuleInfo *mmo,
+ DwarfWriter *dw,
+ DenseMap<const Value *, unsigned> &vm,
+ DenseMap<const BasicBlock*, MachineBasicBlock*> &bm,
+ DenseMap<const AllocaInst *, int> &am
#ifndef NDEBUG
- , SmallSet<Instruction*, 8> &cil
+ , SmallSet<Instruction*, 8> &cil
#endif
) {
return X86::createFastISel(mf, mmo, dw, vm, bm, am
@@ -3413,7 +3571,8 @@ X86TargetLowering::LowerAsSplatVectorLoad(SDValue SrcOp, EVT VT, DebugLoc dl,
int EltNo = (Offset - StartOffset) >> 2;
int Mask[4] = { EltNo, EltNo, EltNo, EltNo };
EVT VT = (PVT == MVT::i32) ? MVT::v4i32 : MVT::v4f32;
- SDValue V1 = DAG.getLoad(VT, dl, Chain, Ptr,LD->getSrcValue(),0);
+ SDValue V1 = DAG.getLoad(VT, dl, Chain, Ptr,LD->getSrcValue(),0,
+ false, false, 0);
// Canonicalize it to a v4i32 shuffle.
V1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4i32, V1);
return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
@@ -3686,6 +3845,33 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
return SDValue();
}
+SDValue
+X86TargetLowering::LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) {
+ // We support concatenate two MMX registers and place them in a MMX
+ // register. This is better than doing a stack convert.
+ DebugLoc dl = Op.getDebugLoc();
+ EVT ResVT = Op.getValueType();
+ assert(Op.getNumOperands() == 2);
+ assert(ResVT == MVT::v2i64 || ResVT == MVT::v4i32 ||
+ ResVT == MVT::v8i16 || ResVT == MVT::v16i8);
+ int Mask[2];
+ SDValue InVec = DAG.getNode(ISD::BIT_CONVERT,dl, MVT::v1i64, Op.getOperand(0));
+ SDValue VecOp = DAG.getNode(X86ISD::MOVQ2DQ, dl, MVT::v2i64, InVec);
+ InVec = Op.getOperand(1);
+ if (InVec.getOpcode() == ISD::SCALAR_TO_VECTOR) {
+ unsigned NumElts = ResVT.getVectorNumElements();
+ VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, ResVT, VecOp);
+ VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, ResVT, VecOp,
+ InVec.getOperand(0), DAG.getIntPtrConstant(NumElts/2+1));
+ } else {
+ InVec = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v1i64, InVec);
+ SDValue VecOp2 = DAG.getNode(X86ISD::MOVQ2DQ, dl, MVT::v2i64, InVec);
+ Mask[0] = 0; Mask[1] = 2;
+ VecOp = DAG.getVectorShuffle(MVT::v2i64, dl, VecOp, VecOp2, Mask);
+ }
+ return DAG.getNode(ISD::BIT_CONVERT, dl, ResVT, VecOp);
+}
+
// v8i16 shuffles - Prefer shuffles in the following order:
// 1. [all] pshuflw, pshufhw, optional move
// 2. [ssse3] 1 x pshufb
@@ -4885,7 +5071,7 @@ X86TargetLowering::LowerGlobalAddress(const GlobalValue *GV, DebugLoc dl,
// load.
if (isGlobalStubReference(OpFlags))
Result = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), Result,
- PseudoSourceValue::getGOT(), 0);
+ PseudoSourceValue::getGOT(), 0, false, false, 0);
// If there was a non-zero offset that we didn't fold, create an explicit
// addition for it.
@@ -4965,7 +5151,7 @@ static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
MVT::i32));
SDValue ThreadPointer = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Base,
- NULL, 0);
+ NULL, 0, false, false, 0);
unsigned char OperandFlags = 0;
// Most TLS accesses are not RIP relative, even on x86-64. One exception is
@@ -4990,7 +5176,7 @@ static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
if (model == TLSModel::InitialExec)
Offset = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Offset,
- PseudoSourceValue::getGOT(), 0);
+ PseudoSourceValue::getGOT(), 0, false, false, 0);
// The address of the thread local variable is the add of the thread
// pointer with the offset of the variable.
@@ -5107,7 +5293,8 @@ SDValue X86TargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
SDValue StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl, Op.getOperand(0),
StackSlot,
- PseudoSourceValue::getFixedStack(SSFI), 0);
+ PseudoSourceValue::getFixedStack(SSFI), 0,
+ false, false, 0);
return BuildFILD(Op, SrcVT, Chain, StackSlot, DAG);
}
@@ -5142,7 +5329,8 @@ SDValue X86TargetLowering::BuildFILD(SDValue Op, EVT SrcVT, SDValue Chain,
};
Chain = DAG.getNode(X86ISD::FST, dl, Tys, Ops, array_lengthof(Ops));
Result = DAG.getLoad(Op.getValueType(), dl, Chain, StackSlot,
- PseudoSourceValue::getFixedStack(SSFI), 0);
+ PseudoSourceValue::getFixedStack(SSFI), 0,
+ false, false, 0);
}
return Result;
@@ -5215,12 +5403,12 @@ SDValue X86TargetLowering::LowerUINT_TO_FP_i64(SDValue Op, SelectionDAG &DAG) {
SDValue Unpck1 = getUnpackl(DAG, dl, MVT::v4i32, XR1, XR2);
SDValue CLod0 = DAG.getLoad(MVT::v4i32, dl, DAG.getEntryNode(), CPIdx0,
PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ false, false, 16);
SDValue Unpck2 = getUnpackl(DAG, dl, MVT::v4i32, Unpck1, CLod0);
SDValue XR2F = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64, Unpck2);
SDValue CLod1 = DAG.getLoad(MVT::v2f64, dl, CLod0.getValue(1), CPIdx1,
PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ false, false, 16);
SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::v2f64, XR2F, CLod1);
// Add the halves; easiest way is to swap them into another reg first.
@@ -5307,9 +5495,9 @@ SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
SDValue OffsetSlot = DAG.getNode(ISD::ADD, dl,
getPointerTy(), StackSlot, WordOff);
SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, Op.getOperand(0),
- StackSlot, NULL, 0);
+ StackSlot, NULL, 0, false, false, 0);
SDValue Store2 = DAG.getStore(Store1, dl, DAG.getConstant(0, MVT::i32),
- OffsetSlot, NULL, 0);
+ OffsetSlot, NULL, 0, false, false, 0);
return BuildFILD(Op, MVT::i64, Store2, StackSlot, DAG);
}
@@ -5357,7 +5545,8 @@ FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG, bool IsSigned) {
if (isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType())) {
assert(DstTy == MVT::i64 && "Invalid FP_TO_SINT to lower!");
Chain = DAG.getStore(Chain, dl, Value, StackSlot,
- PseudoSourceValue::getFixedStack(SSFI), 0);
+ PseudoSourceValue::getFixedStack(SSFI), 0,
+ false, false, 0);
SDVTList Tys = DAG.getVTList(Op.getOperand(0).getValueType(), MVT::Other);
SDValue Ops[] = {
Chain, StackSlot, DAG.getValueType(Op.getOperand(0).getValueType())
@@ -5391,7 +5580,7 @@ SDValue X86TargetLowering::LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
// Load the result.
return DAG.getLoad(Op.getValueType(), Op.getDebugLoc(),
- FIST, StackSlot, NULL, 0);
+ FIST, StackSlot, NULL, 0, false, false, 0);
}
SDValue X86TargetLowering::LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG) {
@@ -5401,7 +5590,7 @@ SDValue X86TargetLowering::LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG) {
// Load the result.
return DAG.getLoad(Op.getValueType(), Op.getDebugLoc(),
- FIST, StackSlot, NULL, 0);
+ FIST, StackSlot, NULL, 0, false, false, 0);
}
SDValue X86TargetLowering::LowerFABS(SDValue Op, SelectionDAG &DAG) {
@@ -5426,8 +5615,8 @@ SDValue X86TargetLowering::LowerFABS(SDValue Op, SelectionDAG &DAG) {
Constant *C = ConstantVector::get(CV);
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
SDValue Mask = DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
- PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 16);
return DAG.getNode(X86ISD::FAND, dl, VT, Op.getOperand(0), Mask);
}
@@ -5453,8 +5642,8 @@ SDValue X86TargetLowering::LowerFNEG(SDValue Op, SelectionDAG &DAG) {
Constant *C = ConstantVector::get(CV);
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
SDValue Mask = DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
- PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 16);
if (VT.isVector()) {
return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
DAG.getNode(ISD::XOR, dl, MVT::v2i64,
@@ -5502,8 +5691,8 @@ SDValue X86TargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) {
Constant *C = ConstantVector::get(CV);
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
SDValue Mask1 = DAG.getLoad(SrcVT, dl, DAG.getEntryNode(), CPIdx,
- PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 16);
SDValue SignBit = DAG.getNode(X86ISD::FAND, dl, SrcVT, Op1, Mask1);
// Shift sign bit right or left if the two operands have different types.
@@ -5531,8 +5720,8 @@ SDValue X86TargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) {
C = ConstantVector::get(CV);
CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
SDValue Mask2 = DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
- PseudoSourceValue::getConstantPool(), 0,
- false, 16);
+ PseudoSourceValue::getConstantPool(), 0,
+ false, false, 16);
SDValue Val = DAG.getNode(X86ISD::FAND, dl, VT, Op0, Mask2);
// Or the value with the sign bit.
@@ -5919,6 +6108,29 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
Cond = NewCond;
}
+ // (select (x == 0), -1, 0) -> (sign_bit (x - 1))
+ SDValue Op1 = Op.getOperand(1);
+ SDValue Op2 = Op.getOperand(2);
+ if (Cond.getOpcode() == X86ISD::SETCC &&
+ cast<ConstantSDNode>(Cond.getOperand(0))->getZExtValue() == X86::COND_E) {
+ SDValue Cmp = Cond.getOperand(1);
+ if (Cmp.getOpcode() == X86ISD::CMP) {
+ ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(Op1);
+ ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(Op2);
+ ConstantSDNode *RHSC =
+ dyn_cast<ConstantSDNode>(Cmp.getOperand(1).getNode());
+ if (N1C && N1C->isAllOnesValue() &&
+ N2C && N2C->isNullValue() &&
+ RHSC && RHSC->isNullValue()) {
+ SDValue CmpOp0 = Cmp.getOperand(0);
+ Cmp = DAG.getNode(X86ISD::CMP, dl, CmpOp0.getValueType(),
+ CmpOp0, DAG.getConstant(1, CmpOp0.getValueType()));
+ return DAG.getNode(X86ISD::SETCC_CARRY, dl, Op.getValueType(),
+ DAG.getConstant(X86::COND_B, MVT::i8), Cmp);
+ }
+ }
+ }
+
// Look pass (and (setcc_carry (cmp ...)), 1).
if (Cond.getOpcode() == ISD::AND &&
Cond.getOperand(0).getOpcode() == X86ISD::SETCC_CARRY) {
@@ -5971,10 +6183,10 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
Cond = EmitTest(Cond, X86::COND_NE, DAG);
}
- SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
// X86ISD::CMOV means set the result (which is operand 1) to the RHS if
// condition is true.
- SDValue Ops[] = { Op.getOperand(2), Op.getOperand(1), CC, Cond };
+ SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
+ SDValue Ops[] = { Op2, Op1, CC, Cond };
return DAG.getNode(X86ISD::CMOV, dl, VTs, Ops, array_lengthof(Ops));
}
@@ -6417,7 +6629,8 @@ SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) {
// vastart just stores the address of the VarArgsFrameIndex slot into the
// memory location argument.
SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
- return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
// __va_list_tag:
@@ -6429,8 +6642,8 @@ SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) {
SDValue FIN = Op.getOperand(1);
// Store gp_offset
SDValue Store = DAG.getStore(Op.getOperand(0), dl,
- DAG.getConstant(VarArgsGPOffset, MVT::i32),
- FIN, SV, 0);
+ DAG.getConstant(VarArgsGPOffset, MVT::i32),
+ FIN, SV, 0, false, false, 0);
MemOps.push_back(Store);
// Store fp_offset
@@ -6438,21 +6651,23 @@ SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) {
FIN, DAG.getIntPtrConstant(4));
Store = DAG.getStore(Op.getOperand(0), dl,
DAG.getConstant(VarArgsFPOffset, MVT::i32),
- FIN, SV, 0);
+ FIN, SV, 0, false, false, 0);
MemOps.push_back(Store);
// Store ptr to overflow_arg_area
FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(),
FIN, DAG.getIntPtrConstant(4));
SDValue OVFIN = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
- Store = DAG.getStore(Op.getOperand(0), dl, OVFIN, FIN, SV, 0);
+ Store = DAG.getStore(Op.getOperand(0), dl, OVFIN, FIN, SV, 0,
+ false, false, 0);
MemOps.push_back(Store);
// Store ptr to reg_save_area.
FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(),
FIN, DAG.getIntPtrConstant(8));
SDValue RSFIN = DAG.getFrameIndex(RegSaveFrameIndex, getPointerTy());
- Store = DAG.getStore(Op.getOperand(0), dl, RSFIN, FIN, SV, 0);
+ Store = DAG.getStore(Op.getOperand(0), dl, RSFIN, FIN, SV, 0,
+ false, false, 0);
MemOps.push_back(Store);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
&MemOps[0], MemOps.size());
@@ -6738,13 +6953,13 @@ SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
DAG.getNode(ISD::ADD, dl, getPointerTy(),
FrameAddr, Offset),
- NULL, 0);
+ NULL, 0, false, false, 0);
}
// Just load the return address.
SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
- RetAddrFI, NULL, 0);
+ RetAddrFI, NULL, 0, false, false, 0);
}
SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
@@ -6756,7 +6971,8 @@ SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
unsigned FrameReg = Subtarget->is64Bit() ? X86::RBP : X86::EBP;
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
while (Depth--)
- FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0);
+ FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0,
+ false, false, 0);
return FrameAddr;
}
@@ -6780,7 +6996,7 @@ SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG)
SDValue StoreAddr = DAG.getNode(ISD::SUB, dl, getPointerTy(), Frame,
DAG.getIntPtrConstant(-TD->getPointerSize()));
StoreAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(), StoreAddr, Offset);
- Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, NULL, 0);
+ Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, NULL, 0, false, false, 0);
Chain = DAG.getCopyToReg(Chain, dl, StoreAddrReg, StoreAddr);
MF.getRegInfo().addLiveOut(StoreAddrReg);
@@ -6799,16 +7015,12 @@ SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
const Value *TrmpAddr = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
- const X86InstrInfo *TII =
- ((X86TargetMachine&)getTargetMachine()).getInstrInfo();
-
if (Subtarget->is64Bit()) {
SDValue OutChains[6];
// Large code-model.
-
- const unsigned char JMP64r = TII->getBaseOpcodeFor(X86::JMP64r);
- const unsigned char MOV64ri = TII->getBaseOpcodeFor(X86::MOV64ri);
+ const unsigned char JMP64r = 0xFF; // 64-bit jmp through register opcode.
+ const unsigned char MOV64ri = 0xB8; // X86::MOV64ri opcode.
const unsigned char N86R10 = RegInfo->getX86RegNum(X86::R10);
const unsigned char N86R11 = RegInfo->getX86RegNum(X86::R11);
@@ -6819,11 +7031,12 @@ SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
unsigned OpCode = ((MOV64ri | N86R11) << 8) | REX_WB; // movabsq r11
SDValue Addr = Trmp;
OutChains[0] = DAG.getStore(Root, dl, DAG.getConstant(OpCode, MVT::i16),
- Addr, TrmpAddr, 0);
+ Addr, TrmpAddr, 0, false, false, 0);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(2, MVT::i64));
- OutChains[1] = DAG.getStore(Root, dl, FPtr, Addr, TrmpAddr, 2, false, 2);
+ OutChains[1] = DAG.getStore(Root, dl, FPtr, Addr, TrmpAddr, 2,
+ false, false, 2);
// Load the 'nest' parameter value into R10.
// R10 is specified in X86CallingConv.td
@@ -6831,24 +7044,25 @@ SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(10, MVT::i64));
OutChains[2] = DAG.getStore(Root, dl, DAG.getConstant(OpCode, MVT::i16),
- Addr, TrmpAddr, 10);
+ Addr, TrmpAddr, 10, false, false, 0);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(12, MVT::i64));
- OutChains[3] = DAG.getStore(Root, dl, Nest, Addr, TrmpAddr, 12, false, 2);
+ OutChains[3] = DAG.getStore(Root, dl, Nest, Addr, TrmpAddr, 12,
+ false, false, 2);
// Jump to the nested function.
OpCode = (JMP64r << 8) | REX_WB; // jmpq *...
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(20, MVT::i64));
OutChains[4] = DAG.getStore(Root, dl, DAG.getConstant(OpCode, MVT::i16),
- Addr, TrmpAddr, 20);
+ Addr, TrmpAddr, 20, false, false, 0);
unsigned char ModRM = N86R11 | (4 << 3) | (3 << 6); // ...r11
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(22, MVT::i64));
OutChains[5] = DAG.getStore(Root, dl, DAG.getConstant(ModRM, MVT::i8), Addr,
- TrmpAddr, 22);
+ TrmpAddr, 22, false, false, 0);
SDValue Ops[] =
{ Trmp, DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains, 6) };
@@ -6903,25 +7117,28 @@ SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
DAG.getConstant(10, MVT::i32));
Disp = DAG.getNode(ISD::SUB, dl, MVT::i32, FPtr, Addr);
- const unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
+ // This is storing the opcode for MOV32ri.
+ const unsigned char MOV32ri = 0xB8; // X86::MOV32ri's opcode byte.
const unsigned char N86Reg = RegInfo->getX86RegNum(NestReg);
OutChains[0] = DAG.getStore(Root, dl,
DAG.getConstant(MOV32ri|N86Reg, MVT::i8),
- Trmp, TrmpAddr, 0);
+ Trmp, TrmpAddr, 0, false, false, 0);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
DAG.getConstant(1, MVT::i32));
- OutChains[1] = DAG.getStore(Root, dl, Nest, Addr, TrmpAddr, 1, false, 1);
+ OutChains[1] = DAG.getStore(Root, dl, Nest, Addr, TrmpAddr, 1,
+ false, false, 1);
- const unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
+ const unsigned char JMP = 0xE9; // jmp <32bit dst> opcode.
Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
DAG.getConstant(5, MVT::i32));
OutChains[2] = DAG.getStore(Root, dl, DAG.getConstant(JMP, MVT::i8), Addr,
- TrmpAddr, 5, false, 1);
+ TrmpAddr, 5, false, false, 1);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
DAG.getConstant(6, MVT::i32));
- OutChains[3] = DAG.getStore(Root, dl, Disp, Addr, TrmpAddr, 6, false, 1);
+ OutChains[3] = DAG.getStore(Root, dl, Disp, Addr, TrmpAddr, 6,
+ false, false, 1);
SDValue Ops[] =
{ Trmp, DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains, 4) };
@@ -6964,7 +7181,8 @@ SDValue X86TargetLowering::LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) {
DAG.getEntryNode(), StackSlot);
// Load FP Control Word from stack slot
- SDValue CWD = DAG.getLoad(MVT::i16, dl, Chain, StackSlot, NULL, 0);
+ SDValue CWD = DAG.getLoad(MVT::i16, dl, Chain, StackSlot, NULL, 0,
+ false, false, 0);
// Transform as necessary
SDValue CWD1 =
@@ -7238,6 +7456,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
case ISD::ATOMIC_CMP_SWAP: return LowerCMP_SWAP(Op,DAG);
case ISD::ATOMIC_LOAD_SUB: return LowerLOAD_SUB(Op,DAG);
case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);
+ case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG);
case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG);
@@ -7327,7 +7546,8 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
if (FIST.getNode() != 0) {
EVT VT = N->getValueType(0);
// Return a load from the stack slot.
- Results.push_back(DAG.getLoad(VT, dl, FIST, StackSlot, NULL, 0));
+ Results.push_back(DAG.getLoad(VT, dl, FIST, StackSlot, NULL, 0,
+ false, false, 0));
}
return;
}
@@ -7345,14 +7565,6 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
Results.push_back(edx.getValue(1));
return;
}
- case ISD::SDIV:
- case ISD::UDIV:
- case ISD::SREM:
- case ISD::UREM: {
- EVT WidenVT = getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
- Results.push_back(DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements()));
- return;
- }
case ISD::ATOMIC_CMP_SWAP: {
EVT T = N->getValueType(0);
assert (T == MVT::i64 && "Only know how to expand i64 Cmp and Swap");
@@ -7551,7 +7763,7 @@ bool X86TargetLowering::isLegalAddressingMode(const AddrMode &AM,
bool X86TargetLowering::isTruncateFree(const Type *Ty1, const Type *Ty2) const {
- if (!Ty1->isInteger() || !Ty2->isInteger())
+ if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
return false;
unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
@@ -7572,7 +7784,7 @@ bool X86TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
bool X86TargetLowering::isZExtFree(const Type *Ty1, const Type *Ty2) const {
// x86-64 implicitly zero-extends 32-bit results in 64-bit registers.
- return Ty1->isInteger(32) && Ty2->isInteger(64) && Subtarget->is64Bit();
+ return Ty1->isIntegerTy(32) && Ty2->isIntegerTy(64) && Subtarget->is64Bit();
}
bool X86TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
@@ -7728,7 +7940,7 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
MIB.addReg(EAXreg);
// insert branch
- BuildMI(newMBB, dl, TII->get(X86::JNE)).addMBB(newMBB);
+ BuildMI(newMBB, dl, TII->get(X86::JNE_4)).addMBB(newMBB);
F->DeleteMachineInstr(bInstr); // The pseudo instruction is gone now.
return nextMBB;
@@ -7885,7 +8097,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
MIB.addReg(X86::EDX);
// insert branch
- BuildMI(newMBB, dl, TII->get(X86::JNE)).addMBB(newMBB);
+ BuildMI(newMBB, dl, TII->get(X86::JNE_4)).addMBB(newMBB);
F->DeleteMachineInstr(bInstr); // The pseudo instruction is gone now.
return nextMBB;
@@ -7988,7 +8200,7 @@ X86TargetLowering::EmitAtomicMinMaxWithCustomInserter(MachineInstr *mInstr,
MIB.addReg(X86::EAX);
// insert branch
- BuildMI(newMBB, dl, TII->get(X86::JNE)).addMBB(newMBB);
+ BuildMI(newMBB, dl, TII->get(X86::JNE_4)).addMBB(newMBB);
F->DeleteMachineInstr(mInstr); // The pseudo instruction is gone now.
return nextMBB;
@@ -8070,7 +8282,7 @@ X86TargetLowering::EmitVAStartSaveXMMRegsWithCustomInserter(
if (!Subtarget->isTargetWin64()) {
// If %al is 0, branch around the XMM save block.
BuildMI(MBB, DL, TII->get(X86::TEST8rr)).addReg(CountReg).addReg(CountReg);
- BuildMI(MBB, DL, TII->get(X86::JE)).addMBB(EndMBB);
+ BuildMI(MBB, DL, TII->get(X86::JE_4)).addMBB(EndMBB);
MBB->addSuccessor(EndMBB);
}
@@ -8556,10 +8768,11 @@ static SDValue PerformShuffleCombine(SDNode *N, SelectionDAG &DAG,
if (DAG.InferPtrAlignment(LD->getBasePtr()) >= 16)
return DAG.getLoad(VT, dl, LD->getChain(), LD->getBasePtr(),
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile());
+ LD->isVolatile(), LD->isNonTemporal(), 0);
return DAG.getLoad(VT, dl, LD->getChain(), LD->getBasePtr(),
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
+ LD->isVolatile(), LD->isNonTemporal(),
+ LD->getAlignment());
} else if (NumElems == 4 && LastLoadedElt == 1) {
SDVTList Tys = DAG.getVTList(MVT::v2i64, MVT::Other);
SDValue Ops[] = { LD->getChain(), LD->getBasePtr() };
@@ -9278,7 +9491,7 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
SDValue NewLd = DAG.getLoad(LdVT, LdDL, Ld->getChain(),
Ld->getBasePtr(), Ld->getSrcValue(),
Ld->getSrcValueOffset(), Ld->isVolatile(),
- Ld->getAlignment());
+ Ld->isNonTemporal(), Ld->getAlignment());
SDValue NewChain = NewLd.getValue(1);
if (TokenFactorIndex != -1) {
Ops.push_back(NewChain);
@@ -9287,7 +9500,8 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
}
return DAG.getStore(NewChain, StDL, NewLd, St->getBasePtr(),
St->getSrcValue(), St->getSrcValueOffset(),
- St->isVolatile(), St->getAlignment());
+ St->isVolatile(), St->isNonTemporal(),
+ St->getAlignment());
}
// Otherwise, lower to two pairs of 32-bit loads / stores.
@@ -9297,10 +9511,11 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
SDValue LoLd = DAG.getLoad(MVT::i32, LdDL, Ld->getChain(), LoAddr,
Ld->getSrcValue(), Ld->getSrcValueOffset(),
- Ld->isVolatile(), Ld->getAlignment());
+ Ld->isVolatile(), Ld->isNonTemporal(),
+ Ld->getAlignment());
SDValue HiLd = DAG.getLoad(MVT::i32, LdDL, Ld->getChain(), HiAddr,
Ld->getSrcValue(), Ld->getSrcValueOffset()+4,
- Ld->isVolatile(),
+ Ld->isVolatile(), Ld->isNonTemporal(),
MinAlign(Ld->getAlignment(), 4));
SDValue NewChain = LoLd.getValue(1);
@@ -9317,11 +9532,13 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
SDValue LoSt = DAG.getStore(NewChain, StDL, LoLd, LoAddr,
St->getSrcValue(), St->getSrcValueOffset(),
- St->isVolatile(), St->getAlignment());
+ St->isVolatile(), St->isNonTemporal(),
+ St->getAlignment());
SDValue HiSt = DAG.getStore(NewChain, StDL, HiLd, HiAddr,
St->getSrcValue(),
St->getSrcValueOffset() + 4,
St->isVolatile(),
+ St->isNonTemporal(),
MinAlign(St->getAlignment(), 4));
return DAG.getNode(ISD::TokenFactor, StDL, MVT::Other, LoSt, HiSt);
}
@@ -9504,7 +9721,7 @@ static bool LowerToBSwap(CallInst *CI) {
// Verify this is a simple bswap.
if (CI->getNumOperands() != 2 ||
CI->getType() != CI->getOperand(1)->getType() ||
- !CI->getType()->isInteger())
+ !CI->getType()->isIntegerTy())
return false;
const IntegerType *Ty = dyn_cast<IntegerType>(CI->getType());
@@ -9553,7 +9770,7 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
return LowerToBSwap(CI);
}
// rorw $$8, ${0:w} --> llvm.bswap.i16
- if (CI->getType()->isInteger(16) &&
+ if (CI->getType()->isIntegerTy(16) &&
AsmPieces.size() == 3 &&
AsmPieces[0] == "rorw" &&
AsmPieces[1] == "$$8," &&
@@ -9563,7 +9780,7 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
}
break;
case 3:
- if (CI->getType()->isInteger(64) &&
+ if (CI->getType()->isIntegerTy(64) &&
Constraints.size() >= 2 &&
Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" &&
Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") {
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 64bc70c..cf0eb40 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -19,6 +19,7 @@
#include "X86RegisterInfo.h"
#include "X86MachineFunctionInfo.h"
#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetOptions.h"
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/CallingConvLower.h"
@@ -156,6 +157,11 @@ namespace llvm {
/// relative displacements.
WrapperRIP,
+ /// MOVQ2DQ - Copies a 64-bit value from a vector to another vector.
+ /// Can be used to move a vector value from a MMX register to a XMM
+ /// register.
+ MOVQ2DQ,
+
/// PEXTRB - Extract an 8-bit value from a vector and zero extend it to
/// i32, corresponds to X86::PEXTRB.
PEXTRB,
@@ -366,25 +372,33 @@ namespace llvm {
unsigned VarArgsGPOffset; // X86-64 vararg func int reg offset.
unsigned VarArgsFPOffset; // X86-64 vararg func fp reg offset.
int BytesToPopOnReturn; // Number of arg bytes ret should pop.
- int BytesCallerReserves; // Number of arg bytes caller makes.
public:
explicit X86TargetLowering(X86TargetMachine &TM);
+ /// getPICBaseSymbol - Return the X86-32 PIC base.
+ MCSymbol *getPICBaseSymbol(const MachineFunction *MF, MCContext &Ctx) const;
+
+ virtual unsigned getJumpTableEncoding() const;
+
+ virtual const MCExpr *
+ LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
+ const MachineBasicBlock *MBB, unsigned uid,
+ MCContext &Ctx) const;
+
/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
/// jumptable.
- SDValue getPICJumpTableRelocBase(SDValue Table,
- SelectionDAG &DAG) const;
-
+ virtual SDValue getPICJumpTableRelocBase(SDValue Table,
+ SelectionDAG &DAG) const;
+ virtual const MCExpr *
+ getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
+ unsigned JTI, MCContext &Ctx) const;
+
// Return the number of bytes that a function should pop when it returns (in
// addition to the space used by the return address).
//
unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; }
- // Return the number of bytes that the caller reserves for arguments passed
- // to this function.
- unsigned getBytesCallerReserves() const { return BytesCallerReserves; }
-
/// getStackPtrReg - Return the stack pointer register we are using: either
/// ESP or RSP.
unsigned getStackPtrReg() const { return X86StackPtr; }
@@ -532,16 +546,6 @@ namespace llvm {
return !X86ScalarSSEf64 || VT == MVT::f80;
}
- /// IsEligibleForTailCallOptimization - Check whether the call is eligible
- /// for tail call optimization. Targets which want to do tail call
- /// optimization should implement this function.
- virtual bool
- IsEligibleForTailCallOptimization(SDValue Callee,
- CallingConv::ID CalleeCC,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- SelectionDAG& DAG) const;
-
virtual const X86Subtarget* getSubtarget() {
return Subtarget;
}
@@ -619,13 +623,22 @@ namespace llvm {
ISD::ArgFlagsTy Flags);
// Call lowering helpers.
+
+ /// IsEligibleForTailCallOptimization - Check whether the call is eligible
+ /// for tail call optimization. Targets which want to do tail call
+ /// optimization should implement this function.
+ bool IsEligibleForTailCallOptimization(SDValue Callee,
+ CallingConv::ID CalleeCC,
+ bool isVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ SelectionDAG& DAG) const;
bool IsCalleePop(bool isVarArg, CallingConv::ID CallConv);
SDValue EmitTailCallLoadRetAddr(SelectionDAG &DAG, SDValue &OutRetAddr,
SDValue Chain, bool IsTailCall, bool Is64Bit,
int FPDiff, DebugLoc dl);
CCAssignFn *CCAssignFnForNode(CallingConv::ID CallConv) const;
- NameDecorationStyle NameDecorationForCallConv(CallingConv::ID CallConv);
unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG);
std::pair<SDValue,SDValue> FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG,
@@ -634,6 +647,7 @@ namespace llvm {
SDValue LowerAsSplatVectorLoad(SDValue SrcOp, EVT VT, DebugLoc dl,
SelectionDAG &DAG);
SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG);
SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG);
SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG);
SDValue LowerEXTRACT_VECTOR_ELT_SSE4(SDValue Op, SelectionDAG &DAG);
@@ -693,7 +707,7 @@ namespace llvm {
SmallVectorImpl<SDValue> &InVals);
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
- CallingConv::ID CallConv, bool isVarArg, bool isTailCall,
+ CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 9037ba6..4ea3739 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -187,7 +187,7 @@ def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64:$dst, i32imm:$offset,
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
- def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64:$dst),
+ def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64:$dst, variable_ops),
"jmp{q}\t{*}$dst # TAILCALL",
[]>;
@@ -435,7 +435,7 @@ def MOVZX64rm32 : I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
// up to 64 bits.
def def32 : PatLeaf<(i32 GR32:$src), [{
return N->getOpcode() != ISD::TRUNCATE &&
- N->getOpcode() != TargetInstrInfo::EXTRACT_SUBREG &&
+ N->getOpcode() != TargetOpcode::EXTRACT_SUBREG &&
N->getOpcode() != ISD::CopyFromReg &&
N->getOpcode() != X86ISD::CMOV;
}]>;
@@ -893,35 +893,38 @@ def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst),
let isTwoAddress = 1 in {
def RCL64r1 : RI<0xD1, MRM2r, (outs GR64:$dst), (ins GR64:$src),
"rcl{q}\t{1, $dst|$dst, 1}", []>;
-def RCL64m1 : RI<0xD1, MRM2m, (outs i64mem:$dst), (ins i64mem:$src),
- "rcl{q}\t{1, $dst|$dst, 1}", []>;
-let Uses = [CL] in {
-def RCL64rCL : RI<0xD3, MRM2r, (outs GR64:$dst), (ins GR64:$src),
- "rcl{q}\t{%cl, $dst|$dst, CL}", []>;
-def RCL64mCL : RI<0xD3, MRM2m, (outs i64mem:$dst), (ins i64mem:$src),
- "rcl{q}\t{%cl, $dst|$dst, CL}", []>;
-}
def RCL64ri : RIi8<0xC1, MRM2r, (outs GR64:$dst), (ins GR64:$src, i8imm:$cnt),
"rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCL64mi : RIi8<0xC1, MRM2m, (outs i64mem:$dst),
- (ins i64mem:$src, i8imm:$cnt),
- "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>;
def RCR64r1 : RI<0xD1, MRM3r, (outs GR64:$dst), (ins GR64:$src),
"rcr{q}\t{1, $dst|$dst, 1}", []>;
-def RCR64m1 : RI<0xD1, MRM3m, (outs i64mem:$dst), (ins i64mem:$src),
- "rcr{q}\t{1, $dst|$dst, 1}", []>;
+def RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src, i8imm:$cnt),
+ "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>;
+
let Uses = [CL] in {
+def RCL64rCL : RI<0xD3, MRM2r, (outs GR64:$dst), (ins GR64:$src),
+ "rcl{q}\t{%cl, $dst|$dst, CL}", []>;
def RCR64rCL : RI<0xD3, MRM3r, (outs GR64:$dst), (ins GR64:$src),
"rcr{q}\t{%cl, $dst|$dst, CL}", []>;
-def RCR64mCL : RI<0xD3, MRM3m, (outs i64mem:$dst), (ins i64mem:$src),
- "rcr{q}\t{%cl, $dst|$dst, CL}", []>;
}
-def RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src, i8imm:$cnt),
- "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCR64mi : RIi8<0xC1, MRM3m, (outs i64mem:$dst),
- (ins i64mem:$src, i8imm:$cnt),
+}
+
+let isTwoAddress = 0 in {
+def RCL64m1 : RI<0xD1, MRM2m, (outs), (ins i64mem:$dst),
+ "rcl{q}\t{1, $dst|$dst, 1}", []>;
+def RCL64mi : RIi8<0xC1, MRM2m, (outs), (ins i64mem:$dst, i8imm:$cnt),
+ "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>;
+def RCR64m1 : RI<0xD1, MRM3m, (outs), (ins i64mem:$dst),
+ "rcr{q}\t{1, $dst|$dst, 1}", []>;
+def RCR64mi : RIi8<0xC1, MRM3m, (outs), (ins i64mem:$dst, i8imm:$cnt),
"rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>;
+
+let Uses = [CL] in {
+def RCL64mCL : RI<0xD3, MRM2m, (outs), (ins i64mem:$dst),
+ "rcl{q}\t{%cl, $dst|$dst, CL}", []>;
+def RCR64mCL : RI<0xD3, MRM3m, (outs), (ins i64mem:$dst),
+ "rcr{q}\t{%cl, $dst|$dst, CL}", []>;
+}
}
let isTwoAddress = 1 in {
@@ -1466,9 +1469,13 @@ def CMOVNO64rm : RI<0x41, MRMSrcMem, // if !overflow, GR64 = [mem64]
} // isTwoAddress
// Use sbb to materialize carry flag into a GPR.
+// FIXME: This are pseudo ops that should be replaced with Pat<> patterns.
+// However, Pat<> can't replicate the destination reg into the inputs of the
+// result.
+// FIXME: Change this to have encoding Pseudo when X86MCCodeEmitter replaces
+// X86CodeEmitter.
let Defs = [EFLAGS], Uses = [EFLAGS], isCodeGenOnly = 1 in
-def SETB_C64r : RI<0x19, MRMInitReg, (outs GR64:$dst), (ins),
- "sbb{q}\t$dst, $dst",
+def SETB_C64r : RI<0x19, MRMInitReg, (outs GR64:$dst), (ins), "",
[(set GR64:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
def : Pat<(i64 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
@@ -1606,8 +1613,7 @@ def SLDT64m : RI<0x00, MRM0m, (outs i16mem:$dst), (ins),
// when we have a better way to specify isel priority.
let Defs = [EFLAGS],
AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in
-def MOV64r0 : I<0x31, MRMInitReg, (outs GR64:$dst), (ins),
- "",
+def MOV64r0 : I<0x31, MRMInitReg, (outs GR64:$dst), (ins), "",
[(set GR64:$dst, 0)]>;
// Materialize i64 constant where top 32-bits are zero. This could theoretically
@@ -1768,7 +1774,7 @@ def LSL64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
def LSL64rr : RI<0x03, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
"lsl{q}\t{$src, $dst|$dst, $src}", []>, TB;
-def SWPGS : I<0x01, RawFrm, (outs), (ins), "swpgs", []>, TB;
+def SWAPGS : I<0x01, MRM_F8, (outs), (ins), "swapgs", []>, TB;
def PUSHFS64 : I<0xa0, RawFrm, (outs), (ins),
"push{q}\t%fs", []>, TB;
diff --git a/lib/Target/X86/X86InstrFPStack.td b/lib/Target/X86/X86InstrFPStack.td
index 71ec178..e22a903 100644
--- a/lib/Target/X86/X86InstrFPStack.td
+++ b/lib/Target/X86/X86InstrFPStack.td
@@ -339,7 +339,6 @@ def FICOMP32m: FPI<0xDA, MRM3m, (outs), (ins i32mem:$src), "ficomp{l}\t$src">;
def FCOM64m : FPI<0xDC, MRM2m, (outs), (ins f64mem:$src), "fcom{ll}\t$src">;
def FCOMP64m : FPI<0xDC, MRM3m, (outs), (ins f64mem:$src), "fcomp{ll}\t$src">;
-def FISTTP32m: FPI<0xDD, MRM1m, (outs i32mem:$dst), (ins), "fisttp{l}\t$dst">;
def FRSTORm : FPI<0xDD, MRM4m, (outs f32mem:$dst), (ins), "frstor\t$dst">;
def FSAVEm : FPI<0xDD, MRM6m, (outs f32mem:$dst), (ins), "fnsave\t$dst">;
def FNSTSWm : FPI<0xDD, MRM7m, (outs f32mem:$dst), (ins), "fnstsw\t$dst">;
diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td
index a799f16..bb81cbf 100644
--- a/lib/Target/X86/X86InstrFormats.td
+++ b/lib/Target/X86/X86InstrFormats.td
@@ -29,7 +29,16 @@ def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>;
def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>;
def MRM6m : Format<30>; def MRM7m : Format<31>;
def MRMInitReg : Format<32>;
-
+def MRM_C1 : Format<33>;
+def MRM_C2 : Format<34>;
+def MRM_C3 : Format<35>;
+def MRM_C4 : Format<36>;
+def MRM_C8 : Format<37>;
+def MRM_C9 : Format<38>;
+def MRM_E8 : Format<39>;
+def MRM_F0 : Format<40>;
+def MRM_F8 : Format<41>;
+def MRM_F9 : Format<42>;
// ImmType - This specifies the immediate type used by an instruction. This is
// part of the ad-hoc solution used to emit machine instruction encodings by our
@@ -37,11 +46,13 @@ def MRMInitReg : Format<32>;
class ImmType<bits<3> val> {
bits<3> Value = val;
}
-def NoImm : ImmType<0>;
-def Imm8 : ImmType<1>;
-def Imm16 : ImmType<2>;
-def Imm32 : ImmType<3>;
-def Imm64 : ImmType<4>;
+def NoImm : ImmType<0>;
+def Imm8 : ImmType<1>;
+def Imm8PCRel : ImmType<2>;
+def Imm16 : ImmType<3>;
+def Imm32 : ImmType<4>;
+def Imm32PCRel : ImmType<5>;
+def Imm64 : ImmType<6>;
// FPFormat - This specifies what form this FP instruction has. This is used by
// the Floating-Point stackifier pass.
@@ -121,6 +132,12 @@ class Ii8 <bits<8> o, Format f, dag outs, dag ins, string asm,
let Pattern = pattern;
let CodeSize = 3;
}
+class Ii8PCRel<bits<8> o, Format f, dag outs, dag ins, string asm,
+ list<dag> pattern>
+ : X86Inst<o, f, Imm8PCRel, outs, ins, asm> {
+ let Pattern = pattern;
+ let CodeSize = 3;
+}
class Ii16<bits<8> o, Format f, dag outs, dag ins, string asm,
list<dag> pattern>
: X86Inst<o, f, Imm16, outs, ins, asm> {
@@ -134,6 +151,13 @@ class Ii32<bits<8> o, Format f, dag outs, dag ins, string asm,
let CodeSize = 3;
}
+class Ii32PCRel<bits<8> o, Format f, dag outs, dag ins, string asm,
+ list<dag> pattern>
+ : X86Inst<o, f, Imm32PCRel, outs, ins, asm> {
+ let Pattern = pattern;
+ let CodeSize = 3;
+}
+
// FPStack Instruction Templates:
// FPI - Floating Point Instruction template.
class FPI<bits<8> o, Format F, dag outs, dag ins, string asm>
diff --git a/lib/Target/X86/X86InstrFragmentsSIMD.td b/lib/Target/X86/X86InstrFragmentsSIMD.td
new file mode 100644
index 0000000..6b9478d
--- /dev/null
+++ b/lib/Target/X86/X86InstrFragmentsSIMD.td
@@ -0,0 +1,62 @@
+//======- X86InstrFragmentsSIMD.td - x86 ISA -------------*- tablegen -*-=====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides pattern fragments useful for SIMD instructions.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// MMX Pattern Fragments
+//===----------------------------------------------------------------------===//
+
+def load_mmx : PatFrag<(ops node:$ptr), (v1i64 (load node:$ptr))>;
+
+def bc_v8i8 : PatFrag<(ops node:$in), (v8i8 (bitconvert node:$in))>;
+def bc_v4i16 : PatFrag<(ops node:$in), (v4i16 (bitconvert node:$in))>;
+def bc_v2i32 : PatFrag<(ops node:$in), (v2i32 (bitconvert node:$in))>;
+def bc_v1i64 : PatFrag<(ops node:$in), (v1i64 (bitconvert node:$in))>;
+
+//===----------------------------------------------------------------------===//
+// MMX Masks
+//===----------------------------------------------------------------------===//
+
+// MMX_SHUFFLE_get_shuf_imm xform function: convert vector_shuffle mask to
+// PSHUFW imm.
+def MMX_SHUFFLE_get_shuf_imm : SDNodeXForm<vector_shuffle, [{
+ return getI8Imm(X86::getShuffleSHUFImmediate(N));
+}]>;
+
+// Patterns for: vector_shuffle v1, v2, <2, 6, 3, 7, ...>
+def mmx_unpckh : PatFrag<(ops node:$lhs, node:$rhs),
+ (vector_shuffle node:$lhs, node:$rhs), [{
+ return X86::isUNPCKHMask(cast<ShuffleVectorSDNode>(N));
+}]>;
+
+// Patterns for: vector_shuffle v1, v2, <0, 4, 2, 5, ...>
+def mmx_unpckl : PatFrag<(ops node:$lhs, node:$rhs),
+ (vector_shuffle node:$lhs, node:$rhs), [{
+ return X86::isUNPCKLMask(cast<ShuffleVectorSDNode>(N));
+}]>;
+
+// Patterns for: vector_shuffle v1, <undef>, <0, 0, 1, 1, ...>
+def mmx_unpckh_undef : PatFrag<(ops node:$lhs, node:$rhs),
+ (vector_shuffle node:$lhs, node:$rhs), [{
+ return X86::isUNPCKH_v_undef_Mask(cast<ShuffleVectorSDNode>(N));
+}]>;
+
+// Patterns for: vector_shuffle v1, <undef>, <2, 2, 3, 3, ...>
+def mmx_unpckl_undef : PatFrag<(ops node:$lhs, node:$rhs),
+ (vector_shuffle node:$lhs, node:$rhs), [{
+ return X86::isUNPCKL_v_undef_Mask(cast<ShuffleVectorSDNode>(N));
+}]>;
+
+def mmx_pshufw : PatFrag<(ops node:$lhs, node:$rhs),
+ (vector_shuffle node:$lhs, node:$rhs), [{
+ return X86::isPSHUFDMask(cast<ShuffleVectorSDNode>(N));
+}], MMX_SHUFFLE_get_shuf_imm>;
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 3ae352c..a0d0312 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -1060,8 +1060,7 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig,
const TargetRegisterInfo *TRI) const {
- DebugLoc DL = DebugLoc::getUnknownLoc();
- if (I != MBB.end()) DL = I->getDebugLoc();
+ DebugLoc DL = MBB.findDebugLoc(I);
if (SubIdx && TargetRegisterInfo::isPhysicalRegister(DestReg)) {
DestReg = TRI->getSubReg(DestReg, SubIdx);
@@ -1588,44 +1587,44 @@ X86InstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const {
static X86::CondCode GetCondFromBranchOpc(unsigned BrOpc) {
switch (BrOpc) {
default: return X86::COND_INVALID;
- case X86::JE: return X86::COND_E;
- case X86::JNE: return X86::COND_NE;
- case X86::JL: return X86::COND_L;
- case X86::JLE: return X86::COND_LE;
- case X86::JG: return X86::COND_G;
- case X86::JGE: return X86::COND_GE;
- case X86::JB: return X86::COND_B;
- case X86::JBE: return X86::COND_BE;
- case X86::JA: return X86::COND_A;
- case X86::JAE: return X86::COND_AE;
- case X86::JS: return X86::COND_S;
- case X86::JNS: return X86::COND_NS;
- case X86::JP: return X86::COND_P;
- case X86::JNP: return X86::COND_NP;
- case X86::JO: return X86::COND_O;
- case X86::JNO: return X86::COND_NO;
+ case X86::JE_4: return X86::COND_E;
+ case X86::JNE_4: return X86::COND_NE;
+ case X86::JL_4: return X86::COND_L;
+ case X86::JLE_4: return X86::COND_LE;
+ case X86::JG_4: return X86::COND_G;
+ case X86::JGE_4: return X86::COND_GE;
+ case X86::JB_4: return X86::COND_B;
+ case X86::JBE_4: return X86::COND_BE;
+ case X86::JA_4: return X86::COND_A;
+ case X86::JAE_4: return X86::COND_AE;
+ case X86::JS_4: return X86::COND_S;
+ case X86::JNS_4: return X86::COND_NS;
+ case X86::JP_4: return X86::COND_P;
+ case X86::JNP_4: return X86::COND_NP;
+ case X86::JO_4: return X86::COND_O;
+ case X86::JNO_4: return X86::COND_NO;
}
}
unsigned X86::GetCondBranchFromCond(X86::CondCode CC) {
switch (CC) {
default: llvm_unreachable("Illegal condition code!");
- case X86::COND_E: return X86::JE;
- case X86::COND_NE: return X86::JNE;
- case X86::COND_L: return X86::JL;
- case X86::COND_LE: return X86::JLE;
- case X86::COND_G: return X86::JG;
- case X86::COND_GE: return X86::JGE;
- case X86::COND_B: return X86::JB;
- case X86::COND_BE: return X86::JBE;
- case X86::COND_A: return X86::JA;
- case X86::COND_AE: return X86::JAE;
- case X86::COND_S: return X86::JS;
- case X86::COND_NS: return X86::JNS;
- case X86::COND_P: return X86::JP;
- case X86::COND_NP: return X86::JNP;
- case X86::COND_O: return X86::JO;
- case X86::COND_NO: return X86::JNO;
+ case X86::COND_E: return X86::JE_4;
+ case X86::COND_NE: return X86::JNE_4;
+ case X86::COND_L: return X86::JL_4;
+ case X86::COND_LE: return X86::JLE_4;
+ case X86::COND_G: return X86::JG_4;
+ case X86::COND_GE: return X86::JGE_4;
+ case X86::COND_B: return X86::JB_4;
+ case X86::COND_BE: return X86::JBE_4;
+ case X86::COND_A: return X86::JA_4;
+ case X86::COND_AE: return X86::JAE_4;
+ case X86::COND_S: return X86::JS_4;
+ case X86::COND_NS: return X86::JNS_4;
+ case X86::COND_P: return X86::JP_4;
+ case X86::COND_NP: return X86::JNP_4;
+ case X86::COND_O: return X86::JO_4;
+ case X86::COND_NO: return X86::JNO_4;
}
}
@@ -1695,7 +1694,7 @@ bool X86InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
return true;
// Handle unconditional branches.
- if (I->getOpcode() == X86::JMP) {
+ if (I->getOpcode() == X86::JMP_4) {
if (!AllowModify) {
TBB = I->getOperand(0).getMBB();
continue;
@@ -1779,7 +1778,7 @@ unsigned X86InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
while (I != MBB.begin()) {
--I;
- if (I->getOpcode() != X86::JMP &&
+ if (I->getOpcode() != X86::JMP_4 &&
GetCondFromBranchOpc(I->getOpcode()) == X86::COND_INVALID)
break;
// Remove the branch.
@@ -1805,7 +1804,7 @@ X86InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
if (Cond.empty()) {
// Unconditional branch?
assert(!FBB && "Unconditional branch with multiple successors!");
- BuildMI(&MBB, dl, get(X86::JMP)).addMBB(TBB);
+ BuildMI(&MBB, dl, get(X86::JMP_4)).addMBB(TBB);
return 1;
}
@@ -1815,16 +1814,16 @@ X86InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
switch (CC) {
case X86::COND_NP_OR_E:
// Synthesize NP_OR_E with two branches.
- BuildMI(&MBB, dl, get(X86::JNP)).addMBB(TBB);
+ BuildMI(&MBB, dl, get(X86::JNP_4)).addMBB(TBB);
++Count;
- BuildMI(&MBB, dl, get(X86::JE)).addMBB(TBB);
+ BuildMI(&MBB, dl, get(X86::JE_4)).addMBB(TBB);
++Count;
break;
case X86::COND_NE_OR_P:
// Synthesize NE_OR_P with two branches.
- BuildMI(&MBB, dl, get(X86::JNE)).addMBB(TBB);
+ BuildMI(&MBB, dl, get(X86::JNE_4)).addMBB(TBB);
++Count;
- BuildMI(&MBB, dl, get(X86::JP)).addMBB(TBB);
+ BuildMI(&MBB, dl, get(X86::JP_4)).addMBB(TBB);
++Count;
break;
default: {
@@ -1835,7 +1834,7 @@ X86InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
}
if (FBB) {
// Two-way Conditional branch. Insert the second branch.
- BuildMI(&MBB, dl, get(X86::JMP)).addMBB(FBB);
+ BuildMI(&MBB, dl, get(X86::JMP_4)).addMBB(FBB);
++Count;
}
return Count;
@@ -1851,8 +1850,7 @@ bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
- DebugLoc DL = DebugLoc::getUnknownLoc();
- if (MI != MBB.end()) DL = MI->getDebugLoc();
+ DebugLoc DL = MBB.findDebugLoc(MI);
// Determine if DstRC and SrcRC have a common superclass in common.
const TargetRegisterClass *CommonRC = DestRC;
@@ -2079,8 +2077,7 @@ void X86InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
const MachineFunction &MF = *MBB.getParent();
bool isAligned = (RI.getStackAlignment() >= 16) || RI.canRealignStack(MF);
unsigned Opc = getStoreRegOpcode(SrcReg, RC, isAligned, TM);
- DebugLoc DL = DebugLoc::getUnknownLoc();
- if (MI != MBB.end()) DL = MI->getDebugLoc();
+ DebugLoc DL = MBB.findDebugLoc(MI);
addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIdx)
.addReg(SrcReg, getKillRegState(isKill));
}
@@ -2173,8 +2170,7 @@ void X86InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
const MachineFunction &MF = *MBB.getParent();
bool isAligned = (RI.getStackAlignment() >= 16) || RI.canRealignStack(MF);
unsigned Opc = getLoadRegOpcode(DestReg, RC, isAligned, TM);
- DebugLoc DL = DebugLoc::getUnknownLoc();
- if (MI != MBB.end()) DL = MI->getDebugLoc();
+ DebugLoc DL = MBB.findDebugLoc(MI);
addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DestReg), FrameIdx);
}
@@ -3018,22 +3014,11 @@ isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
RC == &X86::RFP64RegClass || RC == &X86::RFP80RegClass);
}
-unsigned X86InstrInfo::sizeOfImm(const TargetInstrDesc *Desc) {
- switch (Desc->TSFlags & X86II::ImmMask) {
- case X86II::Imm8: return 1;
- case X86II::Imm16: return 2;
- case X86II::Imm32: return 4;
- case X86II::Imm64: return 8;
- default: llvm_unreachable("Immediate size not set!");
- return 0;
- }
-}
-/// isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended register?
-/// e.g. r8, xmm8, etc.
-bool X86InstrInfo::isX86_64ExtendedReg(const MachineOperand &MO) {
- if (!MO.isReg()) return false;
- switch (MO.getReg()) {
+/// isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended (r8 or higher)
+/// register? e.g. r8, xmm8, xmm13, etc.
+bool X86InstrInfo::isX86_64ExtendedReg(unsigned RegNo) {
+ switch (RegNo) {
default: break;
case X86::R8: case X86::R9: case X86::R10: case X86::R11:
case X86::R12: case X86::R13: case X86::R14: case X86::R15:
@@ -3387,24 +3372,24 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
switch (Opcode) {
default:
break;
- case TargetInstrInfo::INLINEASM: {
+ case TargetOpcode::INLINEASM: {
const MachineFunction *MF = MI.getParent()->getParent();
const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
FinalSize += TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
*MF->getTarget().getMCAsmInfo());
break;
}
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
+ case TargetOpcode::DBG_LABEL:
+ case TargetOpcode::EH_LABEL:
break;
- case TargetInstrInfo::IMPLICIT_DEF:
- case TargetInstrInfo::KILL:
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
case X86::FP_REG_KILL:
break;
case X86::MOVPC32r: {
// This emits the "call" portion of this pseudo instruction.
++FinalSize;
- FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
+ FinalSize += sizeConstant(X86II::getSizeOfImm(Desc->TSFlags));
break;
}
}
@@ -3422,7 +3407,7 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
} else if (MO.isSymbol()) {
FinalSize += sizeExternalSymbolAddress(false);
} else if (MO.isImm()) {
- FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
+ FinalSize += sizeConstant(X86II::getSizeOfImm(Desc->TSFlags));
} else {
llvm_unreachable("Unknown RawFrm operand!");
}
@@ -3435,7 +3420,7 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
if (CurOp != NumOps) {
const MachineOperand &MO1 = MI.getOperand(CurOp++);
- unsigned Size = X86InstrInfo::sizeOfImm(Desc);
+ unsigned Size = X86II::getSizeOfImm(Desc->TSFlags);
if (MO1.isImm())
FinalSize += sizeConstant(Size);
else {
@@ -3460,7 +3445,7 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
CurOp += 2;
if (CurOp != NumOps) {
++CurOp;
- FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
+ FinalSize += sizeConstant(X86II::getSizeOfImm(Desc->TSFlags));
}
break;
}
@@ -3470,7 +3455,7 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
CurOp += X86AddrNumOperands + 1;
if (CurOp != NumOps) {
++CurOp;
- FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
+ FinalSize += sizeConstant(X86II::getSizeOfImm(Desc->TSFlags));
}
break;
}
@@ -3481,7 +3466,7 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
CurOp += 2;
if (CurOp != NumOps) {
++CurOp;
- FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
+ FinalSize += sizeConstant(X86II::getSizeOfImm(Desc->TSFlags));
}
break;
@@ -3498,7 +3483,7 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
CurOp += AddrOperands + 1;
if (CurOp != NumOps) {
++CurOp;
- FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
+ FinalSize += sizeConstant(X86II::getSizeOfImm(Desc->TSFlags));
}
break;
}
@@ -3523,7 +3508,7 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
if (CurOp != NumOps) {
const MachineOperand &MO1 = MI.getOperand(CurOp++);
- unsigned Size = X86InstrInfo::sizeOfImm(Desc);
+ unsigned Size = X86II::getSizeOfImm(Desc->TSFlags);
if (MO1.isImm())
FinalSize += sizeConstant(Size);
else {
@@ -3553,7 +3538,7 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
if (CurOp != NumOps) {
const MachineOperand &MO = MI.getOperand(CurOp++);
- unsigned Size = X86InstrInfo::sizeOfImm(Desc);
+ unsigned Size = X86II::getSizeOfImm(Desc->TSFlags);
if (MO.isImm())
FinalSize += sizeConstant(Size);
else {
@@ -3571,6 +3556,14 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
}
}
break;
+
+ case X86II::MRM_C1:
+ case X86II::MRM_C8:
+ case X86II::MRM_C9:
+ case X86II::MRM_E8:
+ case X86II::MRM_F0:
+ FinalSize += 2;
+ break;
}
case X86II::MRMInitReg:
@@ -3619,8 +3612,7 @@ unsigned X86InstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
// Insert the set of GlobalBaseReg into the first MBB of the function
MachineBasicBlock &FirstMBB = MF->front();
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
- DebugLoc DL = DebugLoc::getUnknownLoc();
- if (MBBI != FirstMBB.end()) DL = MBBI->getDebugLoc();
+ DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
MachineRegisterInfo &RegInfo = MF->getRegInfo();
unsigned PC = RegInfo.createVirtualRegister(X86::GR32RegisterClass);
diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h
index 4f35d0d..5111719 100644
--- a/lib/Target/X86/X86InstrInfo.h
+++ b/lib/Target/X86/X86InstrInfo.h
@@ -18,7 +18,6 @@
#include "X86.h"
#include "X86RegisterInfo.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/Target/TargetRegisterInfo.h"
namespace llvm {
class X86RegisterInfo;
@@ -269,6 +268,18 @@ namespace X86II {
// MRMInitReg - This form is used for instructions whose source and
// destinations are the same register.
MRMInitReg = 32,
+
+ //// MRM_C1 - A mod/rm byte of exactly 0xC1.
+ MRM_C1 = 33,
+ MRM_C2 = 34,
+ MRM_C3 = 35,
+ MRM_C4 = 36,
+ MRM_C8 = 37,
+ MRM_C9 = 38,
+ MRM_E8 = 39,
+ MRM_F0 = 40,
+ MRM_F8 = 41,
+ MRM_F9 = 42,
FormMask = 63,
@@ -332,11 +343,13 @@ namespace X86II {
// This three-bit field describes the size of an immediate operand. Zero is
// unused so that we can tell if we forgot to set a value.
ImmShift = 13,
- ImmMask = 7 << ImmShift,
- Imm8 = 1 << ImmShift,
- Imm16 = 2 << ImmShift,
- Imm32 = 3 << ImmShift,
- Imm64 = 4 << ImmShift,
+ ImmMask = 7 << ImmShift,
+ Imm8 = 1 << ImmShift,
+ Imm8PCRel = 2 << ImmShift,
+ Imm16 = 3 << ImmShift,
+ Imm32 = 4 << ImmShift,
+ Imm32PCRel = 5 << ImmShift,
+ Imm64 = 6 << ImmShift,
//===------------------------------------------------------------------===//
// FP Instruction Classification... Zero is non-fp instruction.
@@ -389,6 +402,47 @@ namespace X86II {
OpcodeShift = 24,
OpcodeMask = 0xFF << OpcodeShift
};
+
+ // getBaseOpcodeFor - This function returns the "base" X86 opcode for the
+ // specified machine instruction.
+ //
+ static inline unsigned char getBaseOpcodeFor(unsigned TSFlags) {
+ return TSFlags >> X86II::OpcodeShift;
+ }
+
+ static inline bool hasImm(unsigned TSFlags) {
+ return (TSFlags & X86II::ImmMask) != 0;
+ }
+
+ /// getSizeOfImm - Decode the "size of immediate" field from the TSFlags field
+ /// of the specified instruction.
+ static inline unsigned getSizeOfImm(unsigned TSFlags) {
+ switch (TSFlags & X86II::ImmMask) {
+ default: assert(0 && "Unknown immediate size");
+ case X86II::Imm8:
+ case X86II::Imm8PCRel: return 1;
+ case X86II::Imm16: return 2;
+ case X86II::Imm32:
+ case X86II::Imm32PCRel: return 4;
+ case X86II::Imm64: return 8;
+ }
+ }
+
+ /// isImmPCRel - Return true if the immediate of the specified instruction's
+ /// TSFlags indicates that it is pc relative.
+ static inline unsigned isImmPCRel(unsigned TSFlags) {
+ switch (TSFlags & X86II::ImmMask) {
+ default: assert(0 && "Unknown immediate size");
+ case X86II::Imm8PCRel:
+ case X86II::Imm32PCRel:
+ return true;
+ case X86II::Imm8:
+ case X86II::Imm16:
+ case X86II::Imm32:
+ case X86II::Imm64:
+ return false;
+ }
+ }
}
const int X86AddrNumOperands = 5;
@@ -637,25 +691,21 @@ public:
/// instruction that defines the specified register class.
bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const;
- // getBaseOpcodeFor - This function returns the "base" X86 opcode for the
- // specified machine instruction.
- //
- unsigned char getBaseOpcodeFor(const TargetInstrDesc *TID) const {
- return TID->TSFlags >> X86II::OpcodeShift;
- }
- unsigned char getBaseOpcodeFor(unsigned Opcode) const {
- return getBaseOpcodeFor(&get(Opcode));
- }
-
static bool isX86_64NonExtLowByteReg(unsigned reg) {
return (reg == X86::SPL || reg == X86::BPL ||
reg == X86::SIL || reg == X86::DIL);
}
- static unsigned sizeOfImm(const TargetInstrDesc *Desc);
- static bool isX86_64ExtendedReg(const MachineOperand &MO);
+ static bool isX86_64ExtendedReg(const MachineOperand &MO) {
+ if (!MO.isReg()) return false;
+ return isX86_64ExtendedReg(MO.getReg());
+ }
static unsigned determineREX(const MachineInstr &MI);
+ /// isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended (r8 or
+ /// higher) register? e.g. r8, xmm8, xmm13, etc.
+ static bool isX86_64ExtendedReg(unsigned RegNo);
+
/// GetInstSize - Returns the size of the specified MachineInstr.
///
virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 396cb53..25cd297 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -182,10 +182,6 @@ def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
// X86 Operand Definitions.
//
-def i32imm_pcrel : Operand<i32> {
- let PrintMethod = "print_pcrel_imm";
-}
-
// A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
// the index operand of an address, to conform to x86 encoding restrictions.
def ptr_rc_nosp : PointerLikeRegClass<1>;
@@ -196,6 +192,14 @@ def X86MemAsmOperand : AsmOperandClass {
let Name = "Mem";
let SuperClass = ?;
}
+def X86AbsMemAsmOperand : AsmOperandClass {
+ let Name = "AbsMem";
+ let SuperClass = X86MemAsmOperand;
+}
+def X86NoSegMemAsmOperand : AsmOperandClass {
+ let Name = "NoSegMem";
+ let SuperClass = X86MemAsmOperand;
+}
class X86MemOperand<string printMethod> : Operand<iPTR> {
let PrintMethod = printMethod;
let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
@@ -207,11 +211,6 @@ def opaque48mem : X86MemOperand<"printopaquemem">;
def opaque80mem : X86MemOperand<"printopaquemem">;
def opaque512mem : X86MemOperand<"printopaquemem">;
-def offset8 : Operand<i64> { let PrintMethod = "print_pcrel_imm"; }
-def offset16 : Operand<i64> { let PrintMethod = "print_pcrel_imm"; }
-def offset32 : Operand<i64> { let PrintMethod = "print_pcrel_imm"; }
-def offset64 : Operand<i64> { let PrintMethod = "print_pcrel_imm"; }
-
def i8mem : X86MemOperand<"printi8mem">;
def i16mem : X86MemOperand<"printi16mem">;
def i32mem : X86MemOperand<"printi32mem">;
@@ -235,7 +234,22 @@ def i8mem_NOREX : Operand<i64> {
def lea32mem : Operand<i32> {
let PrintMethod = "printlea32mem";
let MIOperandInfo = (ops GR32, i8imm, GR32_NOSP, i32imm);
- let ParserMatchClass = X86MemAsmOperand;
+ let ParserMatchClass = X86NoSegMemAsmOperand;
+}
+
+let ParserMatchClass = X86AbsMemAsmOperand,
+ PrintMethod = "print_pcrel_imm" in {
+def i32imm_pcrel : Operand<i32>;
+
+def offset8 : Operand<i64>;
+def offset16 : Operand<i64>;
+def offset32 : Operand<i64>;
+def offset64 : Operand<i64>;
+
+// Branch targets have OtherVT type and print as pc-relative values.
+def brtarget : Operand<OtherVT>;
+def brtarget8 : Operand<OtherVT>;
+
}
def SSECC : Operand<i8> {
@@ -257,15 +271,6 @@ def i32i8imm : Operand<i32> {
let ParserMatchClass = ImmSExt8AsmOperand;
}
-// Branch targets have OtherVT type and print as pc-relative values.
-def brtarget : Operand<OtherVT> {
- let PrintMethod = "print_pcrel_imm";
-}
-
-def brtarget8 : Operand<OtherVT> {
- let PrintMethod = "print_pcrel_imm";
-}
-
//===----------------------------------------------------------------------===//
// X86 Complex Pattern Definitions.
//
@@ -591,7 +596,7 @@ let neverHasSideEffects = 1, isNotDuplicable = 1, Uses = [ESP] in
"", []>;
//===----------------------------------------------------------------------===//
-// Control Flow Instructions...
+// Control Flow Instructions.
//
// Return instructions.
@@ -609,16 +614,46 @@ let isTerminator = 1, isReturn = 1, isBarrier = 1,
"lret\t$amt", []>;
}
-// All branches are RawFrm, Void, Branch, and Terminators
-let isBranch = 1, isTerminator = 1 in
- class IBr<bits<8> opcode, dag ins, string asm, list<dag> pattern> :
- I<opcode, RawFrm, (outs), ins, asm, pattern>;
+// Unconditional branches.
+let isBarrier = 1, isBranch = 1, isTerminator = 1 in {
+ def JMP_4 : Ii32PCRel<0xE9, RawFrm, (outs), (ins brtarget:$dst),
+ "jmp\t$dst", [(br bb:$dst)]>;
+ def JMP_1 : Ii8PCRel<0xEB, RawFrm, (outs), (ins brtarget8:$dst),
+ "jmp\t$dst", []>;
+}
-let isBranch = 1, isBarrier = 1 in {
- def JMP : IBr<0xE9, (ins brtarget:$dst), "jmp\t$dst", [(br bb:$dst)]>;
- def JMP8 : IBr<0xEB, (ins brtarget8:$dst), "jmp\t$dst", []>;
+// Conditional Branches.
+let isBranch = 1, isTerminator = 1, Uses = [EFLAGS] in {
+ multiclass ICBr<bits<8> opc1, bits<8> opc4, string asm, PatFrag Cond> {
+ def _1 : Ii8PCRel <opc1, RawFrm, (outs), (ins brtarget8:$dst), asm, []>;
+ def _4 : Ii32PCRel<opc4, RawFrm, (outs), (ins brtarget:$dst), asm,
+ [(X86brcond bb:$dst, Cond, EFLAGS)]>, TB;
+ }
}
+defm JO : ICBr<0x70, 0x80, "jo\t$dst" , X86_COND_O>;
+defm JNO : ICBr<0x71, 0x81, "jno\t$dst" , X86_COND_NO>;
+defm JB : ICBr<0x72, 0x82, "jb\t$dst" , X86_COND_B>;
+defm JAE : ICBr<0x73, 0x83, "jae\t$dst", X86_COND_AE>;
+defm JE : ICBr<0x74, 0x84, "je\t$dst" , X86_COND_E>;
+defm JNE : ICBr<0x75, 0x85, "jne\t$dst", X86_COND_NE>;
+defm JBE : ICBr<0x76, 0x86, "jbe\t$dst", X86_COND_BE>;
+defm JA : ICBr<0x77, 0x87, "ja\t$dst" , X86_COND_A>;
+defm JS : ICBr<0x78, 0x88, "js\t$dst" , X86_COND_S>;
+defm JNS : ICBr<0x79, 0x89, "jns\t$dst", X86_COND_NS>;
+defm JP : ICBr<0x7A, 0x8A, "jp\t$dst" , X86_COND_P>;
+defm JNP : ICBr<0x7B, 0x8B, "jnp\t$dst", X86_COND_NP>;
+defm JL : ICBr<0x7C, 0x8C, "jl\t$dst" , X86_COND_L>;
+defm JGE : ICBr<0x7D, 0x8D, "jge\t$dst", X86_COND_GE>;
+defm JLE : ICBr<0x7E, 0x8E, "jle\t$dst", X86_COND_LE>;
+defm JG : ICBr<0x7F, 0x8F, "jg\t$dst" , X86_COND_G>;
+
+// FIXME: What about the CX/RCX versions of this instruction?
+let Uses = [ECX], isBranch = 1, isTerminator = 1 in
+ def JCXZ8 : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
+ "jcxz\t$dst", []>;
+
+
// Indirect branches
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
def JMP32r : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l}\t{*}$dst",
@@ -639,63 +674,6 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
"ljmp{l}\t{*}$dst", []>;
}
-// Conditional branches
-let Uses = [EFLAGS] in {
-// Short conditional jumps
-def JO8 : IBr<0x70, (ins brtarget8:$dst), "jo\t$dst", []>;
-def JNO8 : IBr<0x71, (ins brtarget8:$dst), "jno\t$dst", []>;
-def JB8 : IBr<0x72, (ins brtarget8:$dst), "jb\t$dst", []>;
-def JAE8 : IBr<0x73, (ins brtarget8:$dst), "jae\t$dst", []>;
-def JE8 : IBr<0x74, (ins brtarget8:$dst), "je\t$dst", []>;
-def JNE8 : IBr<0x75, (ins brtarget8:$dst), "jne\t$dst", []>;
-def JBE8 : IBr<0x76, (ins brtarget8:$dst), "jbe\t$dst", []>;
-def JA8 : IBr<0x77, (ins brtarget8:$dst), "ja\t$dst", []>;
-def JS8 : IBr<0x78, (ins brtarget8:$dst), "js\t$dst", []>;
-def JNS8 : IBr<0x79, (ins brtarget8:$dst), "jns\t$dst", []>;
-def JP8 : IBr<0x7A, (ins brtarget8:$dst), "jp\t$dst", []>;
-def JNP8 : IBr<0x7B, (ins brtarget8:$dst), "jnp\t$dst", []>;
-def JL8 : IBr<0x7C, (ins brtarget8:$dst), "jl\t$dst", []>;
-def JGE8 : IBr<0x7D, (ins brtarget8:$dst), "jge\t$dst", []>;
-def JLE8 : IBr<0x7E, (ins brtarget8:$dst), "jle\t$dst", []>;
-def JG8 : IBr<0x7F, (ins brtarget8:$dst), "jg\t$dst", []>;
-
-def JCXZ8 : IBr<0xE3, (ins brtarget8:$dst), "jcxz\t$dst", []>;
-
-def JE : IBr<0x84, (ins brtarget:$dst), "je\t$dst",
- [(X86brcond bb:$dst, X86_COND_E, EFLAGS)]>, TB;
-def JNE : IBr<0x85, (ins brtarget:$dst), "jne\t$dst",
- [(X86brcond bb:$dst, X86_COND_NE, EFLAGS)]>, TB;
-def JL : IBr<0x8C, (ins brtarget:$dst), "jl\t$dst",
- [(X86brcond bb:$dst, X86_COND_L, EFLAGS)]>, TB;
-def JLE : IBr<0x8E, (ins brtarget:$dst), "jle\t$dst",
- [(X86brcond bb:$dst, X86_COND_LE, EFLAGS)]>, TB;
-def JG : IBr<0x8F, (ins brtarget:$dst), "jg\t$dst",
- [(X86brcond bb:$dst, X86_COND_G, EFLAGS)]>, TB;
-def JGE : IBr<0x8D, (ins brtarget:$dst), "jge\t$dst",
- [(X86brcond bb:$dst, X86_COND_GE, EFLAGS)]>, TB;
-
-def JB : IBr<0x82, (ins brtarget:$dst), "jb\t$dst",
- [(X86brcond bb:$dst, X86_COND_B, EFLAGS)]>, TB;
-def JBE : IBr<0x86, (ins brtarget:$dst), "jbe\t$dst",
- [(X86brcond bb:$dst, X86_COND_BE, EFLAGS)]>, TB;
-def JA : IBr<0x87, (ins brtarget:$dst), "ja\t$dst",
- [(X86brcond bb:$dst, X86_COND_A, EFLAGS)]>, TB;
-def JAE : IBr<0x83, (ins brtarget:$dst), "jae\t$dst",
- [(X86brcond bb:$dst, X86_COND_AE, EFLAGS)]>, TB;
-
-def JS : IBr<0x88, (ins brtarget:$dst), "js\t$dst",
- [(X86brcond bb:$dst, X86_COND_S, EFLAGS)]>, TB;
-def JNS : IBr<0x89, (ins brtarget:$dst), "jns\t$dst",
- [(X86brcond bb:$dst, X86_COND_NS, EFLAGS)]>, TB;
-def JP : IBr<0x8A, (ins brtarget:$dst), "jp\t$dst",
- [(X86brcond bb:$dst, X86_COND_P, EFLAGS)]>, TB;
-def JNP : IBr<0x8B, (ins brtarget:$dst), "jnp\t$dst",
- [(X86brcond bb:$dst, X86_COND_NP, EFLAGS)]>, TB;
-def JO : IBr<0x80, (ins brtarget:$dst), "jo\t$dst",
- [(X86brcond bb:$dst, X86_COND_O, EFLAGS)]>, TB;
-def JNO : IBr<0x81, (ins brtarget:$dst), "jno\t$dst",
- [(X86brcond bb:$dst, X86_COND_NO, EFLAGS)]>, TB;
-} // Uses = [EFLAGS]
// Loop instructions
@@ -716,7 +694,7 @@ let isCall = 1 in
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
Uses = [ESP] in {
- def CALLpcrel32 : Ii32<0xE8, RawFrm,
+ def CALLpcrel32 : Ii32PCRel<0xE8, RawFrm,
(outs), (ins i32imm_pcrel:$dst,variable_ops),
"call\t$dst", []>;
def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst, variable_ops),
@@ -756,15 +734,18 @@ def TCRETURNri : I<0, Pseudo, (outs),
"#TC_RETURN $dst $offset",
[]>;
-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
- def TAILJMPd : IBr<0xE9, (ins i32imm_pcrel:$dst), "jmp\t$dst # TAILCALL",
+// FIXME: The should be pseudo instructions that are lowered when going to
+// mcinst.
+let isCall = 1, isBranch = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
+ def TAILJMPd : Ii32<0xE9, RawFrm, (outs),(ins i32imm_pcrel:$dst,variable_ops),
+ "jmp\t$dst # TAILCALL",
[]>;
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
- def TAILJMPr : I<0xFF, MRM4r, (outs), (ins GR32:$dst),
+ def TAILJMPr : I<0xFF, MRM4r, (outs), (ins GR32:$dst, variable_ops),
"jmp{l}\t{*}$dst # TAILCALL",
[]>;
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
- def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem:$dst),
+ def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem:$dst, variable_ops),
"jmp\t{*}$dst # TAILCALL", []>;
//===----------------------------------------------------------------------===//
@@ -877,7 +858,7 @@ def LEA32r : I<0x8D, MRMSrcMem,
"lea{l}\t{$src|$dst}, {$dst|$src}",
[(set GR32:$dst, lea32addr:$src)]>, Requires<[In32BitMode]>;
-let Defs = [ECX,EDI,ESI], Uses = [ECX,EDI,ESI] in {
+let Defs = [ECX,EDI,ESI], Uses = [ECX,EDI,ESI], isCodeGenOnly = 1 in {
def REP_MOVSB : I<0xA4, RawFrm, (outs), (ins), "{rep;movsb|rep movsb}",
[(X86rep_movs i8)]>, REP;
def REP_MOVSW : I<0xA5, RawFrm, (outs), (ins), "{rep;movsw|rep movsw}",
@@ -886,16 +867,31 @@ def REP_MOVSD : I<0xA5, RawFrm, (outs), (ins), "{rep;movsl|rep movsd}",
[(X86rep_movs i32)]>, REP;
}
-let Defs = [ECX,EDI], Uses = [AL,ECX,EDI] in
+// These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
+let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
+def MOVSB : I<0xA4, RawFrm, (outs), (ins), "{movsb}", []>;
+def MOVSW : I<0xA5, RawFrm, (outs), (ins), "{movsw}", []>, OpSize;
+def MOVSD : I<0xA5, RawFrm, (outs), (ins), "{movsl|movsd}", []>;
+}
+
+let Defs = [ECX,EDI], Uses = [AL,ECX,EDI], isCodeGenOnly = 1 in
def REP_STOSB : I<0xAA, RawFrm, (outs), (ins), "{rep;stosb|rep stosb}",
[(X86rep_stos i8)]>, REP;
-let Defs = [ECX,EDI], Uses = [AX,ECX,EDI] in
+let Defs = [ECX,EDI], Uses = [AX,ECX,EDI], isCodeGenOnly = 1 in
def REP_STOSW : I<0xAB, RawFrm, (outs), (ins), "{rep;stosw|rep stosw}",
[(X86rep_stos i16)]>, REP, OpSize;
-let Defs = [ECX,EDI], Uses = [EAX,ECX,EDI] in
+let Defs = [ECX,EDI], Uses = [EAX,ECX,EDI], isCodeGenOnly = 1 in
def REP_STOSD : I<0xAB, RawFrm, (outs), (ins), "{rep;stosl|rep stosd}",
[(X86rep_stos i32)]>, REP;
+// These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
+let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
+def STOSB : I<0xAA, RawFrm, (outs), (ins), "{stosb}", []>;
+let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
+def STOSW : I<0xAB, RawFrm, (outs), (ins), "{stosw}", []>, OpSize;
+let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
+def STOSD : I<0xAB, RawFrm, (outs), (ins), "{stosl|stosd}", []>;
+
def SCAS8 : I<0xAE, RawFrm, (outs), (ins), "scas{b}", []>;
def SCAS16 : I<0xAF, RawFrm, (outs), (ins), "scas{w}", []>, OpSize;
def SCAS32 : I<0xAF, RawFrm, (outs), (ins), "scas{l}", []>;
@@ -908,6 +904,9 @@ let Defs = [RAX, RDX] in
def RDTSC : I<0x31, RawFrm, (outs), (ins), "rdtsc", [(X86rdtsc)]>,
TB;
+let Defs = [RAX, RCX, RDX] in
+def RDTSCP : I<0x01, MRM_F9, (outs), (ins), "rdtscp", []>, TB;
+
let isBarrier = 1, hasCtrlDep = 1 in {
def TRAP : I<0x0B, RawFrm, (outs), (ins), "ud2", [(trap)]>, TB;
}
@@ -996,6 +995,7 @@ def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
"mov{l}\t{$src, $dst|$dst, $src}",
[(set GR32:$dst, imm:$src)]>;
}
+
def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
"mov{b}\t{$src, $dst|$dst, $src}",
[(store (i8 imm:$src), addr:$dst)]>;
@@ -2306,98 +2306,100 @@ let isTwoAddress = 0 in {
def RCL8r1 : I<0xD0, MRM2r, (outs GR8:$dst), (ins GR8:$src),
"rcl{b}\t{1, $dst|$dst, 1}", []>;
-def RCL8m1 : I<0xD0, MRM2m, (outs i8mem:$dst), (ins i8mem:$src),
- "rcl{b}\t{1, $dst|$dst, 1}", []>;
let Uses = [CL] in {
def RCL8rCL : I<0xD2, MRM2r, (outs GR8:$dst), (ins GR8:$src),
"rcl{b}\t{%cl, $dst|$dst, CL}", []>;
-def RCL8mCL : I<0xD2, MRM2m, (outs i8mem:$dst), (ins i8mem:$src),
- "rcl{b}\t{%cl, $dst|$dst, CL}", []>;
}
def RCL8ri : Ii8<0xC0, MRM2r, (outs GR8:$dst), (ins GR8:$src, i8imm:$cnt),
"rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCL8mi : Ii8<0xC0, MRM2m, (outs i8mem:$dst), (ins i8mem:$src, i8imm:$cnt),
- "rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>;
def RCL16r1 : I<0xD1, MRM2r, (outs GR16:$dst), (ins GR16:$src),
"rcl{w}\t{1, $dst|$dst, 1}", []>, OpSize;
-def RCL16m1 : I<0xD1, MRM2m, (outs i16mem:$dst), (ins i16mem:$src),
- "rcl{w}\t{1, $dst|$dst, 1}", []>, OpSize;
let Uses = [CL] in {
def RCL16rCL : I<0xD3, MRM2r, (outs GR16:$dst), (ins GR16:$src),
"rcl{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
-def RCL16mCL : I<0xD3, MRM2m, (outs i16mem:$dst), (ins i16mem:$src),
- "rcl{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
}
def RCL16ri : Ii8<0xC1, MRM2r, (outs GR16:$dst), (ins GR16:$src, i8imm:$cnt),
"rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
-def RCL16mi : Ii8<0xC1, MRM2m, (outs i16mem:$dst),
- (ins i16mem:$src, i8imm:$cnt),
- "rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
def RCL32r1 : I<0xD1, MRM2r, (outs GR32:$dst), (ins GR32:$src),
"rcl{l}\t{1, $dst|$dst, 1}", []>;
-def RCL32m1 : I<0xD1, MRM2m, (outs i32mem:$dst), (ins i32mem:$src),
- "rcl{l}\t{1, $dst|$dst, 1}", []>;
let Uses = [CL] in {
def RCL32rCL : I<0xD3, MRM2r, (outs GR32:$dst), (ins GR32:$src),
"rcl{l}\t{%cl, $dst|$dst, CL}", []>;
-def RCL32mCL : I<0xD3, MRM2m, (outs i32mem:$dst), (ins i32mem:$src),
- "rcl{l}\t{%cl, $dst|$dst, CL}", []>;
}
def RCL32ri : Ii8<0xC1, MRM2r, (outs GR32:$dst), (ins GR32:$src, i8imm:$cnt),
"rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCL32mi : Ii8<0xC1, MRM2m, (outs i32mem:$dst),
- (ins i32mem:$src, i8imm:$cnt),
- "rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>;
def RCR8r1 : I<0xD0, MRM3r, (outs GR8:$dst), (ins GR8:$src),
"rcr{b}\t{1, $dst|$dst, 1}", []>;
-def RCR8m1 : I<0xD0, MRM3m, (outs i8mem:$dst), (ins i8mem:$src),
- "rcr{b}\t{1, $dst|$dst, 1}", []>;
let Uses = [CL] in {
def RCR8rCL : I<0xD2, MRM3r, (outs GR8:$dst), (ins GR8:$src),
"rcr{b}\t{%cl, $dst|$dst, CL}", []>;
-def RCR8mCL : I<0xD2, MRM3m, (outs i8mem:$dst), (ins i8mem:$src),
- "rcr{b}\t{%cl, $dst|$dst, CL}", []>;
}
def RCR8ri : Ii8<0xC0, MRM3r, (outs GR8:$dst), (ins GR8:$src, i8imm:$cnt),
"rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCR8mi : Ii8<0xC0, MRM3m, (outs i8mem:$dst), (ins i8mem:$src, i8imm:$cnt),
- "rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>;
def RCR16r1 : I<0xD1, MRM3r, (outs GR16:$dst), (ins GR16:$src),
"rcr{w}\t{1, $dst|$dst, 1}", []>, OpSize;
-def RCR16m1 : I<0xD1, MRM3m, (outs i16mem:$dst), (ins i16mem:$src),
- "rcr{w}\t{1, $dst|$dst, 1}", []>, OpSize;
let Uses = [CL] in {
def RCR16rCL : I<0xD3, MRM3r, (outs GR16:$dst), (ins GR16:$src),
"rcr{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
-def RCR16mCL : I<0xD3, MRM3m, (outs i16mem:$dst), (ins i16mem:$src),
- "rcr{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
}
def RCR16ri : Ii8<0xC1, MRM3r, (outs GR16:$dst), (ins GR16:$src, i8imm:$cnt),
"rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
-def RCR16mi : Ii8<0xC1, MRM3m, (outs i16mem:$dst),
- (ins i16mem:$src, i8imm:$cnt),
- "rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
def RCR32r1 : I<0xD1, MRM3r, (outs GR32:$dst), (ins GR32:$src),
"rcr{l}\t{1, $dst|$dst, 1}", []>;
-def RCR32m1 : I<0xD1, MRM3m, (outs i32mem:$dst), (ins i32mem:$src),
- "rcr{l}\t{1, $dst|$dst, 1}", []>;
let Uses = [CL] in {
def RCR32rCL : I<0xD3, MRM3r, (outs GR32:$dst), (ins GR32:$src),
"rcr{l}\t{%cl, $dst|$dst, CL}", []>;
-def RCR32mCL : I<0xD3, MRM3m, (outs i32mem:$dst), (ins i32mem:$src),
- "rcr{l}\t{%cl, $dst|$dst, CL}", []>;
}
def RCR32ri : Ii8<0xC1, MRM3r, (outs GR32:$dst), (ins GR32:$src, i8imm:$cnt),
"rcr{l}\t{$cnt, $dst|$dst, $cnt}", []>;
-def RCR32mi : Ii8<0xC1, MRM3m, (outs i32mem:$dst),
- (ins i32mem:$src, i8imm:$cnt),
+
+let isTwoAddress = 0 in {
+def RCL8m1 : I<0xD0, MRM2m, (outs), (ins i8mem:$dst),
+ "rcl{b}\t{1, $dst|$dst, 1}", []>;
+def RCL8mi : Ii8<0xC0, MRM2m, (outs), (ins i8mem:$dst, i8imm:$cnt),
+ "rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>;
+def RCL16m1 : I<0xD1, MRM2m, (outs), (ins i16mem:$dst),
+ "rcl{w}\t{1, $dst|$dst, 1}", []>, OpSize;
+def RCL16mi : Ii8<0xC1, MRM2m, (outs), (ins i16mem:$dst, i8imm:$cnt),
+ "rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
+def RCL32m1 : I<0xD1, MRM2m, (outs), (ins i32mem:$dst),
+ "rcl{l}\t{1, $dst|$dst, 1}", []>;
+def RCL32mi : Ii8<0xC1, MRM2m, (outs), (ins i32mem:$dst, i8imm:$cnt),
+ "rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>;
+def RCR8m1 : I<0xD0, MRM3m, (outs), (ins i8mem:$dst),
+ "rcr{b}\t{1, $dst|$dst, 1}", []>;
+def RCR8mi : Ii8<0xC0, MRM3m, (outs), (ins i8mem:$dst, i8imm:$cnt),
+ "rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>;
+def RCR16m1 : I<0xD1, MRM3m, (outs), (ins i16mem:$dst),
+ "rcr{w}\t{1, $dst|$dst, 1}", []>, OpSize;
+def RCR16mi : Ii8<0xC1, MRM3m, (outs), (ins i16mem:$dst, i8imm:$cnt),
+ "rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize;
+def RCR32m1 : I<0xD1, MRM3m, (outs), (ins i32mem:$dst),
+ "rcr{l}\t{1, $dst|$dst, 1}", []>;
+def RCR32mi : Ii8<0xC1, MRM3m, (outs), (ins i32mem:$dst, i8imm:$cnt),
"rcr{l}\t{$cnt, $dst|$dst, $cnt}", []>;
+let Uses = [CL] in {
+def RCL8mCL : I<0xD2, MRM2m, (outs), (ins i8mem:$dst),
+ "rcl{b}\t{%cl, $dst|$dst, CL}", []>;
+def RCL16mCL : I<0xD3, MRM2m, (outs), (ins i16mem:$dst),
+ "rcl{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
+def RCL32mCL : I<0xD3, MRM2m, (outs), (ins i32mem:$dst),
+ "rcl{l}\t{%cl, $dst|$dst, CL}", []>;
+def RCR8mCL : I<0xD2, MRM3m, (outs), (ins i8mem:$dst),
+ "rcr{b}\t{%cl, $dst|$dst, CL}", []>;
+def RCR16mCL : I<0xD3, MRM3m, (outs), (ins i16mem:$dst),
+ "rcr{w}\t{%cl, $dst|$dst, CL}", []>, OpSize;
+def RCR32mCL : I<0xD3, MRM3m, (outs), (ins i32mem:$dst),
+ "rcr{l}\t{%cl, $dst|$dst, CL}", []>;
+}
+}
+
// FIXME: provide shorter instructions when imm8 == 1
let Uses = [CL] in {
def ROL8rCL : I<0xD2, MRM0r, (outs GR8 :$dst), (ins GR8 :$src),
@@ -3006,8 +3008,8 @@ let isTwoAddress = 0 in {
def SBB32mr : I<0x19, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
"sbb{l}\t{$src2, $dst|$dst, $src2}",
[(store (sube (load addr:$dst), GR32:$src2), addr:$dst)]>;
- def SBB8mi : Ii32<0x80, MRM3m, (outs), (ins i8mem:$dst, i8imm:$src2),
- "sbb{b}\t{$src2, $dst|$dst, $src2}",
+ def SBB8mi : Ii8<0x80, MRM3m, (outs), (ins i8mem:$dst, i8imm:$src2),
+ "sbb{b}\t{$src2, $dst|$dst, $src2}",
[(store (sube (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
def SBB16mi : Ii16<0x81, MRM3m, (outs), (ins i16mem:$dst, i16imm:$src2),
"sbb{w}\t{$src2, $dst|$dst, $src2}",
@@ -3234,17 +3236,18 @@ def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>; // AH = flags
let Uses = [EFLAGS] in {
// Use sbb to materialize carry bit.
-
let Defs = [EFLAGS], isCodeGenOnly = 1 in {
-def SETB_C8r : I<0x18, MRMInitReg, (outs GR8:$dst), (ins),
- "sbb{b}\t$dst, $dst",
+// FIXME: These are pseudo ops that should be replaced with Pat<> patterns.
+// However, Pat<> can't replicate the destination reg into the inputs of the
+// result.
+// FIXME: Change these to have encoding Pseudo when X86MCCodeEmitter replaces
+// X86CodeEmitter.
+def SETB_C8r : I<0x18, MRMInitReg, (outs GR8:$dst), (ins), "",
[(set GR8:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
-def SETB_C16r : I<0x19, MRMInitReg, (outs GR16:$dst), (ins),
- "sbb{w}\t$dst, $dst",
+def SETB_C16r : I<0x19, MRMInitReg, (outs GR16:$dst), (ins), "",
[(set GR16:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>,
OpSize;
-def SETB_C32r : I<0x19, MRMInitReg, (outs GR32:$dst), (ins),
- "sbb{l}\t$dst, $dst",
+def SETB_C32r : I<0x19, MRMInitReg, (outs GR32:$dst), (ins), "",
[(set GR32:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
} // isCodeGenOnly
@@ -3681,7 +3684,7 @@ def MOVZX32rm16: I<0xB7, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src),
"movz{wl|x}\t{$src, $dst|$dst, $src}",
[(set GR32:$dst, (zextloadi32i16 addr:$src))]>, TB;
-// These are the same as the regular regular MOVZX32rr8 and MOVZX32rm8
+// These are the same as the regular MOVZX32rr8 and MOVZX32rm8
// except that they use GR32_NOREX for the output operand register class
// instead of GR32. This allows them to operate on h registers on x86-64.
def MOVZX32_NOREXrr8 : I<0xB6, MRMSrcReg,
@@ -3716,10 +3719,10 @@ let neverHasSideEffects = 1 in {
// Alias instructions that map movr0 to xor.
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
+// FIXME: Set encoding to pseudo.
let Defs = [EFLAGS], isReMaterializable = 1, isAsCheapAsAMove = 1,
isCodeGenOnly = 1 in {
-def MOV8r0 : I<0x30, MRMInitReg, (outs GR8 :$dst), (ins),
- "xor{b}\t$dst, $dst",
+def MOV8r0 : I<0x30, MRMInitReg, (outs GR8 :$dst), (ins), "",
[(set GR8:$dst, 0)]>;
// We want to rewrite MOV16r0 in terms of MOV32r0, because it's a smaller
@@ -3731,8 +3734,8 @@ def MOV16r0 : I<0x31, MRMInitReg, (outs GR16:$dst), (ins),
"",
[(set GR16:$dst, 0)]>, OpSize;
-def MOV32r0 : I<0x31, MRMInitReg, (outs GR32:$dst), (ins),
- "xor{l}\t$dst, $dst",
+// FIXME: Set encoding to pseudo.
+def MOV32r0 : I<0x31, MRMInitReg, (outs GR32:$dst), (ins), "",
[(set GR32:$dst, 0)]>;
}
@@ -4077,7 +4080,7 @@ def LSL32rm : I<0x03, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
def LSL32rr : I<0x03, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
"lsl{l}\t{$src, $dst|$dst, $src}", []>, TB;
-def INVLPG : I<0x01, RawFrm, (outs), (ins), "invlpg", []>, TB;
+def INVLPG : I<0x01, MRM7m, (outs), (ins i8mem:$addr), "invlpg\t$addr", []>, TB;
def STRr : I<0x00, MRM1r, (outs GR16:$dst), (ins),
"str{w}\t{$dst}", []>, TB;
@@ -4155,6 +4158,26 @@ def LLDT16r : I<0x00, MRM2r, (outs), (ins GR16:$src),
def LLDT16m : I<0x00, MRM2m, (outs), (ins i16mem:$src),
"lldt{w}\t$src", []>, TB;
+// Lock instruction prefix
+def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
+
+// Repeat string operation instruction prefixes
+// These uses the DF flag in the EFLAGS register to inc or dec ECX
+let Defs = [ECX], Uses = [ECX,EFLAGS] in {
+// Repeat (used with INS, OUTS, MOVS, LODS and STOS)
+def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
+// Repeat while not equal (used with CMPS and SCAS)
+def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
+}
+
+// Segment override instruction prefixes
+def CS_PREFIX : I<0x2E, RawFrm, (outs), (ins), "cs", []>;
+def SS_PREFIX : I<0x36, RawFrm, (outs), (ins), "ss", []>;
+def DS_PREFIX : I<0x3E, RawFrm, (outs), (ins), "ds", []>;
+def ES_PREFIX : I<0x26, RawFrm, (outs), (ins), "es", []>;
+def FS_PREFIX : I<0x64, RawFrm, (outs), (ins), "fs", []>;
+def GS_PREFIX : I<0x65, RawFrm, (outs), (ins), "gs", []>;
+
// String manipulation instructions
def LODSB : I<0xAC, RawFrm, (outs), (ins), "lodsb", []>;
@@ -4219,17 +4242,17 @@ def WBINVD : I<0x09, RawFrm, (outs), (ins), "wbinvd", []>, TB;
// VMX instructions
// 66 0F 38 80
-def INVEPT : I<0x38, RawFrm, (outs), (ins), "invept", []>, OpSize, TB;
+def INVEPT : I<0x80, RawFrm, (outs), (ins), "invept", []>, OpSize, T8;
// 66 0F 38 81
-def INVVPID : I<0x38, RawFrm, (outs), (ins), "invvpid", []>, OpSize, TB;
+def INVVPID : I<0x81, RawFrm, (outs), (ins), "invvpid", []>, OpSize, T8;
// 0F 01 C1
-def VMCALL : I<0x01, RawFrm, (outs), (ins), "vmcall", []>, TB;
+def VMCALL : I<0x01, MRM_C1, (outs), (ins), "vmcall", []>, TB;
def VMCLEARm : I<0xC7, MRM6m, (outs), (ins i64mem:$vmcs),
"vmclear\t$vmcs", []>, OpSize, TB;
// 0F 01 C2
-def VMLAUNCH : I<0x01, RawFrm, (outs), (ins), "vmlaunch", []>, TB;
+def VMLAUNCH : I<0x01, MRM_C2, (outs), (ins), "vmlaunch", []>, TB;
// 0F 01 C3
-def VMRESUME : I<0x01, RawFrm, (outs), (ins), "vmresume", []>, TB;
+def VMRESUME : I<0x01, MRM_C3, (outs), (ins), "vmresume", []>, TB;
def VMPTRLDm : I<0xC7, MRM6m, (outs), (ins i64mem:$vmcs),
"vmptrld\t$vmcs", []>, TB;
def VMPTRSTm : I<0xC7, MRM7m, (outs i64mem:$vmcs), (ins),
@@ -4251,7 +4274,7 @@ def VMWRITE32rm : I<0x79, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
def VMWRITE32rr : I<0x79, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
"vmwrite{l}\t{$src, $dst|$dst, $src}", []>, TB;
// 0F 01 C4
-def VMXOFF : I<0x01, RawFrm, (outs), (ins), "vmxoff", []>, OpSize;
+def VMXOFF : I<0x01, MRM_C4, (outs), (ins), "vmxoff", []>, TB;
def VMXON : I<0xC7, MRM6m, (outs), (ins i64mem:$vmxon),
"vmxon\t{$vmxon}", []>, XD;
@@ -5181,6 +5204,12 @@ include "X86InstrFPStack.td"
include "X86Instr64bit.td"
//===----------------------------------------------------------------------===//
+// SIMD support (SSE, MMX and AVX)
+//===----------------------------------------------------------------------===//
+
+include "X86InstrFragmentsSIMD.td"
+
+//===----------------------------------------------------------------------===//
// XMM Floating point support (requires SSE / SSE2)
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/X86/X86InstrMMX.td b/lib/Target/X86/X86InstrMMX.td
index fc40c9a..89f020c 100644
--- a/lib/Target/X86/X86InstrMMX.td
+++ b/lib/Target/X86/X86InstrMMX.td
@@ -14,56 +14,6 @@
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
-// MMX Pattern Fragments
-//===----------------------------------------------------------------------===//
-
-def load_mmx : PatFrag<(ops node:$ptr), (v1i64 (load node:$ptr))>;
-
-def bc_v8i8 : PatFrag<(ops node:$in), (v8i8 (bitconvert node:$in))>;
-def bc_v4i16 : PatFrag<(ops node:$in), (v4i16 (bitconvert node:$in))>;
-def bc_v2i32 : PatFrag<(ops node:$in), (v2i32 (bitconvert node:$in))>;
-def bc_v1i64 : PatFrag<(ops node:$in), (v1i64 (bitconvert node:$in))>;
-
-//===----------------------------------------------------------------------===//
-// MMX Masks
-//===----------------------------------------------------------------------===//
-
-// MMX_SHUFFLE_get_shuf_imm xform function: convert vector_shuffle mask to
-// PSHUFW imm.
-def MMX_SHUFFLE_get_shuf_imm : SDNodeXForm<vector_shuffle, [{
- return getI8Imm(X86::getShuffleSHUFImmediate(N));
-}]>;
-
-// Patterns for: vector_shuffle v1, v2, <2, 6, 3, 7, ...>
-def mmx_unpckh : PatFrag<(ops node:$lhs, node:$rhs),
- (vector_shuffle node:$lhs, node:$rhs), [{
- return X86::isUNPCKHMask(cast<ShuffleVectorSDNode>(N));
-}]>;
-
-// Patterns for: vector_shuffle v1, v2, <0, 4, 2, 5, ...>
-def mmx_unpckl : PatFrag<(ops node:$lhs, node:$rhs),
- (vector_shuffle node:$lhs, node:$rhs), [{
- return X86::isUNPCKLMask(cast<ShuffleVectorSDNode>(N));
-}]>;
-
-// Patterns for: vector_shuffle v1, <undef>, <0, 0, 1, 1, ...>
-def mmx_unpckh_undef : PatFrag<(ops node:$lhs, node:$rhs),
- (vector_shuffle node:$lhs, node:$rhs), [{
- return X86::isUNPCKH_v_undef_Mask(cast<ShuffleVectorSDNode>(N));
-}]>;
-
-// Patterns for: vector_shuffle v1, <undef>, <2, 2, 3, 3, ...>
-def mmx_unpckl_undef : PatFrag<(ops node:$lhs, node:$rhs),
- (vector_shuffle node:$lhs, node:$rhs), [{
- return X86::isUNPCKL_v_undef_Mask(cast<ShuffleVectorSDNode>(N));
-}]>;
-
-def mmx_pshufw : PatFrag<(ops node:$lhs, node:$rhs),
- (vector_shuffle node:$lhs, node:$rhs), [{
- return X86::isPSHUFDMask(cast<ShuffleVectorSDNode>(N));
-}], MMX_SHUFFLE_get_shuf_imm>;
-
-//===----------------------------------------------------------------------===//
// MMX Multiclasses
//===----------------------------------------------------------------------===//
@@ -501,6 +451,20 @@ let Constraints = "$src1 = $dst" in {
(iPTR imm:$src3))))]>;
}
+// MMX to XMM for vector types
+def MMX_X86movq2dq : SDNode<"X86ISD::MOVQ2DQ", SDTypeProfile<1, 1,
+ [SDTCisVT<0, v2i64>, SDTCisVT<1, v1i64>]>>;
+
+def : Pat<(v2i64 (MMX_X86movq2dq VR64:$src)),
+ (v2i64 (MMX_MOVQ2DQrr VR64:$src))>;
+
+def : Pat<(v2i64 (MMX_X86movq2dq (load_mmx addr:$src))),
+ (v2i64 (MOVQI2PQIrm addr:$src))>;
+
+def : Pat<(v2i64 (MMX_X86movq2dq (v1i64 (bitconvert
+ (v2i32 (scalar_to_vector (loadi32 addr:$src))))))),
+ (v2i64 (MOVDI2PDIrm addr:$src))>;
+
// Mask creation
def MMX_PMOVMSKBrr : MMXI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR64:$src),
"pmovmskb\t{$src, $dst|$dst, $src}",
@@ -522,11 +486,10 @@ def MMX_MASKMOVQ64: MMXI64<0xF7, MRMSrcReg, (outs), (ins VR64:$src, VR64:$mask),
// Alias instructions that map zero vector to pxor.
let isReMaterializable = 1, isCodeGenOnly = 1 in {
- def MMX_V_SET0 : MMXI<0xEF, MRMInitReg, (outs VR64:$dst), (ins),
- "pxor\t$dst, $dst",
+ // FIXME: Change encoding to pseudo.
+ def MMX_V_SET0 : MMXI<0xEF, MRMInitReg, (outs VR64:$dst), (ins), "",
[(set VR64:$dst, (v2i32 immAllZerosV))]>;
- def MMX_V_SETALLONES : MMXI<0x76, MRMInitReg, (outs VR64:$dst), (ins),
- "pcmpeqd\t$dst, $dst",
+ def MMX_V_SETALLONES : MMXI<0x76, MRMInitReg, (outs VR64:$dst), (ins), "",
[(set VR64:$dst, (v2i32 immAllOnesV))]>;
}
diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td
index 94b9b55..9b2140f 100644
--- a/lib/Target/X86/X86InstrSSE.td
+++ b/lib/Target/X86/X86InstrSSE.td
@@ -505,9 +505,10 @@ def Int_COMISSrm: PSI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
// Alias instructions that map fld0 to pxor for sse.
let isReMaterializable = 1, isAsCheapAsAMove = 1, isCodeGenOnly = 1,
canFoldAsLoad = 1 in
-def FsFLD0SS : I<0xEF, MRMInitReg, (outs FR32:$dst), (ins),
- "pxor\t$dst, $dst", [(set FR32:$dst, fp32imm0)]>,
- Requires<[HasSSE1]>, TB, OpSize;
+ // FIXME: Set encoding to pseudo!
+def FsFLD0SS : I<0xEF, MRMInitReg, (outs FR32:$dst), (ins), "",
+ [(set FR32:$dst, fp32imm0)]>,
+ Requires<[HasSSE1]>, TB, OpSize;
// Alias instruction to do FR32 reg-to-reg copy using movaps. Upper bits are
// disregarded.
@@ -761,6 +762,9 @@ let Constraints = "$src1 = $dst" in {
} // Constraints = "$src1 = $dst"
+def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
+ (MOVHPSrm VR128:$src1, addr:$src2)>;
+
def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
"movlps\t{$src, $dst|$dst, $src}",
[(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
@@ -1025,10 +1029,10 @@ def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
// Alias instructions that map zero vector to pxor / xorp* for sse.
// We set canFoldAsLoad because this can be converted to a constant-pool
// load of an all-zeros value if folding it would be beneficial.
+// FIXME: Change encoding to pseudo!
let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
isCodeGenOnly = 1 in
-def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins),
- "xorps\t$dst, $dst",
+def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "",
[(set VR128:$dst, (v4i32 immAllZerosV))]>;
let Predicates = [HasSSE1] in {
@@ -1269,8 +1273,8 @@ def Int_COMISDrm: PDI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
// Alias instructions that map fld0 to pxor for sse.
let isReMaterializable = 1, isAsCheapAsAMove = 1, isCodeGenOnly = 1,
canFoldAsLoad = 1 in
-def FsFLD0SD : I<0xEF, MRMInitReg, (outs FR64:$dst), (ins),
- "pxor\t$dst, $dst", [(set FR64:$dst, fpimm0)]>,
+def FsFLD0SD : I<0xEF, MRMInitReg, (outs FR64:$dst), (ins), "",
+ [(set FR64:$dst, fpimm0)]>,
Requires<[HasSSE2]>, TB, OpSize;
// Alias instruction to do FR64 reg-to-reg copy using movapd. Upper bits are
@@ -2311,9 +2315,9 @@ def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
TB, Requires<[HasSSE2]>;
// Load, store, and memory fence
-def LFENCE : I<0xAE, MRM5r, (outs), (ins),
+def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
"lfence", [(int_x86_sse2_lfence)]>, TB, Requires<[HasSSE2]>;
-def MFENCE : I<0xAE, MRM6r, (outs), (ins),
+def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
"mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
//TODO: custom lower this so as to never even generate the noop
@@ -2329,8 +2333,8 @@ def : Pat<(membarrier (i8 imm:$ll), (i8 imm:$ls), (i8 imm:$sl), (i8 imm:$ss),
// load of an all-ones value if folding it would be beneficial.
let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
isCodeGenOnly = 1 in
- def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins),
- "pcmpeqd\t$dst, $dst",
+ // FIXME: Change encoding to pseudo.
+ def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
[(set VR128:$dst, (v4i32 immAllOnesV))]>;
// FR64 to 128-bit vector conversion.
@@ -2612,9 +2616,9 @@ let Constraints = "$src1 = $dst" in {
}
// Thread synchronization
-def MONITOR : I<0x01, MRM1r, (outs), (ins), "monitor",
+def MONITOR : I<0x01, MRM_C8, (outs), (ins), "monitor",
[(int_x86_sse3_monitor EAX, ECX, EDX)]>,TB, Requires<[HasSSE3]>;
-def MWAIT : I<0x01, MRM1r, (outs), (ins), "mwait",
+def MWAIT : I<0x01, MRM_C9, (outs), (ins), "mwait",
[(int_x86_sse3_mwait ECX, EAX)]>, TB, Requires<[HasSSE3]>;
// vector_shuffle v1, <undef> <1, 1, 3, 3>
@@ -3746,7 +3750,8 @@ def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, i128mem:$src2),
def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
"movntdqa\t{$src, $dst|$dst, $src}",
- [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>;
+ [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
+ OpSize;
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/X86/X86JITInfo.cpp b/lib/Target/X86/X86JITInfo.cpp
index f363903..d297d24 100644
--- a/lib/Target/X86/X86JITInfo.cpp
+++ b/lib/Target/X86/X86JITInfo.cpp
@@ -297,6 +297,7 @@ extern "C" {
push edx
push ecx
and esp, -16
+ sub esp, 16
mov eax, dword ptr [ebp+4]
mov dword ptr [esp+4], eax
mov dword ptr [esp], ebp
diff --git a/lib/Target/X86/X86MCAsmInfo.cpp b/lib/Target/X86/X86MCAsmInfo.cpp
index 1738d49..91c0fbb 100644
--- a/lib/Target/X86/X86MCAsmInfo.cpp
+++ b/lib/Target/X86/X86MCAsmInfo.cpp
@@ -55,9 +55,6 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &Triple) {
if (!is64Bit)
Data64bitsDirective = 0; // we can't emit a 64-bit unit
- // Leopard and above support aligned common symbols.
- COMMDirectiveTakesAlignment = Triple.getDarwinMajorNumber() >= 9;
-
CommentString = "##";
PCSymbol = ".";
@@ -75,7 +72,6 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &Triple) {
PrivateGlobalPrefix = ".L";
WeakRefDirective = "\t.weak\t";
- SetDirective = "\t.set\t";
PCSymbol = ".";
// Set up DWARF directives
@@ -98,27 +94,4 @@ MCSection *X86ELFMCAsmInfo::getNonexecutableStackSection(MCContext &Ctx) const {
X86MCAsmInfoCOFF::X86MCAsmInfoCOFF(const Triple &Triple) {
AsmTransCBE = x86_asm_table;
AssemblerDialect = AsmWriterFlavor;
-}
-
-
-X86WinMCAsmInfo::X86WinMCAsmInfo(const Triple &Triple) {
- AsmTransCBE = x86_asm_table;
- AssemblerDialect = AsmWriterFlavor;
-
- GlobalPrefix = "_";
- CommentString = ";";
-
- PrivateGlobalPrefix = "$";
- AlignDirective = "\tALIGN\t";
- ZeroDirective = "\tdb\t";
- AsciiDirective = "\tdb\t";
- AscizDirective = 0;
- Data8bitsDirective = "\tdb\t";
- Data16bitsDirective = "\tdw\t";
- Data32bitsDirective = "\tdd\t";
- Data64bitsDirective = "\tdq\t";
- HasDotTypeDotSizeDirective = false;
- HasSingleParameterDotFile = false;
-
- AlignmentIsInBytes = true;
-}
+} \ No newline at end of file
diff --git a/lib/Target/X86/X86MCAsmInfo.h b/lib/Target/X86/X86MCAsmInfo.h
index ca227b7..69716bf 100644
--- a/lib/Target/X86/X86MCAsmInfo.h
+++ b/lib/Target/X86/X86MCAsmInfo.h
@@ -33,11 +33,6 @@ namespace llvm {
struct X86MCAsmInfoCOFF : public MCAsmInfoCOFF {
explicit X86MCAsmInfoCOFF(const Triple &Triple);
};
-
- struct X86WinMCAsmInfo : public MCAsmInfo {
- explicit X86WinMCAsmInfo(const Triple &Triple);
- };
-
} // namespace llvm
#endif
diff --git a/lib/Target/X86/X86MCCodeEmitter.cpp b/lib/Target/X86/X86MCCodeEmitter.cpp
new file mode 100644
index 0000000..3f18696
--- /dev/null
+++ b/lib/Target/X86/X86MCCodeEmitter.cpp
@@ -0,0 +1,645 @@
+//===-- X86/X86MCCodeEmitter.cpp - Convert X86 code to machine code -------===//
+//
+// 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 X86MCCodeEmitter class.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "x86-emitter"
+#include "X86.h"
+#include "X86InstrInfo.h"
+#include "X86FixupKinds.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+namespace {
+class X86MCCodeEmitter : public MCCodeEmitter {
+ X86MCCodeEmitter(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
+ void operator=(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
+ const TargetMachine &TM;
+ const TargetInstrInfo &TII;
+ MCContext &Ctx;
+ bool Is64BitMode;
+public:
+ X86MCCodeEmitter(TargetMachine &tm, MCContext &ctx, bool is64Bit)
+ : TM(tm), TII(*TM.getInstrInfo()), Ctx(ctx) {
+ Is64BitMode = is64Bit;
+ }
+
+ ~X86MCCodeEmitter() {}
+
+ unsigned getNumFixupKinds() const {
+ return 3;
+ }
+
+ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
+ const static MCFixupKindInfo Infos[] = {
+ { "reloc_pcrel_4byte", 0, 4 * 8 },
+ { "reloc_pcrel_1byte", 0, 1 * 8 },
+ { "reloc_riprel_4byte", 0, 4 * 8 }
+ };
+
+ if (Kind < FirstTargetFixupKind)
+ return MCCodeEmitter::getFixupKindInfo(Kind);
+
+ assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
+ "Invalid kind!");
+ return Infos[Kind - FirstTargetFixupKind];
+ }
+
+ static unsigned GetX86RegNum(const MCOperand &MO) {
+ return X86RegisterInfo::getX86RegNum(MO.getReg());
+ }
+
+ void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const {
+ OS << (char)C;
+ ++CurByte;
+ }
+
+ void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte,
+ raw_ostream &OS) const {
+ // Output the constant in little endian byte order.
+ for (unsigned i = 0; i != Size; ++i) {
+ EmitByte(Val & 255, CurByte, OS);
+ Val >>= 8;
+ }
+ }
+
+ void EmitImmediate(const MCOperand &Disp,
+ unsigned ImmSize, MCFixupKind FixupKind,
+ unsigned &CurByte, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ int ImmOffset = 0) const;
+
+ inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode,
+ unsigned RM) {
+ assert(Mod < 4 && RegOpcode < 8 && RM < 8 && "ModRM Fields out of range!");
+ return RM | (RegOpcode << 3) | (Mod << 6);
+ }
+
+ void EmitRegModRMByte(const MCOperand &ModRMReg, unsigned RegOpcodeFld,
+ unsigned &CurByte, raw_ostream &OS) const {
+ EmitByte(ModRMByte(3, RegOpcodeFld, GetX86RegNum(ModRMReg)), CurByte, OS);
+ }
+
+ void EmitSIBByte(unsigned SS, unsigned Index, unsigned Base,
+ unsigned &CurByte, raw_ostream &OS) const {
+ // SIB byte is in the same format as the ModRMByte.
+ EmitByte(ModRMByte(SS, Index, Base), CurByte, OS);
+ }
+
+
+ void EmitMemModRMByte(const MCInst &MI, unsigned Op,
+ unsigned RegOpcodeField,
+ unsigned TSFlags, unsigned &CurByte, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
+ void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
+};
+
+} // end anonymous namespace
+
+
+MCCodeEmitter *llvm::createX86_32MCCodeEmitter(const Target &,
+ TargetMachine &TM,
+ MCContext &Ctx) {
+ return new X86MCCodeEmitter(TM, Ctx, false);
+}
+
+MCCodeEmitter *llvm::createX86_64MCCodeEmitter(const Target &,
+ TargetMachine &TM,
+ MCContext &Ctx) {
+ return new X86MCCodeEmitter(TM, Ctx, true);
+}
+
+
+/// isDisp8 - Return true if this signed displacement fits in a 8-bit
+/// sign-extended field.
+static bool isDisp8(int Value) {
+ return Value == (signed char)Value;
+}
+
+/// getImmFixupKind - Return the appropriate fixup kind to use for an immediate
+/// in an instruction with the specified TSFlags.
+static MCFixupKind getImmFixupKind(unsigned TSFlags) {
+ unsigned Size = X86II::getSizeOfImm(TSFlags);
+ bool isPCRel = X86II::isImmPCRel(TSFlags);
+
+ switch (Size) {
+ default: assert(0 && "Unknown immediate size");
+ case 1: return isPCRel ? MCFixupKind(X86::reloc_pcrel_1byte) : FK_Data_1;
+ case 4: return isPCRel ? MCFixupKind(X86::reloc_pcrel_4byte) : FK_Data_4;
+ case 2: assert(!isPCRel); return FK_Data_2;
+ case 8: assert(!isPCRel); return FK_Data_8;
+ }
+}
+
+
+void X86MCCodeEmitter::
+EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind,
+ unsigned &CurByte, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const {
+ // If this is a simple integer displacement that doesn't require a relocation,
+ // emit it now.
+ if (DispOp.isImm()) {
+ // FIXME: is this right for pc-rel encoding?? Probably need to emit this as
+ // a fixup if so.
+ EmitConstant(DispOp.getImm()+ImmOffset, Size, CurByte, OS);
+ return;
+ }
+
+ // If we have an immoffset, add it to the expression.
+ const MCExpr *Expr = DispOp.getExpr();
+
+ // If the fixup is pc-relative, we need to bias the value to be relative to
+ // the start of the field, not the end of the field.
+ if (FixupKind == MCFixupKind(X86::reloc_pcrel_4byte) ||
+ FixupKind == MCFixupKind(X86::reloc_riprel_4byte))
+ ImmOffset -= 4;
+ if (FixupKind == MCFixupKind(X86::reloc_pcrel_1byte))
+ ImmOffset -= 1;
+
+ if (ImmOffset)
+ Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(ImmOffset, Ctx),
+ Ctx);
+
+ // Emit a symbolic constant as a fixup and 4 zeros.
+ Fixups.push_back(MCFixup::Create(CurByte, Expr, FixupKind));
+ EmitConstant(0, Size, CurByte, OS);
+}
+
+
+void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
+ unsigned RegOpcodeField,
+ unsigned TSFlags, unsigned &CurByte,
+ raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups) const{
+ const MCOperand &Disp = MI.getOperand(Op+3);
+ const MCOperand &Base = MI.getOperand(Op);
+ const MCOperand &Scale = MI.getOperand(Op+1);
+ const MCOperand &IndexReg = MI.getOperand(Op+2);
+ unsigned BaseReg = Base.getReg();
+
+ // Handle %rip relative addressing.
+ if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode
+ assert(IndexReg.getReg() == 0 && Is64BitMode &&
+ "Invalid rip-relative address");
+ EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
+
+ // rip-relative addressing is actually relative to the *next* instruction.
+ // Since an immediate can follow the mod/rm byte for an instruction, this
+ // means that we need to bias the immediate field of the instruction with
+ // the size of the immediate field. If we have this case, add it into the
+ // expression to emit.
+ int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0;
+
+ EmitImmediate(Disp, 4, MCFixupKind(X86::reloc_riprel_4byte),
+ CurByte, OS, Fixups, -ImmSize);
+ return;
+ }
+
+ unsigned BaseRegNo = BaseReg ? GetX86RegNum(Base) : -1U;
+
+ // Determine whether a SIB byte is needed.
+ // If no BaseReg, issue a RIP relative instruction only if the MCE can
+ // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
+ // 2-7) and absolute references.
+
+ if (// The SIB byte must be used if there is an index register.
+ IndexReg.getReg() == 0 &&
+ // The SIB byte must be used if the base is ESP/RSP/R12, all of which
+ // encode to an R/M value of 4, which indicates that a SIB byte is
+ // present.
+ BaseRegNo != N86::ESP &&
+ // If there is no base register and we're in 64-bit mode, we need a SIB
+ // byte to emit an addr that is just 'disp32' (the non-RIP relative form).
+ (!Is64BitMode || BaseReg != 0)) {
+
+ if (BaseReg == 0) { // [disp32] in X86-32 mode
+ EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
+ EmitImmediate(Disp, 4, FK_Data_4, CurByte, OS, Fixups);
+ return;
+ }
+
+ // If the base is not EBP/ESP and there is no displacement, use simple
+ // indirect register encoding, this handles addresses like [EAX]. The
+ // encoding for [EBP] with no displacement means [disp32] so we handle it
+ // by emitting a displacement of 0 below.
+ if (Disp.isImm() && Disp.getImm() == 0 && BaseRegNo != N86::EBP) {
+ EmitByte(ModRMByte(0, RegOpcodeField, BaseRegNo), CurByte, OS);
+ return;
+ }
+
+ // Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
+ if (Disp.isImm() && isDisp8(Disp.getImm())) {
+ EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS);
+ EmitImmediate(Disp, 1, FK_Data_1, CurByte, OS, Fixups);
+ return;
+ }
+
+ // Otherwise, emit the most general non-SIB encoding: [REG+disp32]
+ EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS);
+ EmitImmediate(Disp, 4, FK_Data_4, CurByte, OS, Fixups);
+ return;
+ }
+
+ // We need a SIB byte, so start by outputting the ModR/M byte first
+ assert(IndexReg.getReg() != X86::ESP &&
+ IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!");
+
+ bool ForceDisp32 = false;
+ bool ForceDisp8 = false;
+ if (BaseReg == 0) {
+ // If there is no base register, we emit the special case SIB byte with
+ // MOD=0, BASE=5, to JUST get the index, scale, and displacement.
+ EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS);
+ ForceDisp32 = true;
+ } else if (!Disp.isImm()) {
+ // Emit the normal disp32 encoding.
+ EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS);
+ ForceDisp32 = true;
+ } else if (Disp.getImm() == 0 && BaseReg != X86::EBP) {
+ // Emit no displacement ModR/M byte
+ EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS);
+ } else if (isDisp8(Disp.getImm())) {
+ // Emit the disp8 encoding.
+ EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS);
+ ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
+ } else {
+ // Emit the normal disp32 encoding.
+ EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS);
+ }
+
+ // Calculate what the SS field value should be...
+ static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 };
+ unsigned SS = SSTable[Scale.getImm()];
+
+ if (BaseReg == 0) {
+ // Handle the SIB byte for the case where there is no base, see Intel
+ // Manual 2A, table 2-7. The displacement has already been output.
+ unsigned IndexRegNo;
+ if (IndexReg.getReg())
+ IndexRegNo = GetX86RegNum(IndexReg);
+ else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
+ IndexRegNo = 4;
+ EmitSIBByte(SS, IndexRegNo, 5, CurByte, OS);
+ } else {
+ unsigned IndexRegNo;
+ if (IndexReg.getReg())
+ IndexRegNo = GetX86RegNum(IndexReg);
+ else
+ IndexRegNo = 4; // For example [ESP+1*<noreg>+4]
+ EmitSIBByte(SS, IndexRegNo, GetX86RegNum(Base), CurByte, OS);
+ }
+
+ // Do we need to output a displacement?
+ if (ForceDisp8)
+ EmitImmediate(Disp, 1, FK_Data_1, CurByte, OS, Fixups);
+ else if (ForceDisp32 || Disp.getImm() != 0)
+ EmitImmediate(Disp, 4, FK_Data_4, CurByte, OS, Fixups);
+}
+
+/// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64
+/// REX prefix which specifies 1) 64-bit instructions, 2) non-default operand
+/// size, and 3) use of X86-64 extended registers.
+static unsigned DetermineREXPrefix(const MCInst &MI, unsigned TSFlags,
+ const TargetInstrDesc &Desc) {
+ // Pseudo instructions never have a rex byte.
+ if ((TSFlags & X86II::FormMask) == X86II::Pseudo)
+ return 0;
+
+ unsigned REX = 0;
+ if (TSFlags & X86II::REX_W)
+ REX |= 1 << 3;
+
+ if (MI.getNumOperands() == 0) return REX;
+
+ unsigned NumOps = MI.getNumOperands();
+ // FIXME: MCInst should explicitize the two-addrness.
+ bool isTwoAddr = NumOps > 1 &&
+ Desc.getOperandConstraint(1, TOI::TIED_TO) != -1;
+
+ // If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix.
+ unsigned i = isTwoAddr ? 1 : 0;
+ for (; i != NumOps; ++i) {
+ const MCOperand &MO = MI.getOperand(i);
+ if (!MO.isReg()) continue;
+ unsigned Reg = MO.getReg();
+ if (!X86InstrInfo::isX86_64NonExtLowByteReg(Reg)) continue;
+ // FIXME: The caller of DetermineREXPrefix slaps this prefix onto anything
+ // that returns non-zero.
+ REX |= 0x40;
+ break;
+ }
+
+ switch (TSFlags & X86II::FormMask) {
+ case X86II::MRMInitReg: assert(0 && "FIXME: Remove this!");
+ case X86II::MRMSrcReg:
+ if (MI.getOperand(0).isReg() &&
+ X86InstrInfo::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
+ REX |= 1 << 2;
+ i = isTwoAddr ? 2 : 1;
+ for (; i != NumOps; ++i) {
+ const MCOperand &MO = MI.getOperand(i);
+ if (MO.isReg() && X86InstrInfo::isX86_64ExtendedReg(MO.getReg()))
+ REX |= 1 << 0;
+ }
+ break;
+ case X86II::MRMSrcMem: {
+ if (MI.getOperand(0).isReg() &&
+ X86InstrInfo::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
+ REX |= 1 << 2;
+ unsigned Bit = 0;
+ i = isTwoAddr ? 2 : 1;
+ for (; i != NumOps; ++i) {
+ const MCOperand &MO = MI.getOperand(i);
+ if (MO.isReg()) {
+ if (X86InstrInfo::isX86_64ExtendedReg(MO.getReg()))
+ REX |= 1 << Bit;
+ Bit++;
+ }
+ }
+ break;
+ }
+ case X86II::MRM0m: case X86II::MRM1m:
+ case X86II::MRM2m: case X86II::MRM3m:
+ case X86II::MRM4m: case X86II::MRM5m:
+ case X86II::MRM6m: case X86II::MRM7m:
+ case X86II::MRMDestMem: {
+ unsigned e = (isTwoAddr ? X86AddrNumOperands+1 : X86AddrNumOperands);
+ i = isTwoAddr ? 1 : 0;
+ if (NumOps > e && MI.getOperand(e).isReg() &&
+ X86InstrInfo::isX86_64ExtendedReg(MI.getOperand(e).getReg()))
+ REX |= 1 << 2;
+ unsigned Bit = 0;
+ for (; i != e; ++i) {
+ const MCOperand &MO = MI.getOperand(i);
+ if (MO.isReg()) {
+ if (X86InstrInfo::isX86_64ExtendedReg(MO.getReg()))
+ REX |= 1 << Bit;
+ Bit++;
+ }
+ }
+ break;
+ }
+ default:
+ if (MI.getOperand(0).isReg() &&
+ X86InstrInfo::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
+ REX |= 1 << 0;
+ i = isTwoAddr ? 2 : 1;
+ for (unsigned e = NumOps; i != e; ++i) {
+ const MCOperand &MO = MI.getOperand(i);
+ if (MO.isReg() && X86InstrInfo::isX86_64ExtendedReg(MO.getReg()))
+ REX |= 1 << 2;
+ }
+ break;
+ }
+ return REX;
+}
+
+void X86MCCodeEmitter::
+EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ unsigned Opcode = MI.getOpcode();
+ const TargetInstrDesc &Desc = TII.get(Opcode);
+ unsigned TSFlags = Desc.TSFlags;
+
+ // Keep track of the current byte being emitted.
+ unsigned CurByte = 0;
+
+ // FIXME: We should emit the prefixes in exactly the same order as GAS does,
+ // in order to provide diffability.
+
+ // Emit the lock opcode prefix as needed.
+ if (TSFlags & X86II::LOCK)
+ EmitByte(0xF0, CurByte, OS);
+
+ // Emit segment override opcode prefix as needed.
+ switch (TSFlags & X86II::SegOvrMask) {
+ default: assert(0 && "Invalid segment!");
+ case 0: break; // No segment override!
+ case X86II::FS:
+ EmitByte(0x64, CurByte, OS);
+ break;
+ case X86II::GS:
+ EmitByte(0x65, CurByte, OS);
+ break;
+ }
+
+ // Emit the repeat opcode prefix as needed.
+ if ((TSFlags & X86II::Op0Mask) == X86II::REP)
+ EmitByte(0xF3, CurByte, OS);
+
+ // Emit the operand size opcode prefix as needed.
+ if (TSFlags & X86II::OpSize)
+ EmitByte(0x66, CurByte, OS);
+
+ // Emit the address size opcode prefix as needed.
+ if (TSFlags & X86II::AdSize)
+ EmitByte(0x67, CurByte, OS);
+
+ bool Need0FPrefix = false;
+ switch (TSFlags & X86II::Op0Mask) {
+ default: assert(0 && "Invalid prefix!");
+ case 0: break; // No prefix!
+ case X86II::REP: break; // already handled.
+ case X86II::TB: // Two-byte opcode prefix
+ case X86II::T8: // 0F 38
+ case X86II::TA: // 0F 3A
+ Need0FPrefix = true;
+ break;
+ case X86II::TF: // F2 0F 38
+ EmitByte(0xF2, CurByte, OS);
+ Need0FPrefix = true;
+ break;
+ case X86II::XS: // F3 0F
+ EmitByte(0xF3, CurByte, OS);
+ Need0FPrefix = true;
+ break;
+ case X86II::XD: // F2 0F
+ EmitByte(0xF2, CurByte, OS);
+ Need0FPrefix = true;
+ break;
+ case X86II::D8: EmitByte(0xD8, CurByte, OS); break;
+ case X86II::D9: EmitByte(0xD9, CurByte, OS); break;
+ case X86II::DA: EmitByte(0xDA, CurByte, OS); break;
+ case X86II::DB: EmitByte(0xDB, CurByte, OS); break;
+ case X86II::DC: EmitByte(0xDC, CurByte, OS); break;
+ case X86II::DD: EmitByte(0xDD, CurByte, OS); break;
+ case X86II::DE: EmitByte(0xDE, CurByte, OS); break;
+ case X86II::DF: EmitByte(0xDF, CurByte, OS); break;
+ }
+
+ // Handle REX prefix.
+ // FIXME: Can this come before F2 etc to simplify emission?
+ if (Is64BitMode) {
+ if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc))
+ EmitByte(0x40 | REX, CurByte, OS);
+ }
+
+ // 0x0F escape code must be emitted just before the opcode.
+ if (Need0FPrefix)
+ EmitByte(0x0F, CurByte, OS);
+
+ // FIXME: Pull this up into previous switch if REX can be moved earlier.
+ switch (TSFlags & X86II::Op0Mask) {
+ case X86II::TF: // F2 0F 38
+ case X86II::T8: // 0F 38
+ EmitByte(0x38, CurByte, OS);
+ break;
+ case X86II::TA: // 0F 3A
+ EmitByte(0x3A, CurByte, OS);
+ break;
+ }
+
+ // If this is a two-address instruction, skip one of the register operands.
+ unsigned NumOps = Desc.getNumOperands();
+ unsigned CurOp = 0;
+ if (NumOps > 1 && Desc.getOperandConstraint(1, TOI::TIED_TO) != -1)
+ ++CurOp;
+ else if (NumOps > 2 && Desc.getOperandConstraint(NumOps-1, TOI::TIED_TO)== 0)
+ // Skip the last source operand that is tied_to the dest reg. e.g. LXADD32
+ --NumOps;
+
+ unsigned char BaseOpcode = X86II::getBaseOpcodeFor(TSFlags);
+ switch (TSFlags & X86II::FormMask) {
+ case X86II::MRMInitReg:
+ assert(0 && "FIXME: Remove this form when the JIT moves to MCCodeEmitter!");
+ default: errs() << "FORM: " << (TSFlags & X86II::FormMask) << "\n";
+ assert(0 && "Unknown FormMask value in X86MCCodeEmitter!");
+ case X86II::Pseudo: return; // Pseudo instructions encode to nothing.
+ case X86II::RawFrm:
+ EmitByte(BaseOpcode, CurByte, OS);
+ break;
+
+ case X86II::AddRegFrm:
+ EmitByte(BaseOpcode + GetX86RegNum(MI.getOperand(CurOp++)), CurByte, OS);
+ break;
+
+ case X86II::MRMDestReg:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitRegModRMByte(MI.getOperand(CurOp),
+ GetX86RegNum(MI.getOperand(CurOp+1)), CurByte, OS);
+ CurOp += 2;
+ break;
+
+ case X86II::MRMDestMem:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitMemModRMByte(MI, CurOp,
+ GetX86RegNum(MI.getOperand(CurOp + X86AddrNumOperands)),
+ TSFlags, CurByte, OS, Fixups);
+ CurOp += X86AddrNumOperands + 1;
+ break;
+
+ case X86II::MRMSrcReg:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitRegModRMByte(MI.getOperand(CurOp+1), GetX86RegNum(MI.getOperand(CurOp)),
+ CurByte, OS);
+ CurOp += 2;
+ break;
+
+ case X86II::MRMSrcMem: {
+ EmitByte(BaseOpcode, CurByte, OS);
+
+ // FIXME: Maybe lea should have its own form? This is a horrible hack.
+ int AddrOperands;
+ if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r ||
+ Opcode == X86::LEA16r || Opcode == X86::LEA32r)
+ AddrOperands = X86AddrNumOperands - 1; // No segment register
+ else
+ AddrOperands = X86AddrNumOperands;
+
+ EmitMemModRMByte(MI, CurOp+1, GetX86RegNum(MI.getOperand(CurOp)),
+ TSFlags, CurByte, OS, Fixups);
+ CurOp += AddrOperands + 1;
+ break;
+ }
+
+ case X86II::MRM0r: case X86II::MRM1r:
+ case X86II::MRM2r: case X86II::MRM3r:
+ case X86II::MRM4r: case X86II::MRM5r:
+ case X86II::MRM6r: case X86II::MRM7r:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitRegModRMByte(MI.getOperand(CurOp++),
+ (TSFlags & X86II::FormMask)-X86II::MRM0r,
+ CurByte, OS);
+ break;
+ case X86II::MRM0m: case X86II::MRM1m:
+ case X86II::MRM2m: case X86II::MRM3m:
+ case X86II::MRM4m: case X86II::MRM5m:
+ case X86II::MRM6m: case X86II::MRM7m:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m,
+ TSFlags, CurByte, OS, Fixups);
+ CurOp += X86AddrNumOperands;
+ break;
+ case X86II::MRM_C1:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC1, CurByte, OS);
+ break;
+ case X86II::MRM_C2:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC2, CurByte, OS);
+ break;
+ case X86II::MRM_C3:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC3, CurByte, OS);
+ break;
+ case X86II::MRM_C4:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC4, CurByte, OS);
+ break;
+ case X86II::MRM_C8:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC8, CurByte, OS);
+ break;
+ case X86II::MRM_C9:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xC9, CurByte, OS);
+ break;
+ case X86II::MRM_E8:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xE8, CurByte, OS);
+ break;
+ case X86II::MRM_F0:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xF0, CurByte, OS);
+ break;
+ case X86II::MRM_F8:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xF8, CurByte, OS);
+ break;
+ case X86II::MRM_F9:
+ EmitByte(BaseOpcode, CurByte, OS);
+ EmitByte(0xF9, CurByte, OS);
+ break;
+ }
+
+ // If there is a remaining operand, it must be a trailing immediate. Emit it
+ // according to the right size for the instruction.
+ if (CurOp != NumOps)
+ EmitImmediate(MI.getOperand(CurOp++),
+ X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
+ CurByte, OS, Fixups);
+
+#ifndef NDEBUG
+ // FIXME: Verify.
+ if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) {
+ errs() << "Cannot encode all operands of: ";
+ MI.dump();
+ errs() << '\n';
+ abort();
+ }
+#endif
+}
diff --git a/lib/Target/X86/X86MCTargetExpr.cpp b/lib/Target/X86/X86MCTargetExpr.cpp
new file mode 100644
index 0000000..17b4fe8
--- /dev/null
+++ b/lib/Target/X86/X86MCTargetExpr.cpp
@@ -0,0 +1,48 @@
+//===- X86MCTargetExpr.cpp - X86 Target Specific MCExpr Implementation ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86MCTargetExpr.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+X86MCTargetExpr *X86MCTargetExpr::Create(const MCSymbol *Sym, VariantKind K,
+ MCContext &Ctx) {
+ return new (Ctx) X86MCTargetExpr(Sym, K);
+}
+
+void X86MCTargetExpr::PrintImpl(raw_ostream &OS) const {
+ OS << *Sym;
+
+ switch (Kind) {
+ case Invalid: OS << "@<invalid>"; break;
+ case GOT: OS << "@GOT"; break;
+ case GOTOFF: OS << "@GOTOFF"; break;
+ case GOTPCREL: OS << "@GOTPCREL"; break;
+ case GOTTPOFF: OS << "@GOTTPOFF"; break;
+ case INDNTPOFF: OS << "@INDNTPOFF"; break;
+ case NTPOFF: OS << "@NTPOFF"; break;
+ case PLT: OS << "@PLT"; break;
+ case TLSGD: OS << "@TLSGD"; break;
+ case TPOFF: OS << "@TPOFF"; break;
+ }
+}
+
+bool X86MCTargetExpr::EvaluateAsRelocatableImpl(MCValue &Res) const {
+ // FIXME: I don't know if this is right, it followed MCSymbolRefExpr.
+
+ // Evaluate recursively if this is a variable.
+ if (Sym->isVariable())
+ return Sym->getValue()->EvaluateAsRelocatable(Res);
+
+ Res = MCValue::get(Sym, 0, 0);
+ return true;
+}
diff --git a/lib/Target/X86/X86MCTargetExpr.h b/lib/Target/X86/X86MCTargetExpr.h
new file mode 100644
index 0000000..7de8a5c
--- /dev/null
+++ b/lib/Target/X86/X86MCTargetExpr.h
@@ -0,0 +1,49 @@
+//===- X86MCTargetExpr.h - X86 Target Specific MCExpr -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86_MCTARGETEXPR_H
+#define X86_MCTARGETEXPR_H
+
+#include "llvm/MC/MCExpr.h"
+
+namespace llvm {
+
+/// X86MCTargetExpr - This class represents symbol variants, like foo@GOT.
+class X86MCTargetExpr : public MCTargetExpr {
+public:
+ enum VariantKind {
+ Invalid,
+ GOT,
+ GOTOFF,
+ GOTPCREL,
+ GOTTPOFF,
+ INDNTPOFF,
+ NTPOFF,
+ PLT,
+ TLSGD,
+ TPOFF
+ };
+private:
+ /// Sym - The symbol being referenced.
+ const MCSymbol * const Sym;
+ /// Kind - The modifier.
+ const VariantKind Kind;
+
+ X86MCTargetExpr(const MCSymbol *S, VariantKind K) : Sym(S), Kind(K) {}
+public:
+ static X86MCTargetExpr *Create(const MCSymbol *Sym, VariantKind K,
+ MCContext &Ctx);
+
+ void PrintImpl(raw_ostream &OS) const;
+ bool EvaluateAsRelocatableImpl(MCValue &Res) const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/lib/Target/X86/X86MachineFunctionInfo.h b/lib/Target/X86/X86MachineFunctionInfo.h
index fafcf7e..4b2529b 100644
--- a/lib/Target/X86/X86MachineFunctionInfo.h
+++ b/lib/Target/X86/X86MachineFunctionInfo.h
@@ -18,12 +18,6 @@
namespace llvm {
-enum NameDecorationStyle {
- None,
- StdCall,
- FastCall
-};
-
/// X86MachineFunctionInfo - This class is derived from MachineFunction and
/// contains private X86 target-specific information for each MachineFunction.
class X86MachineFunctionInfo : public MachineFunctionInfo {
@@ -41,16 +35,11 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
/// Used on windows platform for stdcall & fastcall name decoration
unsigned BytesToPopOnReturn;
- /// DecorationStyle - If the function requires additional name decoration,
- /// DecorationStyle holds the right way to do so.
- NameDecorationStyle DecorationStyle;
-
/// ReturnAddrIndex - FrameIndex for return slot.
int ReturnAddrIndex;
- /// TailCallReturnAddrDelta - Delta the ReturnAddr stack slot is moved
- /// Used for creating an area before the register spill area on the stack
- /// the returnaddr can be savely move to this area
+ /// TailCallReturnAddrDelta - The number of bytes by which return address
+ /// stack slot is moved as the result of tail call optimization.
int TailCallReturnAddrDelta;
/// SRetReturnReg - Some subtargets require that sret lowering includes
@@ -67,7 +56,6 @@ public:
X86MachineFunctionInfo() : ForceFramePointer(false),
CalleeSavedFrameSize(0),
BytesToPopOnReturn(0),
- DecorationStyle(None),
ReturnAddrIndex(0),
TailCallReturnAddrDelta(0),
SRetReturnReg(0),
@@ -77,7 +65,6 @@ public:
: ForceFramePointer(false),
CalleeSavedFrameSize(0),
BytesToPopOnReturn(0),
- DecorationStyle(None),
ReturnAddrIndex(0),
TailCallReturnAddrDelta(0),
SRetReturnReg(0),
@@ -92,9 +79,6 @@ public:
unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; }
void setBytesToPopOnReturn (unsigned bytes) { BytesToPopOnReturn = bytes;}
- NameDecorationStyle getDecorationStyle() const { return DecorationStyle; }
- void setDecorationStyle(NameDecorationStyle style) { DecorationStyle = style;}
-
int getRAIndex() const { return ReturnAddrIndex; }
void setRAIndex(int Index) { ReturnAddrIndex = Index; }
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index f959a2d..8524236 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -473,9 +473,9 @@ bool X86RegisterInfo::hasReservedSpillSlot(MachineFunction &MF, unsigned Reg,
}
int
-X86RegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
+X86RegisterInfo::getFrameIndexOffset(const MachineFunction &MF, int FI) const {
const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
- MachineFrameInfo *MFI = MF.getFrameInfo();
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
int Offset = MFI->getObjectOffset(FI) - TFI.getOffsetOfLocalArea();
uint64_t StackSize = MFI->getStackSize();
@@ -485,7 +485,7 @@ X86RegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
Offset += SlotSize;
} else {
unsigned Align = MFI->getObjectAlignment(FI);
- assert( (-(Offset + StackSize)) % Align == 0);
+ assert((-(Offset + StackSize)) % Align == 0);
Align = 0;
return Offset + StackSize;
}
@@ -498,7 +498,7 @@ X86RegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
Offset += SlotSize;
// Skip the RETADDR move area
- X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
+ const X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
if (TailCallReturnAddrDelta < 0)
Offset -= TailCallReturnAddrDelta;
@@ -627,10 +627,6 @@ X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
- // Calculate and set max stack object alignment early, so we can decide
- // whether we will need stack realignment (and thus FP).
- MFI->calculateMaxStackAlignment();
-
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
@@ -1242,13 +1238,19 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
}
// Jump to label or value in register.
- if (RetOpcode == X86::TCRETURNdi|| RetOpcode == X86::TCRETURNdi64)
+ if (RetOpcode == X86::TCRETURNdi|| RetOpcode == X86::TCRETURNdi64) {
BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPd)).
- addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
- else if (RetOpcode== X86::TCRETURNri64)
+ addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
+ JumpTarget.getTargetFlags());
+ } else if (RetOpcode == X86::TCRETURNri64) {
BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr64), JumpTarget.getReg());
- else
+ } else {
BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr), JumpTarget.getReg());
+ }
+
+ MachineInstr *NewMI = prior(MBBI);
+ for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i)
+ NewMI->addOperand(MBBI->getOperand(i));
// Delete the pseudo instruction TCRETURN.
MBB.erase(MBBI);
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
index dec3fba..8fb5e92 100644
--- a/lib/Target/X86/X86RegisterInfo.h
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -156,7 +156,7 @@ public:
// Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(const MachineFunction &MF) const;
- int getFrameIndexOffset(MachineFunction &MF, int FI) const;
+ int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
void getInitialFrameState(std::vector<MachineMove> &Moves) const;
// Exception handling queries.
diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td
index 6db0cc3..1559bf7 100644
--- a/lib/Target/X86/X86RegisterInfo.td
+++ b/lib/Target/X86/X86RegisterInfo.td
@@ -512,20 +512,17 @@ def GR64_ABCD : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RBX]> {
let SubRegClassList = [GR8_ABCD_L, GR8_ABCD_H, GR16_ABCD, GR32_ABCD];
}
-// GR8_NOREX, GR16_NOREX, GR32_NOREX, GR64_NOREX - Subclasses of
-// GR8, GR16, GR32, and GR64 which contain only the first 8 GPRs.
-// On x86-64, GR64_NOREX, GR32_NOREX and GR16_NOREX are the classes
-// of registers which do not by themselves require a REX prefix.
+// GR8_NOREX - GR8 registers which do not require a REX prefix.
def GR8_NOREX : RegisterClass<"X86", [i8], 8,
- [AL, CL, DL, AH, CH, DH, BL, BH,
- SIL, DIL, BPL, SPL]> {
+ [AL, CL, DL, AH, CH, DH, BL, BH]> {
let MethodProtos = [{
iterator allocation_order_begin(const MachineFunction &MF) const;
iterator allocation_order_end(const MachineFunction &MF) const;
}];
let MethodBodies = [{
+ // In 64-bit mode, it's not safe to blindly allocate H registers.
static const unsigned X86_GR8_NOREX_AO_64[] = {
- X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, X86::BL, X86::BPL
+ X86::AL, X86::CL, X86::DL, X86::BL
};
GR8_NOREXClass::iterator
@@ -541,21 +538,15 @@ def GR8_NOREX : RegisterClass<"X86", [i8], 8,
GR8_NOREXClass::iterator
GR8_NOREXClass::allocation_order_end(const MachineFunction &MF) const {
const TargetMachine &TM = MF.getTarget();
- const TargetRegisterInfo *RI = TM.getRegisterInfo();
const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
- // Does the function dedicate RBP / EBP to being a frame ptr?
- if (!Subtarget.is64Bit())
- // In 32-mode, none of the 8-bit registers aliases EBP or ESP.
- return begin() + 8;
- else if (RI->hasFP(MF))
- // If so, don't allocate SPL or BPL.
- return array_endof(X86_GR8_NOREX_AO_64) - 1;
- else
- // If not, just don't allocate SPL.
+ if (Subtarget.is64Bit())
return array_endof(X86_GR8_NOREX_AO_64);
+ else
+ return end();
}
}];
}
+// GR16_NOREX - GR16 registers which do not require a REX prefix.
def GR16_NOREX : RegisterClass<"X86", [i16], 16,
[AX, CX, DX, SI, DI, BX, BP, SP]> {
let SubRegClassList = [GR8_NOREX, GR8_NOREX];
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
index 2039be7..adef5bc 100644
--- a/lib/Target/X86/X86Subtarget.cpp
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -53,9 +53,9 @@ ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const {
if (GV->hasDLLImportLinkage())
return X86II::MO_DLLIMPORT;
- // GV with ghost linkage (in JIT lazy compilation mode) do not require an
+ // Materializable GVs (in JIT lazy compilation mode) do not require an
// extra load from stub.
- bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
+ bool isDecl = GV->isDeclaration() && !GV->isMaterializable();
// X86-64 in PIC mode.
if (isPICStyleRIPRel()) {
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index 618dd10..5e05c2f 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -175,7 +175,7 @@ public:
else if (isTargetDarwin())
p = "e-p:32:32-f64:32:64-i64:32:64-f80:128:128-n8:16:32";
else if (isTargetMingw() || isTargetWindows())
- p = "e-p:32:32-f64:64:64-i64:64:64-f80:128:128-n8:16:32";
+ p = "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32";
else
p = "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32";
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index 731c3ab..7802f98 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -30,9 +30,8 @@ static const MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
case Triple::MinGW32:
case Triple::MinGW64:
case Triple::Cygwin:
- return new X86MCAsmInfoCOFF(TheTriple);
case Triple::Win32:
- return new X86WinMCAsmInfo(TheTriple);
+ return new X86MCAsmInfoCOFF(TheTriple);
default:
return new X86ELFMCAsmInfo(TheTriple);
}
@@ -48,8 +47,10 @@ extern "C" void LLVMInitializeX86Target() {
RegisterAsmInfoFn B(TheX86_64Target, createMCAsmInfo);
// Register the code emitter.
- TargetRegistry::RegisterCodeEmitter(TheX86_32Target, createX86MCCodeEmitter);
- TargetRegistry::RegisterCodeEmitter(TheX86_64Target, createX86MCCodeEmitter);
+ TargetRegistry::RegisterCodeEmitter(TheX86_32Target,
+ createX86_32MCCodeEmitter);
+ TargetRegistry::RegisterCodeEmitter(TheX86_64Target,
+ createX86_64MCCodeEmitter);
}
@@ -145,10 +146,6 @@ bool X86TargetMachine::addInstSelector(PassManagerBase &PM,
// Install an instruction selector.
PM.add(createX86ISelDag(*this, OptLevel));
- // If we're using Fast-ISel, clean up the mess.
- if (EnableFastISel)
- PM.add(createDeadMachineInstructionElimPass());
-
// Install a pass to insert x87 FP_REG_KILL instructions, as needed.
PM.add(createX87FPRegKillInserterPass());
@@ -168,22 +165,6 @@ bool X86TargetMachine::addPostRegAlloc(PassManagerBase &PM,
bool X86TargetMachine::addCodeEmitter(PassManagerBase &PM,
CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE) {
- // FIXME: Move this to TargetJITInfo!
- // On Darwin, do not override 64-bit setting made in X86TargetMachine().
- if (DefRelocModel == Reloc::Default &&
- (!Subtarget.isTargetDarwin() || !Subtarget.is64Bit())) {
- setRelocationModel(Reloc::Static);
- Subtarget.setPICStyle(PICStyles::None);
- }
-
- PM.add(createX86CodeEmitterPass(*this, MCE));
-
- return false;
-}
-
-bool X86TargetMachine::addCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
JITCodeEmitter &JCE) {
// FIXME: Move this to TargetJITInfo!
// On Darwin, do not override 64-bit setting made in X86TargetMachine().
@@ -199,34 +180,6 @@ bool X86TargetMachine::addCodeEmitter(PassManagerBase &PM,
return false;
}
-bool X86TargetMachine::addCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE) {
- PM.add(createX86ObjectCodeEmitterPass(*this, OCE));
- return false;
-}
-
-bool X86TargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE) {
- PM.add(createX86CodeEmitterPass(*this, MCE));
- return false;
-}
-
-bool X86TargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- JITCodeEmitter &JCE) {
- PM.add(createX86JITCodeEmitterPass(*this, JCE));
- return false;
-}
-
-bool X86TargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE) {
- PM.add(createX86ObjectCodeEmitterPass(*this, OCE));
- return false;
-}
-
void X86TargetMachine::setCodeModelForStatic() {
if (getCodeModel() != CodeModel::Default) return;
@@ -246,32 +199,3 @@ void X86TargetMachine::setCodeModelForJIT() {
else
setCodeModel(CodeModel::Small);
}
-
-/// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are 4-byte,
-/// 8-byte, and target default. The CIE is hard-coded to indicate that the LSDA
-/// pointer in the FDE section is an "sdata4", and should be encoded as a 4-byte
-/// pointer by default. However, some systems may require a different size due
-/// to bugs or other conditions. We will default to a 4-byte encoding unless the
-/// system tells us otherwise.
-///
-/// The issue is when the CIE says their is an LSDA. That mandates that every
-/// FDE have an LSDA slot. But if the function does not need an LSDA. There
-/// needs to be some way to signify there is none. The LSDA is encoded as
-/// pc-rel. But you don't look for some magic value after adding the pc. You
-/// have to look for a zero before adding the pc. The problem is that the size
-/// of the zero to look for depends on the encoding. The unwinder bug in SL is
-/// that it always checks for a pointer-size zero. So on x86_64 it looks for 8
-/// bytes of zero. If you have an LSDA, it works fine since the 8-bytes are
-/// non-zero so it goes ahead and then reads the value based on the encoding.
-/// But if you use sdata4 and there is no LSDA, then the test for zero gives a
-/// false negative and the unwinder thinks there is an LSDA.
-///
-/// FIXME: This call-back isn't good! We should be using the correct encoding
-/// regardless of the system. However, there are some systems which have bugs
-/// that prevent this from occuring.
-DwarfLSDAEncoding::Encoding X86TargetMachine::getLSDAEncoding() const {
- if (Subtarget.isTargetDarwin() && Subtarget.getDarwinVers() != 10)
- return DwarfLSDAEncoding::Default;
-
- return DwarfLSDAEncoding::EightByte;
-}
diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h
index d05bebd..2bb5454 100644
--- a/lib/Target/X86/X86TargetMachine.h
+++ b/lib/Target/X86/X86TargetMachine.h
@@ -62,37 +62,12 @@ public:
return Subtarget.isTargetELF() ? &ELFWriterInfo : 0;
}
- /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are
- /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that
- /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded
- /// as a 4-byte pointer by default. However, some systems may require a
- /// different size due to bugs or other conditions. We will default to a
- /// 4-byte encoding unless the system tells us otherwise.
- ///
- /// FIXME: This call-back isn't good! We should be using the correct encoding
- /// regardless of the system. However, there are some systems which have bugs
- /// that prevent this from occuring.
- virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const;
-
// Set up the pass pipeline.
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addPreRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addPostRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE);
- virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
JITCodeEmitter &JCE);
- virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- MachineCodeEmitter &MCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- JITCodeEmitter &JCE);
- virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
- CodeGenOpt::Level OptLevel,
- ObjectCodeEmitter &OCE);
};
/// X86_32TargetMachine - X86 32-bit target machine.
diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp
index 41ad153..d1ee3fc 100644
--- a/lib/Target/X86/X86TargetObjectFile.cpp
+++ b/lib/Target/X86/X86TargetObjectFile.cpp
@@ -7,60 +7,176 @@
//
//===----------------------------------------------------------------------===//
+#include "X86MCTargetExpr.h"
#include "X86TargetObjectFile.h"
+#include "X86TargetMachine.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
#include "llvm/Target/Mangler.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Dwarf.h"
using namespace llvm;
+using namespace dwarf;
const MCExpr *X8632_MachoTargetObjectFile::
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const {
+ MachineModuleInfo *MMI, unsigned Encoding) const {
// The mach-o version of this method defaults to returning a stub reference.
- IsIndirect = true;
- IsPCRel = false;
-
-
- MachineModuleInfoMachO &MachOMMI =
- MMI->getObjFileInfo<MachineModuleInfoMachO>();
-
- // FIXME: Use GetSymbolWithGlobalValueBase.
- SmallString<128> Name;
- Mang->getNameWithPrefix(Name, GV, true);
- Name += "$non_lazy_ptr";
-
- // Add information about the stub reference to MachOMMI so that the stub gets
- // emitted by the asmprinter.
- MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
- const MCSymbol *&StubSym = MachOMMI.getGVStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = getContext().GetOrCreateSymbol(Name.str());
+
+ if (Encoding & DW_EH_PE_indirect) {
+ MachineModuleInfoMachO &MachOMMI =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>();
+
+ SmallString<128> Name;
+ Mang->getNameWithPrefix(Name, GV, true);
+ Name += "$non_lazy_ptr";
+
+ // Add information about the stub reference to MachOMMI so that the stub
+ // gets emitted by the asmprinter.
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
+ MCSymbol *&StubSym = MachOMMI.getGVStubEntry(Sym);
+ if (StubSym == 0) {
+ Name.clear();
+ Mang->getNameWithPrefix(Name, GV, false);
+ StubSym = getContext().GetOrCreateSymbol(Name.str());
+ }
+
+ return TargetLoweringObjectFile::
+ getSymbolForDwarfReference(Sym, MMI,
+ Encoding & ~dwarf::DW_EH_PE_indirect);
}
-
- return MCSymbolRefExpr::Create(Sym, getContext());
+
+ return TargetLoweringObjectFileMachO::
+ getSymbolForDwarfGlobalReference(GV, Mang, MMI, Encoding);
}
const MCExpr *X8664_MachoTargetObjectFile::
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const {
-
+ MachineModuleInfo *MMI, unsigned Encoding) const {
+
// On Darwin/X86-64, we can reference dwarf symbols with foo@GOTPCREL+4, which
// is an indirect pc-relative reference.
- IsIndirect = true;
- IsPCRel = true;
-
- SmallString<128> Name;
- Mang->getNameWithPrefix(Name, GV, false);
- Name += "@GOTPCREL";
- const MCExpr *Res =
- MCSymbolRefExpr::Create(Name.str(), getContext());
- const MCExpr *Four = MCConstantExpr::Create(4, getContext());
- return MCBinaryExpr::CreateAdd(Res, Four, getContext());
+ if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) {
+ SmallString<128> Name;
+ Mang->getNameWithPrefix(Name, GV, false);
+ const MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+ const MCExpr *Res =
+ X86MCTargetExpr::Create(Sym, X86MCTargetExpr::GOTPCREL, getContext());
+ const MCExpr *Four = MCConstantExpr::Create(4, getContext());
+ return MCBinaryExpr::CreateAdd(Res, Four, getContext());
+ }
+
+ return TargetLoweringObjectFileMachO::
+ getSymbolForDwarfGlobalReference(GV, Mang, MMI, Encoding);
}
+unsigned X8632_ELFTargetObjectFile::getPersonalityEncoding() const {
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ else
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8632_ELFTargetObjectFile::getLSDAEncoding() const {
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ else
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8632_ELFTargetObjectFile::getFDEEncoding() const {
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ else
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8632_ELFTargetObjectFile::getTTypeEncoding() const {
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+ else
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8664_ELFTargetObjectFile::getPersonalityEncoding() const {
+ CodeModel::Model Model = TM.getCodeModel();
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | (Model == CodeModel::Small ||
+ Model == CodeModel::Medium ?
+ DW_EH_PE_sdata4 : DW_EH_PE_sdata8);
+
+ if (Model == CodeModel::Small || Model == CodeModel::Medium)
+ return DW_EH_PE_udata4;
+
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8664_ELFTargetObjectFile::getLSDAEncoding() const {
+ CodeModel::Model Model = TM.getCodeModel();
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_pcrel | (Model == CodeModel::Small ?
+ DW_EH_PE_sdata4 : DW_EH_PE_sdata8);
+
+ if (Model == CodeModel::Small)
+ return DW_EH_PE_udata4;
+
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8664_ELFTargetObjectFile::getFDEEncoding() const {
+ CodeModel::Model Model = TM.getCodeModel();
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_pcrel | (Model == CodeModel::Small ||
+ Model == CodeModel::Medium ?
+ DW_EH_PE_sdata4 : DW_EH_PE_sdata8);
+
+ if (Model == CodeModel::Small || Model == CodeModel::Medium)
+ return DW_EH_PE_udata4;
+
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8664_ELFTargetObjectFile::getTTypeEncoding() const {
+ CodeModel::Model Model = TM.getCodeModel();
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | (Model == CodeModel::Small ||
+ Model == CodeModel::Medium ?
+ DW_EH_PE_sdata4 : DW_EH_PE_sdata8);
+
+ if (Model == CodeModel::Small)
+ return DW_EH_PE_udata4;
+
+ return DW_EH_PE_absptr;
+}
+
+unsigned X8632_MachoTargetObjectFile::getPersonalityEncoding() const {
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
+
+unsigned X8632_MachoTargetObjectFile::getLSDAEncoding() const {
+ return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
+
+unsigned X8632_MachoTargetObjectFile::getFDEEncoding() const {
+ return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
+
+unsigned X8632_MachoTargetObjectFile::getTTypeEncoding() const {
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
+
+unsigned X8664_MachoTargetObjectFile::getPersonalityEncoding() const {
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
+
+unsigned X8664_MachoTargetObjectFile::getLSDAEncoding() const {
+ return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
+
+unsigned X8664_MachoTargetObjectFile::getFDEEncoding() const {
+ return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
+
+unsigned X8664_MachoTargetObjectFile::getTTypeEncoding() const {
+ return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
diff --git a/lib/Target/X86/X86TargetObjectFile.h b/lib/Target/X86/X86TargetObjectFile.h
index 377a93b..0fff194 100644
--- a/lib/Target/X86/X86TargetObjectFile.h
+++ b/lib/Target/X86/X86TargetObjectFile.h
@@ -10,21 +10,27 @@
#ifndef LLVM_TARGET_X86_TARGETOBJECTFILE_H
#define LLVM_TARGET_X86_TARGETOBJECTFILE_H
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
namespace llvm {
-
+ class X86TargetMachine;
+
/// X8632_MachoTargetObjectFile - This TLOF implementation is used for
/// Darwin/x86-32.
class X8632_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
public:
-
+
virtual const MCExpr *
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const;
+ MachineModuleInfo *MMI, unsigned Encoding) const;
+ virtual unsigned getPersonalityEncoding() const;
+ virtual unsigned getLSDAEncoding() const;
+ virtual unsigned getFDEEncoding() const;
+ virtual unsigned getTTypeEncoding() const;
};
-
+
/// X8664_MachoTargetObjectFile - This TLOF implementation is used for
/// Darwin/x86-64.
class X8664_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
@@ -32,9 +38,35 @@ namespace llvm {
virtual const MCExpr *
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- bool &IsIndirect, bool &IsPCRel) const;
+ MachineModuleInfo *MMI, unsigned Encoding) const;
+ virtual unsigned getPersonalityEncoding() const;
+ virtual unsigned getLSDAEncoding() const;
+ virtual unsigned getFDEEncoding() const;
+ virtual unsigned getTTypeEncoding() const;
+ };
+
+ class X8632_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
+ const X86TargetMachine &TM;
+ public:
+ X8632_ELFTargetObjectFile(const X86TargetMachine &tm)
+ :TM(tm) { };
+ virtual unsigned getPersonalityEncoding() const;
+ virtual unsigned getLSDAEncoding() const;
+ virtual unsigned getFDEEncoding() const;
+ virtual unsigned getTTypeEncoding() const;
};
+
+ class X8664_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
+ const X86TargetMachine &TM;
+ public:
+ X8664_ELFTargetObjectFile(const X86TargetMachine &tm)
+ :TM(tm) { };
+ virtual unsigned getPersonalityEncoding() const;
+ virtual unsigned getLSDAEncoding() const;
+ virtual unsigned getFDEEncoding() const;
+ virtual unsigned getTTypeEncoding() const;
+ };
+
} // end namespace llvm
#endif
diff --git a/lib/Target/XCore/AsmPrinter/Makefile b/lib/Target/XCore/AsmPrinter/Makefile
index f0e883e..82dc1df 100644
--- a/lib/Target/XCore/AsmPrinter/Makefile
+++ b/lib/Target/XCore/AsmPrinter/Makefile
@@ -9,7 +9,6 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMXCoreAsmPrinter
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' XCore target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
index 40d7160..d18f55d 100644
--- a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
+++ b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
@@ -32,7 +32,6 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
@@ -42,8 +41,6 @@
#include <cctype>
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
static cl::opt<unsigned> MaxThreads("xcore-max-threads", cl::Optional,
cl::desc("Maximum number of threads (for emulation thread-local storage)"),
cl::Hidden,
@@ -55,8 +52,9 @@ namespace {
const XCoreSubtarget &Subtarget;
public:
explicit XCoreAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const MCAsmInfo *T, bool V)
- : AsmPrinter(O, TM, T, V),
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
+ : AsmPrinter(O, TM, Ctx, Streamer, T),
Subtarget(TM.getSubtarget<XCoreSubtarget>()) {}
virtual const char *getPassName() const {
@@ -74,13 +72,13 @@ namespace {
virtual void EmitGlobalVariable(const GlobalVariable *GV);
void emitFunctionStart(MachineFunction &MF);
- void emitFunctionEnd(MachineFunction &MF);
void printInstruction(const MachineInstr *MI); // autogenerated.
static const char *getRegisterName(unsigned RegNo);
- void printMachineInstruction(const MachineInstr *MI);
- bool runOnMachineFunction(MachineFunction &F);
+ bool runOnMachineFunction(MachineFunction &MF);
+ void EmitInstruction(const MachineInstr *MI);
+ void EmitFunctionBodyEnd();
void getAnalysisUsage(AnalysisUsage &AU) const {
AsmPrinter::getAnalysisUsage(AU);
@@ -106,7 +104,7 @@ void XCoreAsmPrinter::emitArrayBound(const MCSymbol *Sym,
cast<PointerType>(GV->getType())->getElementType())) {
O << MAI->getGlobalDirective() << *Sym;
O << ".globound" << "\n";
- O << MAI->getSetDirective() << *Sym;
+ O << "\t.set\t" << *Sym;
O << ".globound" << "," << ATy->getNumElements() << "\n";
if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
// TODO Use COMDAT groups for LinkOnceLinkage
@@ -150,8 +148,6 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
case GlobalValue::PrivateLinkage:
case GlobalValue::LinkerPrivateLinkage:
break;
- case GlobalValue::GhostLinkage:
- llvm_unreachable("Should not have any unmaterialized functions!");
case GlobalValue::DLLImportLinkage:
llvm_unreachable("DLLImport linkage is not supported by this target!");
case GlobalValue::DLLExportLinkage:
@@ -222,26 +218,22 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
O << *CurrentFnSym << ":\n";
}
-/// Emit the directives on the end of functions
-void XCoreAsmPrinter::emitFunctionEnd(MachineFunction &MF) {
- // Mark the end of the function
+
+/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
+/// the last basic block in the function.
+void XCoreAsmPrinter::EmitFunctionBodyEnd() {
+ // Emit function end directives
O << "\t.cc_bottom " << *CurrentFnSym << ".function\n";
}
/// runOnMachineFunction - This uses the printMachineInstruction()
/// method to print assembly for each instruction.
///
-bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &MF)
-{
- this->MF = &MF;
-
+bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &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);
+ EmitConstantPool();
// Emit the function start directives
emitFunctionStart(MF);
@@ -249,32 +241,7 @@ bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &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()) {
- EmitBasicBlockStart(I);
- }
-
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II) {
- // Print the assembly for the instruction.
- 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.
+ EmitFunctionBody();
return false;
}
@@ -300,7 +267,7 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- O << *GetMBBSymbol(MO.getMBB()->getNumber());
+ O << *MO.getMBB()->getSymbol(OutContext);
break;
case MachineOperand::MO_GlobalAddress:
O << *GetGlobalValueSymbol(MO.getGlobal());
@@ -333,24 +300,17 @@ bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
return false;
}
-void XCoreAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
- ++EmittedInsts;
-
- processDebugLoc(MI, true);
-
+void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Check for mov mnemonic
unsigned src, dst, srcSR, dstSR;
if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst, srcSR, dstSR)) {
O << "\tmov " << getRegisterName(dst) << ", ";
- O << getRegisterName(src) << '\n';
+ O << getRegisterName(src);
+ OutStreamer.AddBlankLine();
return;
}
printInstruction(MI);
- if (VerboseAsm)
- EmitComments(*MI);
- O << '\n';
-
- processDebugLoc(MI, false);
+ OutStreamer.AddBlankLine();
}
// Force static initialization.
diff --git a/lib/Target/XCore/Makefile b/lib/Target/XCore/Makefile
index 3bb127f..1b70974 100644
--- a/lib/Target/XCore/Makefile
+++ b/lib/Target/XCore/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMXCoreCodeGen
TARGET = XCore
-CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = XCoreGenRegisterInfo.h.inc XCoreGenRegisterNames.inc \
diff --git a/lib/Target/XCore/TargetInfo/Makefile b/lib/Target/XCore/TargetInfo/Makefile
index 83bba13..f8a4095 100644
--- a/lib/Target/XCore/TargetInfo/Makefile
+++ b/lib/Target/XCore/TargetInfo/Makefile
@@ -9,7 +9,6 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMXCoreInfo
-CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp
index 6849e0b..57fd43b 100644
--- a/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/lib/Target/XCore/XCoreISelLowering.cpp
@@ -390,7 +390,12 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG)
if (Offset % 4 == 0) {
// We've managed to infer better alignment information than the load
// already has. Use an aligned load.
- return DAG.getLoad(getPointerTy(), dl, Chain, BasePtr, NULL, 4);
+ //
+ // FIXME: No new alignment information is actually passed here.
+ // Should the offset really be 4?
+ //
+ return DAG.getLoad(getPointerTy(), dl, Chain, BasePtr, NULL, 4,
+ false, false, 0);
}
// Lower to
// ldw low, base[offset >> 2]
@@ -407,9 +412,9 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG)
SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, Base, HighOffset);
SDValue Low = DAG.getLoad(getPointerTy(), dl, Chain,
- LowAddr, NULL, 4);
+ LowAddr, NULL, 4, false, false, 0);
SDValue High = DAG.getLoad(getPointerTy(), dl, Chain,
- HighAddr, NULL, 4);
+ HighAddr, NULL, 4, false, false, 0);
SDValue LowShifted = DAG.getNode(ISD::SRL, dl, MVT::i32, Low, LowShift);
SDValue HighShifted = DAG.getNode(ISD::SHL, dl, MVT::i32, High, HighShift);
SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, LowShifted, HighShifted);
@@ -423,12 +428,13 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG)
int SVOffset = LD->getSrcValueOffset();
SDValue Low = DAG.getExtLoad(ISD::ZEXTLOAD, dl, MVT::i32, Chain,
BasePtr, LD->getSrcValue(), SVOffset, MVT::i16,
- LD->isVolatile(), 2);
+ LD->isVolatile(), LD->isNonTemporal(), 2);
SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr,
DAG.getConstant(2, MVT::i32));
SDValue High = DAG.getExtLoad(ISD::EXTLOAD, dl, MVT::i32, Chain,
HighAddr, LD->getSrcValue(), SVOffset + 2,
- MVT::i16, LD->isVolatile(), 2);
+ MVT::i16, LD->isVolatile(),
+ LD->isNonTemporal(), 2);
SDValue HighShifted = DAG.getNode(ISD::SHL, dl, MVT::i32, High,
DAG.getConstant(16, MVT::i32));
SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, Low, HighShifted);
@@ -487,12 +493,14 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG)
DAG.getConstant(16, MVT::i32));
SDValue StoreLow = DAG.getTruncStore(Chain, dl, Low, BasePtr,
ST->getSrcValue(), SVOffset, MVT::i16,
- ST->isVolatile(), 2);
+ ST->isVolatile(), ST->isNonTemporal(),
+ 2);
SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr,
DAG.getConstant(2, MVT::i32));
SDValue StoreHigh = DAG.getTruncStore(Chain, dl, High, HighAddr,
ST->getSrcValue(), SVOffset + 2,
- MVT::i16, ST->isVolatile(), 2);
+ MVT::i16, ST->isVolatile(),
+ ST->isNonTemporal(), 2);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, StoreLow, StoreHigh);
}
@@ -561,15 +569,16 @@ LowerVAARG(SDValue Op, SelectionDAG &DAG)
const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
EVT VT = Node->getValueType(0);
SDValue VAList = DAG.getLoad(getPointerTy(), dl, Node->getOperand(0),
- Node->getOperand(1), V, 0);
+ Node->getOperand(1), V, 0, false, false, 0);
// Increment the pointer, VAList, to the next vararg
SDValue Tmp3 = DAG.getNode(ISD::ADD, dl, getPointerTy(), VAList,
DAG.getConstant(VT.getSizeInBits(),
getPointerTy()));
// Store the incremented VAList to the legalized pointer
- Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), V, 0);
+ Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), V, 0,
+ false, false, 0);
// Load the actual argument out of the pointer VAList
- return DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0);
+ return DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0, false, false, 0);
}
SDValue XCoreTargetLowering::
@@ -582,7 +591,8 @@ LowerVASTART(SDValue Op, SelectionDAG &DAG)
XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
SDValue Addr = DAG.getFrameIndex(XFI->getVarArgsFrameIndex(), MVT::i32);
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
- return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), SV, 0);
+ return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), SV, 0,
+ false, false, 0);
}
SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
@@ -611,11 +621,13 @@ SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
SDValue
XCoreTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // XCore target does not yet support tail call optimization.
+ isTailCall = false;
// For now, only CallingConv::C implemented
switch (CallConv)
@@ -875,7 +887,8 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain,
// Create the SelectionDAG nodes corresponding to a load
//from this parameter
SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
- InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, NULL, 0));
+ InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, NULL, 0,
+ false, false, 0));
}
}
@@ -906,7 +919,8 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain,
RegInfo.addLiveIn(ArgRegs[i], VReg);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
// Move argument from virt reg -> stack
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0,
+ false, false, 0);
MemOps.push_back(Store);
}
if (!MemOps.empty())
diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h
index f86be5e..5095f36 100644
--- a/lib/Target/XCore/XCoreISelLowering.h
+++ b/lib/Target/XCore/XCoreISelLowering.h
@@ -28,7 +28,7 @@ namespace llvm {
namespace XCoreISD {
enum NodeType {
// Start the numbering where the builtin ops and target ops leave off.
- FIRST_NUMBER = ISD::BUILTIN_OP_END+XCore::INSTRUCTION_LIST_END,
+ FIRST_NUMBER = ISD::BUILTIN_OP_END,
// Branch and link (call)
BL,
@@ -149,7 +149,7 @@ namespace llvm {
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/XCore/XCoreInstrInfo.td b/lib/Target/XCore/XCoreInstrInfo.td
index d4ae49e..10dc18c 100644
--- a/lib/Target/XCore/XCoreInstrInfo.td
+++ b/lib/Target/XCore/XCoreInstrInfo.td
@@ -686,7 +686,7 @@ def LDAP_lu10_ba : _FLU10<(outs),
[(set R11, (pcrelwrapper tblockaddress:$addr))]>;
let isCall=1,
-// All calls clobber the the link register and the non-callee-saved registers:
+// All calls clobber the link register and the non-callee-saved registers:
Defs = [R0, R1, R2, R3, R11, LR] in {
def BL_u10 : _FU10<
(outs),
@@ -779,7 +779,7 @@ def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src),
[]>;
let isCall=1,
-// All calls clobber the the link register and the non-callee-saved registers:
+// All calls clobber the link register and the non-callee-saved registers:
Defs = [R0, R1, R2, R3, R11, LR] in {
def BLA_1r : _F1R<(outs), (ins GRRegs:$addr, variable_ops),
"bla $addr",
diff --git a/lib/Target/XCore/XCoreMCAsmInfo.cpp b/lib/Target/XCore/XCoreMCAsmInfo.cpp
index dffdda9..bf78575 100644
--- a/lib/Target/XCore/XCoreMCAsmInfo.cpp
+++ b/lib/Target/XCore/XCoreMCAsmInfo.cpp
@@ -22,7 +22,6 @@ XCoreMCAsmInfo::XCoreMCAsmInfo(const Target &T, const StringRef &TT) {
AscizDirective = ".asciiz";
WeakDefDirective = "\t.weak\t";
WeakRefDirective = "\t.weak\t";
- SetDirective = "\t.set\t";
// Debug
HasLEB128 = true;
diff --git a/lib/Target/XCore/XCoreTargetObjectFile.h b/lib/Target/XCore/XCoreTargetObjectFile.h
index 7efb990..7424c78 100644
--- a/lib/Target/XCore/XCoreTargetObjectFile.h
+++ b/lib/Target/XCore/XCoreTargetObjectFile.h
@@ -10,13 +10,12 @@
#ifndef LLVM_TARGET_XCORE_TARGETOBJECTFILE_H
#define LLVM_TARGET_XCORE_TARGETOBJECTFILE_H
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
namespace llvm {
class XCoreTargetObjectFile : public TargetLoweringObjectFileELF {
public:
-
void Initialize(MCContext &Ctx, const TargetMachine &TM);
// TODO: Classify globals as xcore wishes.
diff --git a/lib/Transforms/Hello/Makefile b/lib/Transforms/Hello/Makefile
index 46f8098..c5e75d4 100644
--- a/lib/Transforms/Hello/Makefile
+++ b/lib/Transforms/Hello/Makefile
@@ -11,7 +11,6 @@ LEVEL = ../../..
LIBRARYNAME = LLVMHello
LOADABLE_MODULE = 1
USEDLIBS =
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp
index d8190a4..325d353 100644
--- a/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -247,7 +247,7 @@ static bool PrefixIn(const ArgPromotion::IndicesVector &Indices,
return Low != Set.end() && IsPrefix(*Low, Indices);
}
-/// Mark the given indices (ToMark) as safe in the the given set of indices
+/// Mark the given indices (ToMark) as safe in the given set of indices
/// (Safe). Marking safe usually means adding ToMark to Safe. However, if there
/// is already a prefix of Indices in Safe, Indices are implicitely marked safe
/// already. Furthermore, any indices that Indices is itself a prefix of, are
diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp
index 4972687..3c05f88 100644
--- a/lib/Transforms/IPO/ConstantMerge.cpp
+++ b/lib/Transforms/IPO/ConstantMerge.cpp
@@ -19,10 +19,11 @@
#define DEBUG_TYPE "constmerge"
#include "llvm/Transforms/IPO.h"
+#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Statistic.h"
-#include <map>
using namespace llvm;
STATISTIC(NumMerged, "Number of global constants merged");
@@ -48,10 +49,10 @@ ModulePass *llvm::createConstantMergePass() { return new ConstantMerge(); }
bool ConstantMerge::runOnModule(Module &M) {
// Map unique constant/section pairs to globals. We don't want to merge
// globals in different sections.
- std::map<std::pair<Constant*, std::string>, GlobalVariable*> CMap;
+ DenseMap<Constant*, GlobalVariable*> CMap;
// Replacements - This vector contains a list of replacements to perform.
- std::vector<std::pair<GlobalVariable*, GlobalVariable*> > Replacements;
+ SmallVector<std::pair<GlobalVariable*, GlobalVariable*>, 32> Replacements;
bool MadeChange = false;
@@ -76,19 +77,21 @@ bool ConstantMerge::runOnModule(Module &M) {
continue;
}
- // Only process constants with initializers.
- if (GV->isConstant() && GV->hasDefinitiveInitializer()) {
- Constant *Init = GV->getInitializer();
-
- // Check to see if the initializer is already known.
- GlobalVariable *&Slot = CMap[std::make_pair(Init, GV->getSection())];
-
- if (Slot == 0) { // Nope, add it to the map.
- Slot = GV;
- } else if (GV->hasLocalLinkage()) { // Yup, this is a duplicate!
- // Make all uses of the duplicate constant use the canonical version.
- Replacements.push_back(std::make_pair(GV, Slot));
- }
+ // Only process constants with initializers in the default addres space.
+ if (!GV->isConstant() ||!GV->hasDefinitiveInitializer() ||
+ GV->getType()->getAddressSpace() != 0 || !GV->getSection().empty())
+ continue;
+
+ Constant *Init = GV->getInitializer();
+
+ // Check to see if the initializer is already known.
+ GlobalVariable *&Slot = CMap[Init];
+
+ if (Slot == 0) { // Nope, add it to the map.
+ Slot = GV;
+ } else if (GV->hasLocalLinkage()) { // Yup, this is a duplicate!
+ // Make all uses of the duplicate constant use the canonical version.
+ Replacements.push_back(std::make_pair(GV, Slot));
}
}
@@ -100,11 +103,11 @@ bool ConstantMerge::runOnModule(Module &M) {
// now. This avoid invalidating the pointers in CMap, which are unneeded
// now.
for (unsigned i = 0, e = Replacements.size(); i != e; ++i) {
- // Eliminate any uses of the dead global...
+ // Eliminate any uses of the dead global.
Replacements[i].first->replaceAllUsesWith(Replacements[i].second);
- // Delete the global value from the module...
- M.getGlobalList().erase(Replacements[i].first);
+ // Delete the global value from the module.
+ Replacements[i].first->eraseFromParent();
}
NumMerged += Replacements.size();
diff --git a/lib/Transforms/IPO/DeadTypeElimination.cpp b/lib/Transforms/IPO/DeadTypeElimination.cpp
index 025d77e..662fbb5 100644
--- a/lib/Transforms/IPO/DeadTypeElimination.cpp
+++ b/lib/Transforms/IPO/DeadTypeElimination.cpp
@@ -57,13 +57,13 @@ ModulePass *llvm::createDeadTypeEliminationPass() {
//
static inline bool ShouldNukeSymtabEntry(const Type *Ty){
// Nuke all names for primitive types!
- if (Ty->isPrimitiveType() || Ty->isInteger())
+ if (Ty->isPrimitiveType() || Ty->isIntegerTy())
return true;
// Nuke all pointers to primitive types as well...
if (const PointerType *PT = dyn_cast<PointerType>(Ty))
if (PT->getElementType()->isPrimitiveType() ||
- PT->getElementType()->isInteger())
+ PT->getElementType()->isIntegerTy())
return true;
return false;
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index ee260e9..df060eb 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -638,8 +638,8 @@ static bool AllUsesOfValueWillTrapIfNull(Value *V,
} else if (PHINode *PN = dyn_cast<PHINode>(*UI)) {
// If we've already seen this phi node, ignore it, it has already been
// checked.
- if (PHIs.insert(PN))
- return AllUsesOfValueWillTrapIfNull(PN, PHIs);
+ if (PHIs.insert(PN) && !AllUsesOfValueWillTrapIfNull(PN, PHIs))
+ return false;
} else if (isa<ICmpInst>(*UI) &&
isa<ConstantPointerNull>(UI->getOperand(1))) {
// Ignore setcc X, null
@@ -1590,7 +1590,7 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
// simplification. In these cases, we typically end up with "cond ? v1 : v2"
// where v1 and v2 both require constant pool loads, a big loss.
if (GVElType == Type::getInt1Ty(GV->getContext()) ||
- GVElType->isFloatingPoint() ||
+ GVElType->isFloatingPointTy() ||
isa<PointerType>(GVElType) || isa<VectorType>(GVElType))
return false;
@@ -1925,7 +1925,7 @@ GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) {
if (!ATy) return 0;
const StructType *STy = dyn_cast<StructType>(ATy->getElementType());
if (!STy || STy->getNumElements() != 2 ||
- !STy->getElementType(0)->isInteger(32)) return 0;
+ !STy->getElementType(0)->isIntegerTy(32)) return 0;
const PointerType *PFTy = dyn_cast<PointerType>(STy->getElementType(1));
if (!PFTy) return 0;
const FunctionType *FTy = dyn_cast<FunctionType>(PFTy->getElementType());
diff --git a/lib/Transforms/IPO/Inliner.cpp b/lib/Transforms/IPO/Inliner.cpp
index 0990278..752a97c 100644
--- a/lib/Transforms/IPO/Inliner.cpp
+++ b/lib/Transforms/IPO/Inliner.cpp
@@ -38,8 +38,15 @@ STATISTIC(NumDeleted, "Number of functions deleted because all callers found");
STATISTIC(NumMergedAllocas, "Number of allocas merged together");
static cl::opt<int>
-InlineLimit("inline-threshold", cl::Hidden, cl::init(200), cl::ZeroOrMore,
- cl::desc("Control the amount of inlining to perform (default = 200)"));
+InlineLimit("inline-threshold", cl::Hidden, cl::init(225), cl::ZeroOrMore,
+ cl::desc("Control the amount of inlining to perform (default = 225)"));
+
+static cl::opt<int>
+HintThreshold("inlinehint-threshold", cl::Hidden, cl::init(325),
+ cl::desc("Threshold for inlining functions with inline hint"));
+
+// Threshold to use when optsize is specified (and there is no -inline-limit).
+const int OptSizeThreshold = 75;
Inliner::Inliner(void *ID)
: CallGraphSCCPass(ID), InlineThreshold(InlineLimit) {}
@@ -172,13 +179,23 @@ static bool InlineCallIfPossible(CallSite CS, CallGraph &CG,
return true;
}
-unsigned Inliner::getInlineThreshold(Function* Caller) const {
+unsigned Inliner::getInlineThreshold(CallSite CS) const {
+ int thres = InlineThreshold;
+
+ // Listen to optsize when -inline-limit is not given.
+ Function *Caller = CS.getCaller();
if (Caller && !Caller->isDeclaration() &&
Caller->hasFnAttr(Attribute::OptimizeForSize) &&
InlineLimit.getNumOccurrences() == 0)
- return 50;
- else
- return InlineThreshold;
+ thres = OptSizeThreshold;
+
+ // Listen to inlinehint when it would increase the threshold.
+ Function *Callee = CS.getCalledFunction();
+ if (HintThreshold > thres && Callee && !Callee->isDeclaration() &&
+ Callee->hasFnAttr(Attribute::InlineHint))
+ thres = HintThreshold;
+
+ return thres;
}
/// shouldInline - Return true if the inliner should attempt to inline
@@ -200,7 +217,7 @@ bool Inliner::shouldInline(CallSite CS) {
int Cost = IC.getValue();
Function *Caller = CS.getCaller();
- int CurrentThreshold = getInlineThreshold(Caller);
+ int CurrentThreshold = getInlineThreshold(CS);
float FudgeFactor = getInlineFudgeFactor(CS);
if (Cost >= (int)(CurrentThreshold * FudgeFactor)) {
DEBUG(dbgs() << " NOT Inlining: cost=" << Cost
@@ -236,8 +253,7 @@ bool Inliner::shouldInline(CallSite CS) {
outerCallsFound = true;
int Cost2 = IC2.getValue();
- Function *Caller2 = CS2.getCaller();
- int CurrentThreshold2 = getInlineThreshold(Caller2);
+ int CurrentThreshold2 = getInlineThreshold(CS2);
float FudgeFactor2 = getInlineFudgeFactor(CS2);
if (Cost2 >= (int)(CurrentThreshold2 * FudgeFactor2))
diff --git a/lib/Transforms/IPO/Makefile b/lib/Transforms/IPO/Makefile
index fd018c4..5c42374 100644
--- a/lib/Transforms/IPO/Makefile
+++ b/lib/Transforms/IPO/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMipo
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp
index fa8845b..b07e22c 100644
--- a/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/lib/Transforms/IPO/MergeFunctions.cpp
@@ -467,7 +467,6 @@ static LinkageCategory categorize(const Function *F) {
case GlobalValue::AppendingLinkage:
case GlobalValue::DLLImportLinkage:
case GlobalValue::DLLExportLinkage:
- case GlobalValue::GhostLinkage:
case GlobalValue::CommonLinkage:
return ExternalStrong;
}
diff --git a/lib/Transforms/IPO/PartialInlining.cpp b/lib/Transforms/IPO/PartialInlining.cpp
index f40902f..f8ec722 100644
--- a/lib/Transforms/IPO/PartialInlining.cpp
+++ b/lib/Transforms/IPO/PartialInlining.cpp
@@ -117,7 +117,7 @@ Function* PartialInliner::unswitchFunction(Function* F) {
DominatorTree DT;
DT.runOnFunction(*duplicateFunction);
- // Extract the body of the the if.
+ // Extract the body of the if.
Function* extractedFunction = ExtractCodeRegion(DT, toExtract);
// Inline the top-level if test into all callers.
diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp
index 0e0d83a..310e4a2 100644
--- a/lib/Transforms/IPO/StripSymbols.cpp
+++ b/lib/Transforms/IPO/StripSymbols.cpp
@@ -214,6 +214,15 @@ static bool StripDebugInfo(Module &M) {
Changed = true;
}
+ if (Function *DbgVal = M.getFunction("llvm.dbg.value")) {
+ while (!DbgVal->use_empty()) {
+ CallInst *CI = cast<CallInst>(DbgVal->use_back());
+ CI->eraseFromParent();
+ }
+ DbgVal->eraseFromParent();
+ Changed = true;
+ }
+
NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv");
if (NMD) {
Changed = true;
diff --git a/lib/Transforms/InstCombine/InstCombine.h b/lib/Transforms/InstCombine/InstCombine.h
index 5367900..09accb6 100644
--- a/lib/Transforms/InstCombine/InstCombine.h
+++ b/lib/Transforms/InstCombine/InstCombine.h
@@ -199,11 +199,12 @@ private:
SmallVectorImpl<Value*> &NewIndices);
Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI);
- /// ValueRequiresCast - Return true if the cast from "V to Ty" actually
- /// results in any code being generated. It does not require codegen if V is
- /// simple enough or if the cast can be folded into other casts.
- bool ValueRequiresCast(Instruction::CastOps opcode,const Value *V,
- const Type *Ty);
+ /// ShouldOptimizeCast - Return true if the cast from "V to Ty" actually
+ /// results in any code being generated and is interesting to optimize out. If
+ /// the cast can be eliminated by some other simple transformation, we prefer
+ /// to do the simplification first.
+ bool ShouldOptimizeCast(Instruction::CastOps opcode,const Value *V,
+ const Type *Ty);
Instruction *visitCallSite(CallSite CS);
bool transformConstExprCastCall(CallSite CS);
diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 4891ff0..2da17f1 100644
--- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -35,7 +35,7 @@ static Constant *SubOne(ConstantInt *C) {
// Otherwise, return null.
//
static inline Value *dyn_castFoldableMul(Value *V, ConstantInt *&CST) {
- if (!V->hasOneUse() || !V->getType()->isInteger())
+ if (!V->hasOneUse() || !V->getType()->isIntegerTy())
return 0;
Instruction *I = dyn_cast<Instruction>(V);
@@ -121,50 +121,34 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) {
uint32_t TySizeBits = I.getType()->getScalarSizeInBits();
const APInt& RHSVal = cast<ConstantInt>(RHSC)->getValue();
-
- uint32_t Size = TySizeBits / 2;
- APInt C0080Val(APInt(TySizeBits, 1ULL).shl(Size - 1));
- APInt CFF80Val(-C0080Val);
- do {
- if (TySizeBits > Size) {
- // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext.
- // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext.
- if ((RHSVal == CFF80Val && XorRHS->getValue() == C0080Val) ||
- (RHSVal == C0080Val && XorRHS->getValue() == CFF80Val)) {
- // This is a sign extend if the top bits are known zero.
- if (!MaskedValueIsZero(XorLHS,
- APInt::getHighBitsSet(TySizeBits, TySizeBits - Size)))
- Size = 0; // Not a sign ext, but can't be any others either.
- break;
- }
- }
- Size >>= 1;
- C0080Val = APIntOps::lshr(C0080Val, Size);
- CFF80Val = APIntOps::ashr(CFF80Val, Size);
- } while (Size >= 1);
-
- // FIXME: This shouldn't be necessary. When the backends can handle types
- // with funny bit widths then this switch statement should be removed. It
- // is just here to get the size of the "middle" type back up to something
- // that the back ends can handle.
- const Type *MiddleType = 0;
- switch (Size) {
- default: break;
- case 32:
- case 16:
- case 8: MiddleType = IntegerType::get(I.getContext(), Size); break;
+ unsigned ExtendAmt = 0;
+ // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext.
+ // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext.
+ if (XorRHS->getValue() == -RHSVal) {
+ if (RHSVal.isPowerOf2())
+ ExtendAmt = TySizeBits - RHSVal.logBase2() - 1;
+ else if (XorRHS->getValue().isPowerOf2())
+ ExtendAmt = TySizeBits - XorRHS->getValue().logBase2() - 1;
+ }
+
+ if (ExtendAmt) {
+ APInt Mask = APInt::getHighBitsSet(TySizeBits, ExtendAmt);
+ if (!MaskedValueIsZero(XorLHS, Mask))
+ ExtendAmt = 0;
}
- if (MiddleType) {
- Value *NewTrunc = Builder->CreateTrunc(XorLHS, MiddleType, "sext");
- return new SExtInst(NewTrunc, I.getType(), I.getName());
+
+ if (ExtendAmt) {
+ Constant *ShAmt = ConstantInt::get(I.getType(), ExtendAmt);
+ Value *NewShl = Builder->CreateShl(XorLHS, ShAmt, "sext");
+ return BinaryOperator::CreateAShr(NewShl, ShAmt);
}
}
}
- if (I.getType()->isInteger(1))
+ if (I.getType()->isIntegerTy(1))
return BinaryOperator::CreateXor(LHS, RHS);
- if (I.getType()->isInteger()) {
+ if (I.getType()->isIntegerTy()) {
// X + X --> X << 1
if (LHS == RHS)
return BinaryOperator::CreateShl(LHS, ConstantInt::get(I.getType(), 1));
@@ -184,7 +168,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
// -A + B --> B - A
// -A + -B --> -(A + B)
if (Value *LHSV = dyn_castNegVal(LHS)) {
- if (LHS->getType()->isIntOrIntVector()) {
+ if (LHS->getType()->isIntOrIntVectorTy()) {
if (Value *RHSV = dyn_castNegVal(RHS)) {
Value *NewAdd = Builder->CreateAdd(LHSV, RHSV, "sum");
return BinaryOperator::CreateNeg(NewAdd);
@@ -238,7 +222,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
}
// W*X + Y*Z --> W * (X+Z) iff W == Y
- if (I.getType()->isIntOrIntVector()) {
+ if (I.getType()->isIntOrIntVectorTy()) {
Value *W, *X, *Y, *Z;
if (match(LHS, m_Mul(m_Value(W), m_Value(X))) &&
match(RHS, m_Mul(m_Value(Y), m_Value(Z)))) {
@@ -576,7 +560,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
return ReplaceInstUsesWith(I, Op0); // undef - X -> undef
if (isa<UndefValue>(Op1))
return ReplaceInstUsesWith(I, Op1); // X - undef -> undef
- if (I.getType()->isInteger(1))
+ if (I.getType()->isIntegerTy(1))
return BinaryOperator::CreateXor(Op0, Op1);
if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) {
@@ -676,6 +660,13 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
return BinaryOperator::CreateSDiv(Op1I->getOperand(0),
ConstantExpr::getNeg(DivRHS));
+ // 0 - (C << X) -> (-C << X)
+ if (Op1I->getOpcode() == Instruction::Shl)
+ if (ConstantInt *CSI = dyn_cast<ConstantInt>(Op0))
+ if (CSI->isZero())
+ if (Value *ShlLHSNeg = dyn_castNegVal(Op1I->getOperand(0)))
+ return BinaryOperator::CreateShl(ShlLHSNeg, Op1I->getOperand(1));
+
// X - X*C --> X * (1-C)
ConstantInt *C2 = 0;
if (dyn_castFoldableMul(Op1I, C2) == Op0) {
diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index fa7bb12..5e47953 100644
--- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -546,7 +546,7 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
std::swap(LHSCC, RHSCC);
}
- // At this point, we know we have have two icmp instructions
+ // At this point, we know we have two icmp instructions
// comparing a value against two constants and and'ing the result
// together. Because of the above check, we know that we only have
// icmp eq, icmp ne, icmp [su]lt, and icmp [SU]gt here. We also know
@@ -932,24 +932,49 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0))
if (Instruction *Res = FoldAndOfICmps(I, LHS, RHS))
return Res;
-
+
+ // If and'ing two fcmp, try combine them into one.
+ if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0)))
+ if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1)))
+ if (Instruction *Res = FoldAndOfFCmps(I, LHS, RHS))
+ return Res;
+
+
// fold (and (cast A), (cast B)) -> (cast (and A, B))
if (CastInst *Op0C = dyn_cast<CastInst>(Op0))
- if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
- if (Op0C->getOpcode() == Op1C->getOpcode()) { // same cast kind ?
- const Type *SrcTy = Op0C->getOperand(0)->getType();
- if (SrcTy == Op1C->getOperand(0)->getType() &&
- SrcTy->isIntOrIntVector() &&
- // Only do this if the casts both really cause code to be generated.
- ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0),
- I.getType()) &&
- ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0),
- I.getType())) {
- Value *NewOp = Builder->CreateAnd(Op0C->getOperand(0),
- Op1C->getOperand(0), I.getName());
+ if (CastInst *Op1C = dyn_cast<CastInst>(Op1)) {
+ const Type *SrcTy = Op0C->getOperand(0)->getType();
+ if (Op0C->getOpcode() == Op1C->getOpcode() && // same cast kind ?
+ SrcTy == Op1C->getOperand(0)->getType() &&
+ SrcTy->isIntOrIntVectorTy()) {
+ Value *Op0COp = Op0C->getOperand(0), *Op1COp = Op1C->getOperand(0);
+
+ // Only do this if the casts both really cause code to be generated.
+ if (ShouldOptimizeCast(Op0C->getOpcode(), Op0COp, I.getType()) &&
+ ShouldOptimizeCast(Op1C->getOpcode(), Op1COp, I.getType())) {
+ Value *NewOp = Builder->CreateAnd(Op0COp, Op1COp, I.getName());
return CastInst::Create(Op0C->getOpcode(), NewOp, I.getType());
}
+
+ // If this is and(cast(icmp), cast(icmp)), try to fold this even if the
+ // cast is otherwise not optimizable. This happens for vector sexts.
+ if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1COp))
+ if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0COp))
+ if (Instruction *Res = FoldAndOfICmps(I, LHS, RHS)) {
+ InsertNewInstBefore(Res, I);
+ return CastInst::Create(Op0C->getOpcode(), Res, I.getType());
+ }
+
+ // If this is and(cast(fcmp), cast(fcmp)), try to fold this even if the
+ // cast is otherwise not optimizable. This happens for vector sexts.
+ if (FCmpInst *RHS = dyn_cast<FCmpInst>(Op1COp))
+ if (FCmpInst *LHS = dyn_cast<FCmpInst>(Op0COp))
+ if (Instruction *Res = FoldAndOfFCmps(I, LHS, RHS)) {
+ InsertNewInstBefore(Res, I);
+ return CastInst::Create(Op0C->getOpcode(), Res, I.getType());
+ }
}
+ }
// (X >> Z) & (Y >> Z) -> (X&Y) >> Z for all shifts.
if (BinaryOperator *SI1 = dyn_cast<BinaryOperator>(Op1)) {
@@ -965,13 +990,6 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
}
}
- // If and'ing two fcmp, try combine them into one.
- if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0))) {
- if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1)))
- if (Instruction *Res = FoldAndOfFCmps(I, LHS, RHS))
- return Res;
- }
-
return Changed ? &I : 0;
}
@@ -1142,18 +1160,20 @@ static Instruction *MatchSelectFromAndOr(Value *A, Value *B,
Value *C, Value *D) {
// If A is not a select of -1/0, this cannot match.
Value *Cond = 0;
- if (!match(A, m_SelectCst<-1, 0>(m_Value(Cond))))
+ if (!match(A, m_SExt(m_Value(Cond))) ||
+ !Cond->getType()->isIntegerTy(1))
return 0;
// ((cond?-1:0)&C) | (B&(cond?0:-1)) -> cond ? C : B.
- if (match(D, m_SelectCst<0, -1>(m_Specific(Cond))))
+ if (match(D, m_Not(m_SExt(m_Specific(Cond)))))
return SelectInst::Create(Cond, C, B);
- if (match(D, m_Not(m_SelectCst<-1, 0>(m_Specific(Cond)))))
+ if (match(D, m_SExt(m_Not(m_Specific(Cond)))))
return SelectInst::Create(Cond, C, B);
+
// ((cond?-1:0)&C) | ((cond?0:-1)&D) -> cond ? C : D.
- if (match(B, m_SelectCst<0, -1>(m_Specific(Cond))))
+ if (match(B, m_Not(m_SExt(m_Specific(Cond)))))
return SelectInst::Create(Cond, C, D);
- if (match(B, m_Not(m_SelectCst<-1, 0>(m_Specific(Cond)))))
+ if (match(B, m_SExt(m_Not(m_Specific(Cond)))))
return SelectInst::Create(Cond, C, D);
return 0;
}
@@ -1224,7 +1244,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
std::swap(LHSCC, RHSCC);
}
- // At this point, we know we have have two icmp instructions
+ // At this point, we know we have two icmp instructions
// comparing a value against two constants and or'ing the result
// together. Because of the above check, we know that we only have
// ICMP_EQ, ICMP_NE, ICMP_LT, and ICMP_GT here. We also know (from the
@@ -1595,15 +1615,19 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
}
}
- // (A & (C0?-1:0)) | (B & ~(C0?-1:0)) -> C0 ? A : B, and commuted variants
- if (Instruction *Match = MatchSelectFromAndOr(A, B, C, D))
- return Match;
- if (Instruction *Match = MatchSelectFromAndOr(B, A, D, C))
- return Match;
- if (Instruction *Match = MatchSelectFromAndOr(C, B, A, D))
- return Match;
- if (Instruction *Match = MatchSelectFromAndOr(D, A, B, C))
- return Match;
+ // (A & (C0?-1:0)) | (B & ~(C0?-1:0)) -> C0 ? A : B, and commuted variants.
+ // Don't do this for vector select idioms, the code generator doesn't handle
+ // them well yet.
+ if (!isa<VectorType>(I.getType())) {
+ if (Instruction *Match = MatchSelectFromAndOr(A, B, C, D))
+ return Match;
+ if (Instruction *Match = MatchSelectFromAndOr(B, A, D, C))
+ return Match;
+ if (Instruction *Match = MatchSelectFromAndOr(C, B, A, D))
+ return Match;
+ if (Instruction *Match = MatchSelectFromAndOr(D, A, B, C))
+ return Match;
+ }
// ((A&~B)|(~A&B)) -> A^B
if ((match(C, m_Not(m_Specific(D))) &&
@@ -1663,37 +1687,51 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
if (Instruction *Res = FoldOrOfICmps(I, LHS, RHS))
return Res;
+ // (fcmp uno x, c) | (fcmp uno y, c) -> (fcmp uno x, y)
+ if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0)))
+ if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1)))
+ if (Instruction *Res = FoldOrOfFCmps(I, LHS, RHS))
+ return Res;
+
// fold (or (cast A), (cast B)) -> (cast (or A, B))
if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
if (Op0C->getOpcode() == Op1C->getOpcode()) {// same cast kind ?
- if (!isa<ICmpInst>(Op0C->getOperand(0)) ||
- !isa<ICmpInst>(Op1C->getOperand(0))) {
- const Type *SrcTy = Op0C->getOperand(0)->getType();
- if (SrcTy == Op1C->getOperand(0)->getType() &&
- SrcTy->isIntOrIntVector() &&
+ const Type *SrcTy = Op0C->getOperand(0)->getType();
+ if (SrcTy == Op1C->getOperand(0)->getType() &&
+ SrcTy->isIntOrIntVectorTy()) {
+ Value *Op0COp = Op0C->getOperand(0), *Op1COp = Op1C->getOperand(0);
+
+ if ((!isa<ICmpInst>(Op0COp) || !isa<ICmpInst>(Op1COp)) &&
// Only do this if the casts both really cause code to be
// generated.
- ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0),
- I.getType()) &&
- ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0),
- I.getType())) {
- Value *NewOp = Builder->CreateOr(Op0C->getOperand(0),
- Op1C->getOperand(0), I.getName());
+ ShouldOptimizeCast(Op0C->getOpcode(), Op0COp, I.getType()) &&
+ ShouldOptimizeCast(Op1C->getOpcode(), Op1COp, I.getType())) {
+ Value *NewOp = Builder->CreateOr(Op0COp, Op1COp, I.getName());
return CastInst::Create(Op0C->getOpcode(), NewOp, I.getType());
}
+
+ // If this is or(cast(icmp), cast(icmp)), try to fold this even if the
+ // cast is otherwise not optimizable. This happens for vector sexts.
+ if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1COp))
+ if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0COp))
+ if (Instruction *Res = FoldOrOfICmps(I, LHS, RHS)) {
+ InsertNewInstBefore(Res, I);
+ return CastInst::Create(Op0C->getOpcode(), Res, I.getType());
+ }
+
+ // If this is or(cast(fcmp), cast(fcmp)), try to fold this even if the
+ // cast is otherwise not optimizable. This happens for vector sexts.
+ if (FCmpInst *RHS = dyn_cast<FCmpInst>(Op1COp))
+ if (FCmpInst *LHS = dyn_cast<FCmpInst>(Op0COp))
+ if (Instruction *Res = FoldOrOfFCmps(I, LHS, RHS)) {
+ InsertNewInstBefore(Res, I);
+ return CastInst::Create(Op0C->getOpcode(), Res, I.getType());
+ }
}
}
}
-
- // (fcmp uno x, c) | (fcmp uno y, c) -> (fcmp uno x, y)
- if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0))) {
- if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1)))
- if (Instruction *Res = FoldOrOfFCmps(I, LHS, RHS))
- return Res;
- }
-
return Changed ? &I : 0;
}
@@ -1978,12 +2016,12 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
if (Op0C->getOpcode() == Op1C->getOpcode()) { // same cast kind?
const Type *SrcTy = Op0C->getOperand(0)->getType();
- if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isInteger() &&
+ if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegerTy() &&
// Only do this if the casts both really cause code to be generated.
- ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0),
- I.getType()) &&
- ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0),
- I.getType())) {
+ ShouldOptimizeCast(Op0C->getOpcode(), Op0C->getOperand(0),
+ I.getType()) &&
+ ShouldOptimizeCast(Op1C->getOpcode(), Op1C->getOperand(0),
+ I.getType())) {
Value *NewOp = Builder->CreateXor(Op0C->getOperand(0),
Op1C->getOperand(0), I.getName());
return CastInst::Create(Op0C->getOpcode(), NewOp, I.getType());
diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 47c37c4..d7efdcf 100644
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -199,7 +199,7 @@ Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) {
// Extract the length and alignment and fill if they are constant.
ConstantInt *LenC = dyn_cast<ConstantInt>(MI->getLength());
ConstantInt *FillC = dyn_cast<ConstantInt>(MI->getValue());
- if (!LenC || !FillC || !FillC->getType()->isInteger(8))
+ if (!LenC || !FillC || !FillC->getType()->isIntegerTy(8))
return 0;
uint64_t Len = LenC->getZExtValue();
Alignment = MI->getAlignment();
@@ -230,7 +230,6 @@ Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) {
return 0;
}
-
/// visitCallInst - CallInst simplification. This mostly only handles folding
/// of intrinsic instructions. For normal calls, it allows visitCallSite to do
/// the heavy lifting.
@@ -304,6 +303,60 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
switch (II->getIntrinsicID()) {
default: break;
+ case Intrinsic::objectsize: {
+ const Type *ReturnTy = CI.getType();
+ Value *Op1 = II->getOperand(1);
+ bool Min = (cast<ConstantInt>(II->getOperand(2))->getZExtValue() == 1);
+
+ // We need target data for just about everything so depend on it.
+ if (!TD) break;
+
+ // Get to the real allocated thing and offset as fast as possible.
+ Op1 = Op1->stripPointerCasts();
+
+ // If we've stripped down to a single global variable that we
+ // can know the size of then just return that.
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op1)) {
+ if (GV->hasDefinitiveInitializer()) {
+ Constant *C = GV->getInitializer();
+ size_t globalSize = TD->getTypeAllocSize(C->getType());
+ return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, globalSize));
+ } else {
+ Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL);
+ return ReplaceInstUsesWith(CI, RetVal);
+ }
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op1)) {
+
+ // Only handle constant GEPs here.
+ if (CE->getOpcode() != Instruction::GetElementPtr) break;
+ GEPOperator *GEP = cast<GEPOperator>(CE);
+
+ // Make sure we're not a constant offset from an external
+ // global.
+ Value *Operand = GEP->getPointerOperand();
+ Operand = Operand->stripPointerCasts();
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Operand))
+ if (!GV->hasDefinitiveInitializer()) break;
+
+ // Get what we're pointing to and its size.
+ const PointerType *BaseType =
+ cast<PointerType>(Operand->getType());
+ size_t Size = TD->getTypeAllocSize(BaseType->getElementType());
+
+ // Get the current byte offset into the thing. Use the original
+ // operand in case we're looking through a bitcast.
+ SmallVector<Value*, 8> Ops(CE->op_begin()+1, CE->op_end());
+ const PointerType *OffsetType =
+ cast<PointerType>(GEP->getPointerOperand()->getType());
+ size_t Offset = TD->getIndexedOffset(OffsetType, &Ops[0], Ops.size());
+
+ assert(Size >= Offset);
+
+ Constant *RetVal = ConstantInt::get(ReturnTy, Size-Offset);
+ return ReplaceInstUsesWith(CI, RetVal);
+
+ }
+ }
case Intrinsic::bswap:
// bswap(bswap(x)) -> x
if (IntrinsicInst *Operand = dyn_cast<IntrinsicInst>(II->getOperand(1)))
@@ -632,18 +685,6 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
return EraseInstFromFunction(CI);
break;
}
- case Intrinsic::objectsize: {
- ConstantInt *Const = cast<ConstantInt>(II->getOperand(2));
- const Type *Ty = CI.getType();
-
- // 0 is maximum number of bytes left, 1 is minimum number of bytes left.
- // TODO: actually add these values, the current return values are "don't
- // know".
- if (Const->getZExtValue() == 0)
- return ReplaceInstUsesWith(CI, Constant::getAllOnesValue(Ty));
- else
- return ReplaceInstUsesWith(CI, ConstantInt::get(Ty, 0));
- }
}
return visitCallSite(II);
@@ -692,10 +733,14 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) {
Value *Callee = CS.getCalledValue();
if (Function *CalleeF = dyn_cast<Function>(Callee))
- if (CalleeF->getCallingConv() != CS.getCallingConv()) {
+ // If the call and callee calling conventions don't match, this call must
+ // be unreachable, as the call is undefined.
+ if (CalleeF->getCallingConv() != CS.getCallingConv() &&
+ // Only do this for calls to a function with a body. A prototype may
+ // not actually end up matching the implementation's calling conv for a
+ // variety of reasons (e.g. it may be written in assembly).
+ !CalleeF->isDeclaration()) {
Instruction *OldCall = CS.getInstruction();
- // If the call and callee calling conventions don't match, this call must
- // be unreachable, as the call is undefined.
new StoreInst(ConstantInt::getTrue(Callee->getContext()),
UndefValue::get(Type::getInt1PtrTy(Callee->getContext())),
OldCall);
@@ -703,8 +748,13 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) {
// This allows ValueHandlers and custom metadata to adjust itself.
if (!OldCall->getType()->isVoidTy())
OldCall->replaceAllUsesWith(UndefValue::get(OldCall->getType()));
- if (isa<CallInst>(OldCall)) // Not worth removing an invoke here.
+ if (isa<CallInst>(OldCall))
return EraseInstFromFunction(*OldCall);
+
+ // We cannot remove an invoke, because it would change the CFG, just
+ // change the callee to a null pointer.
+ cast<InvokeInst>(OldCall)->setOperand(0,
+ Constant::getNullValue(CalleeF->getType()));
return 0;
}
diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp
index f25dd35..bb4a0e9 100644
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -23,7 +23,7 @@ using namespace PatternMatch;
///
static Value *DecomposeSimpleLinearExpr(Value *Val, unsigned &Scale,
int &Offset) {
- assert(Val->getType()->isInteger(32) && "Unexpected allocation size type!");
+ assert(Val->getType()->isIntegerTy(32) && "Unexpected allocation size type!");
if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
Offset = CI->getZExtValue();
Scale = 0;
@@ -255,17 +255,26 @@ isEliminableCastPair(
return Instruction::CastOps(Res);
}
-/// ValueRequiresCast - Return true if the cast from "V to Ty" actually results
-/// in any code being generated. It does not require codegen if V is simple
-/// enough or if the cast can be folded into other casts.
-bool InstCombiner::ValueRequiresCast(Instruction::CastOps opcode,const Value *V,
- const Type *Ty) {
+/// ShouldOptimizeCast - Return true if the cast from "V to Ty" actually
+/// results in any code being generated and is interesting to optimize out. If
+/// the cast can be eliminated by some other simple transformation, we prefer
+/// to do the simplification first.
+bool InstCombiner::ShouldOptimizeCast(Instruction::CastOps opc, const Value *V,
+ const Type *Ty) {
+ // Noop casts and casts of constants should be eliminated trivially.
if (V->getType() == Ty || isa<Constant>(V)) return false;
- // If this is another cast that can be eliminated, it isn't codegen either.
+ // If this is another cast that can be eliminated, we prefer to have it
+ // eliminated.
if (const CastInst *CI = dyn_cast<CastInst>(V))
- if (isEliminableCastPair(CI, opcode, Ty, TD))
+ if (isEliminableCastPair(CI, opc, Ty, TD))
return false;
+
+ // If this is a vector sext from a compare, then we don't want to break the
+ // idiom where each element of the extended vector is either zero or all ones.
+ if (opc == Instruction::SExt && isa<CmpInst>(V) && isa<VectorType>(Ty))
+ return false;
+
return true;
}
@@ -828,7 +837,7 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
// zext (xor i1 X, true) to i32 --> xor (zext i1 X to i32), 1
Value *X;
- if (SrcI && SrcI->hasOneUse() && SrcI->getType()->isInteger(1) &&
+ if (SrcI && SrcI->hasOneUse() && SrcI->getType()->isIntegerTy(1) &&
match(SrcI, m_Not(m_Value(X))) &&
(!X->hasOneUse() || !isa<CmpInst>(X))) {
Value *New = Builder->CreateZExt(X, CI.getType());
@@ -923,12 +932,6 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
Value *Src = CI.getOperand(0);
const Type *SrcTy = Src->getType(), *DestTy = CI.getType();
- // Canonicalize sign-extend from i1 to a select.
- if (Src->getType()->isInteger(1))
- return SelectInst::Create(Src,
- Constant::getAllOnesValue(CI.getType()),
- Constant::getNullValue(CI.getType()));
-
// Attempt to extend the entire input expression tree to the destination
// type. Only do this if the dest type is a simple type, don't convert the
// expression tree to something weird like i93 unless the source is also
@@ -968,6 +971,30 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
return BinaryOperator::CreateAShr(Res, ShAmt);
}
+
+ // (x <s 0) ? -1 : 0 -> ashr x, 31 -> all ones if signed
+ // (x >s -1) ? -1 : 0 -> ashr x, 31 -> all ones if not signed
+ {
+ ICmpInst::Predicate Pred; Value *CmpLHS; ConstantInt *CmpRHS;
+ if (match(Src, m_ICmp(Pred, m_Value(CmpLHS), m_ConstantInt(CmpRHS)))) {
+ // sext (x <s 0) to i32 --> x>>s31 true if signbit set.
+ // sext (x >s -1) to i32 --> (x>>s31)^-1 true if signbit clear.
+ if ((Pred == ICmpInst::ICMP_SLT && CmpRHS->isZero()) ||
+ (Pred == ICmpInst::ICMP_SGT && CmpRHS->isAllOnesValue())) {
+ Value *Sh = ConstantInt::get(CmpLHS->getType(),
+ CmpLHS->getType()->getScalarSizeInBits()-1);
+ Value *In = Builder->CreateAShr(CmpLHS, Sh, CmpLHS->getName()+".lobit");
+ if (In->getType() != CI.getType())
+ In = Builder->CreateIntCast(In, CI.getType(), true/*SExt*/, "tmp");
+
+ if (Pred == ICmpInst::ICMP_SGT)
+ In = Builder->CreateNot(In, In->getName()+".not");
+ return ReplaceInstUsesWith(CI, In);
+ }
+ }
+ }
+
+
// If the input is a shl/ashr pair of a same constant, then this is a sign
// extension from a smaller value. If we could trust arbitrary bitwidth
// integers, we could turn this into a truncate to the smaller bit and then
@@ -1127,16 +1154,22 @@ Instruction *InstCombiner::visitSIToFP(CastInst &CI) {
}
Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) {
- // If the source integer type is larger than the intptr_t type for
- // this target, do a trunc to the intptr_t type, then inttoptr of it. This
- // allows the trunc to be exposed to other transforms. Don't do this for
- // extending inttoptr's, because we don't know if the target sign or zero
- // extends to pointers.
- if (TD && CI.getOperand(0)->getType()->getScalarSizeInBits() >
- TD->getPointerSizeInBits()) {
- Value *P = Builder->CreateTrunc(CI.getOperand(0),
- TD->getIntPtrType(CI.getContext()), "tmp");
- return new IntToPtrInst(P, CI.getType());
+ // If the source integer type is not the intptr_t type for this target, do a
+ // trunc or zext to the intptr_t type, then inttoptr of it. This allows the
+ // cast to be exposed to other transforms.
+ if (TD) {
+ if (CI.getOperand(0)->getType()->getScalarSizeInBits() >
+ TD->getPointerSizeInBits()) {
+ Value *P = Builder->CreateTrunc(CI.getOperand(0),
+ TD->getIntPtrType(CI.getContext()), "tmp");
+ return new IntToPtrInst(P, CI.getType());
+ }
+ if (CI.getOperand(0)->getType()->getScalarSizeInBits() <
+ TD->getPointerSizeInBits()) {
+ Value *P = Builder->CreateZExt(CI.getOperand(0),
+ TD->getIntPtrType(CI.getContext()), "tmp");
+ return new IntToPtrInst(P, CI.getType());
+ }
}
if (Instruction *I = commonCastTransforms(CI))
@@ -1198,17 +1231,22 @@ Instruction *InstCombiner::commonPointerCastTransforms(CastInst &CI) {
}
Instruction *InstCombiner::visitPtrToInt(PtrToIntInst &CI) {
- // If the destination integer type is smaller than the intptr_t type for
- // this target, do a ptrtoint to intptr_t then do a trunc. This allows the
- // trunc to be exposed to other transforms. Don't do this for extending
- // ptrtoint's, because we don't know if the target sign or zero extends its
- // pointers.
- if (TD &&
- CI.getType()->getScalarSizeInBits() < TD->getPointerSizeInBits()) {
- Value *P = Builder->CreatePtrToInt(CI.getOperand(0),
- TD->getIntPtrType(CI.getContext()),
- "tmp");
- return new TruncInst(P, CI.getType());
+ // If the destination integer type is not the intptr_t type for this target,
+ // do a ptrtoint to intptr_t then do a trunc or zext. This allows the cast
+ // to be exposed to other transforms.
+ if (TD) {
+ if (CI.getType()->getScalarSizeInBits() < TD->getPointerSizeInBits()) {
+ Value *P = Builder->CreatePtrToInt(CI.getOperand(0),
+ TD->getIntPtrType(CI.getContext()),
+ "tmp");
+ return new TruncInst(P, CI.getType());
+ }
+ if (CI.getType()->getScalarSizeInBits() > TD->getPointerSizeInBits()) {
+ Value *P = Builder->CreatePtrToInt(CI.getOperand(0),
+ TD->getIntPtrType(CI.getContext()),
+ "tmp");
+ return new ZExtInst(P, CI.getType());
+ }
}
return commonPointerCastTransforms(CI);
diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp
index e59406c6..72af80f 100644
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1589,24 +1589,24 @@ Instruction *InstCombiner::visitICmpInstWithCastAndCast(ICmpInst &ICI) {
Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
bool Changed = false;
+ Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
/// Orders the operands of the compare so that they are listed from most
/// complex to least complex. This puts constants before unary operators,
/// before binary operators.
- if (getComplexity(I.getOperand(0)) < getComplexity(I.getOperand(1))) {
+ if (getComplexity(Op0) < getComplexity(Op1)) {
I.swapOperands();
+ std::swap(Op0, Op1);
Changed = true;
}
- Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
-
if (Value *V = SimplifyICmpInst(I.getPredicate(), Op0, Op1, TD))
return ReplaceInstUsesWith(I, V);
const Type *Ty = Op0->getType();
// icmp's with boolean values can always be turned into bitwise operations
- if (Ty == Type::getInt1Ty(I.getContext())) {
+ if (Ty->isIntegerTy(1)) {
switch (I.getPredicate()) {
default: llvm_unreachable("Invalid icmp instruction!");
case ICmpInst::ICMP_EQ: { // icmp eq i1 A, B -> ~(A^B)
@@ -1650,7 +1650,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
unsigned BitWidth = 0;
if (TD)
BitWidth = TD->getTypeSizeInBits(Ty->getScalarType());
- else if (Ty->isIntOrIntVector())
+ else if (Ty->isIntOrIntVectorTy())
BitWidth = Ty->getScalarSizeInBits();
bool isSignBit = false;
diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index ae728dd..e6c59c7 100644
--- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -87,7 +87,7 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
const Type *SrcPTy = SrcTy->getElementType();
- if (DestPTy->isInteger() || isa<PointerType>(DestPTy) ||
+ if (DestPTy->isIntegerTy() || isa<PointerType>(DestPTy) ||
isa<VectorType>(DestPTy)) {
// If the source is an array, the code below will not succeed. Check to
// see if a trivial 'gep P, 0, 0' will help matters. Only do this for
@@ -104,7 +104,7 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
}
if (IC.getTargetData() &&
- (SrcPTy->isInteger() || isa<PointerType>(SrcPTy) ||
+ (SrcPTy->isIntegerTy() || isa<PointerType>(SrcPTy) ||
isa<VectorType>(SrcPTy)) &&
// Do not allow turning this into a load of an integer, which is then
// casted to a pointer, this pessimizes pointer analysis a lot.
@@ -115,8 +115,9 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
// Okay, we are casting from one integer or pointer type to another of
// the same size. Instead of casting the pointer before the load, cast
// the result of the loaded value.
- Value *NewLoad =
+ LoadInst *NewLoad =
IC.Builder->CreateLoad(CastOp, LI.isVolatile(), CI->getName());
+ NewLoad->setAlignment(LI.getAlignment());
// Now cast the result of the load.
return new BitCastInst(NewLoad, LI.getType());
}
@@ -199,12 +200,15 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
//
if (SelectInst *SI = dyn_cast<SelectInst>(Op)) {
// load (select (Cond, &V1, &V2)) --> select(Cond, load &V1, load &V2).
- if (isSafeToLoadUnconditionally(SI->getOperand(1), SI) &&
- isSafeToLoadUnconditionally(SI->getOperand(2), SI)) {
- Value *V1 = Builder->CreateLoad(SI->getOperand(1),
- SI->getOperand(1)->getName()+".val");
- Value *V2 = Builder->CreateLoad(SI->getOperand(2),
- SI->getOperand(2)->getName()+".val");
+ unsigned Align = LI.getAlignment();
+ if (isSafeToLoadUnconditionally(SI->getOperand(1), SI, Align, TD) &&
+ isSafeToLoadUnconditionally(SI->getOperand(2), SI, Align, TD)) {
+ LoadInst *V1 = Builder->CreateLoad(SI->getOperand(1),
+ SI->getOperand(1)->getName()+".val");
+ LoadInst *V2 = Builder->CreateLoad(SI->getOperand(2),
+ SI->getOperand(2)->getName()+".val");
+ V1->setAlignment(Align);
+ V2->setAlignment(Align);
return SelectInst::Create(SI->getCondition(), V1, V2);
}
@@ -239,7 +243,7 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
const Type *SrcPTy = SrcTy->getElementType();
- if (!DestPTy->isInteger() && !isa<PointerType>(DestPTy))
+ if (!DestPTy->isIntegerTy() && !isa<PointerType>(DestPTy))
return 0;
/// NewGEPIndices - If SrcPTy is an aggregate type, we can emit a "noop gep"
@@ -273,7 +277,7 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
SrcTy = PointerType::get(SrcPTy, SrcTy->getAddressSpace());
}
- if (!SrcPTy->isInteger() && !isa<PointerType>(SrcPTy))
+ if (!SrcPTy->isIntegerTy() && !isa<PointerType>(SrcPTy))
return 0;
// If the pointers point into different address spaces or if they point to
@@ -294,7 +298,7 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
const Type* CastSrcTy = SIOp0->getType();
const Type* CastDstTy = SrcPTy;
if (isa<PointerType>(CastDstTy)) {
- if (CastSrcTy->isInteger())
+ if (CastSrcTy->isIntegerTy())
opcode = Instruction::IntToPtr;
} else if (isa<IntegerType>(CastDstTy)) {
if (isa<PointerType>(SIOp0->getType()))
diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 2e26a75..668c34f 100644
--- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -157,7 +157,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
}
/// i1 mul -> i1 and.
- if (I.getType()->isInteger(1))
+ if (I.getType()->isIntegerTy(1))
return BinaryOperator::CreateAnd(Op0, Op1);
// X*(1 << Y) --> X << Y
@@ -314,7 +314,7 @@ Instruction *InstCombiner::commonDivTransforms(BinaryOperator &I) {
// undef / X -> 0 for integer.
// undef / X -> undef for FP (the undef could be a snan).
if (isa<UndefValue>(Op0)) {
- if (Op0->getType()->isFPOrFPVector())
+ if (Op0->getType()->isFPOrFPVectorTy())
return ReplaceInstUsesWith(I, Op0);
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
}
@@ -386,7 +386,7 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
// It can't be division by zero, hence it must be division by one.
- if (I.getType()->isInteger(1))
+ if (I.getType()->isIntegerTy(1))
return ReplaceInstUsesWith(I, Op0);
if (ConstantVector *Op1V = dyn_cast<ConstantVector>(Op1)) {
@@ -493,7 +493,7 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
// If the sign bits of both operands are zero (i.e. we can prove they are
// unsigned inputs), turn this into a udiv.
- if (I.getType()->isInteger()) {
+ if (I.getType()->isIntegerTy()) {
APInt Mask(APInt::getSignBit(I.getType()->getPrimitiveSizeInBits()));
if (MaskedValueIsZero(Op0, Mask)) {
if (MaskedValueIsZero(Op1, Mask)) {
@@ -527,7 +527,7 @@ Instruction *InstCombiner::commonRemTransforms(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
if (isa<UndefValue>(Op0)) { // undef % X -> 0
- if (I.getType()->isFPOrFPVector())
+ if (I.getType()->isFPOrFPVectorTy())
return ReplaceInstUsesWith(I, Op0); // X % undef -> undef (could be SNaN)
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
}
@@ -648,7 +648,7 @@ Instruction *InstCombiner::visitSRem(BinaryOperator &I) {
// If the sign bits of both operands are zero (i.e. we can prove they are
// unsigned inputs), turn this into a urem.
- if (I.getType()->isInteger()) {
+ if (I.getType()->isIntegerTy()) {
APInt Mask(APInt::getSignBit(I.getType()->getPrimitiveSizeInBits()));
if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
// X srem Y -> X urem Y, iff X and Y don't have sign bit set
diff --git a/lib/Transforms/InstCombine/InstCombineSelect.cpp b/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 18b2dff..7807d9a 100644
--- a/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -326,44 +326,6 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
break;
}
}
-
- // (x <s 0) ? -1 : 0 -> ashr x, 31 -> all ones if signed
- // (x >s -1) ? -1 : 0 -> ashr x, 31 -> all ones if not signed
- CmpInst::Predicate Pred = CmpInst::BAD_ICMP_PREDICATE;
- if (match(TrueVal, m_ConstantInt<-1>()) &&
- match(FalseVal, m_ConstantInt<0>()))
- Pred = ICI->getPredicate();
- else if (match(TrueVal, m_ConstantInt<0>()) &&
- match(FalseVal, m_ConstantInt<-1>()))
- Pred = CmpInst::getInversePredicate(ICI->getPredicate());
-
- if (Pred != CmpInst::BAD_ICMP_PREDICATE) {
- // If we are just checking for a icmp eq of a single bit and zext'ing it
- // to an integer, then shift the bit to the appropriate place and then
- // cast to integer to avoid the comparison.
- const APInt &Op1CV = CI->getValue();
-
- // sext (x <s 0) to i32 --> x>>s31 true if signbit set.
- // sext (x >s -1) to i32 --> (x>>s31)^-1 true if signbit clear.
- if ((Pred == ICmpInst::ICMP_SLT && Op1CV == 0) ||
- (Pred == ICmpInst::ICMP_SGT && Op1CV.isAllOnesValue())) {
- Value *In = ICI->getOperand(0);
- Value *Sh = ConstantInt::get(In->getType(),
- In->getType()->getScalarSizeInBits()-1);
- In = InsertNewInstBefore(BinaryOperator::CreateAShr(In, Sh,
- In->getName()+".lobit"),
- *ICI);
- if (In->getType() != SI.getType())
- In = CastInst::CreateIntegerCast(In, SI.getType(),
- true/*SExt*/, "tmp", ICI);
-
- if (Pred == ICmpInst::ICMP_SGT)
- In = InsertNewInstBefore(BinaryOperator::CreateNot(In,
- In->getName()+".not"), *ICI);
-
- return ReplaceInstUsesWith(SI, In);
- }
- }
}
if (CmpLHS == TrueVal && CmpRHS == FalseVal) {
@@ -479,7 +441,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
return ReplaceInstUsesWith(SI, FalseVal);
}
- if (SI.getType()->isInteger(1)) {
+ if (SI.getType()->isIntegerTy(1)) {
if (ConstantInt *C = dyn_cast<ConstantInt>(TrueVal)) {
if (C->getZExtValue()) {
// Change: A = select B, true, C --> A = or B, C
@@ -516,16 +478,25 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
if (ConstantInt *TrueValC = dyn_cast<ConstantInt>(TrueVal))
if (ConstantInt *FalseValC = dyn_cast<ConstantInt>(FalseVal)) {
// select C, 1, 0 -> zext C to int
- if (FalseValC->isZero() && TrueValC->getValue() == 1) {
- return CastInst::Create(Instruction::ZExt, CondVal, SI.getType());
- } else if (TrueValC->isZero() && FalseValC->getValue() == 1) {
- // select C, 0, 1 -> zext !C to int
- Value *NotCond =
- InsertNewInstBefore(BinaryOperator::CreateNot(CondVal,
- "not."+CondVal->getName()), SI);
- return CastInst::Create(Instruction::ZExt, NotCond, SI.getType());
+ if (FalseValC->isZero() && TrueValC->getValue() == 1)
+ return new ZExtInst(CondVal, SI.getType());
+
+ // select C, -1, 0 -> sext C to int
+ if (FalseValC->isZero() && TrueValC->isAllOnesValue())
+ return new SExtInst(CondVal, SI.getType());
+
+ // select C, 0, 1 -> zext !C to int
+ if (TrueValC->isZero() && FalseValC->getValue() == 1) {
+ Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName());
+ return new ZExtInst(NotCond, SI.getType());
}
+ // select C, 0, -1 -> sext !C to int
+ if (TrueValC->isZero() && FalseValC->isAllOnesValue()) {
+ Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName());
+ return new SExtInst(NotCond, SI.getType());
+ }
+
if (ICmpInst *IC = dyn_cast<ICmpInst>(SI.getCondition())) {
// If one of the constants is zero (we know they can't both be) and we
// have an icmp instruction with zero, and we have an 'and' with the
@@ -547,8 +518,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
ShouldNotVal ^= IC->getPredicate() == ICmpInst::ICMP_NE;
Value *V = ICA;
if (ShouldNotVal)
- V = InsertNewInstBefore(BinaryOperator::Create(
- Instruction::Xor, V, ICA->getOperand(1)), SI);
+ V = Builder->CreateXor(V, ICA->getOperand(1));
return ReplaceInstUsesWith(SI, V);
}
}
@@ -659,7 +629,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
}
// See if we can fold the select into one of our operands.
- if (SI.getType()->isInteger()) {
+ if (SI.getType()->isIntegerTy()) {
if (Instruction *FoldI = FoldSelectIntoOp(SI, TrueVal, FalseVal))
return FoldI;
diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 321c91d..836bda3 100644
--- a/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "InstCombine.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Support/PatternMatch.h"
using namespace llvm;
using namespace PatternMatch;
@@ -69,10 +70,9 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
if (Op1->uge(TypeBits)) {
if (I.getOpcode() != Instruction::AShr)
return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
- else {
- I.setOperand(1, ConstantInt::get(I.getType(), TypeBits-1));
- return &I;
- }
+ // ashr i32 X, 32 --> ashr i32 X, 31
+ I.setOperand(1, ConstantInt::get(I.getType(), TypeBits-1));
+ return &I;
}
// ((X*C1) << C2) == (X * (C1 << C2))
@@ -387,7 +387,29 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) {
}
Instruction *InstCombiner::visitLShr(BinaryOperator &I) {
- return commonShiftTransforms(I);
+ if (Instruction *R = commonShiftTransforms(I))
+ return R;
+
+ Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+
+ if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1))
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Op0)) {
+ unsigned BitWidth = Op0->getType()->getScalarSizeInBits();
+ // ctlz.i32(x)>>5 --> zext(x == 0)
+ // cttz.i32(x)>>5 --> zext(x == 0)
+ // ctpop.i32(x)>>5 --> zext(x == -1)
+ if ((II->getIntrinsicID() == Intrinsic::ctlz ||
+ II->getIntrinsicID() == Intrinsic::cttz ||
+ II->getIntrinsicID() == Intrinsic::ctpop) &&
+ isPowerOf2_32(BitWidth) && Log2_32(BitWidth) == Op1C->getZExtValue()){
+ bool isCtPop = II->getIntrinsicID() == Intrinsic::ctpop;
+ Constant *RHS = ConstantInt::getSigned(Op0->getType(), isCtPop ? -1:0);
+ Value *Cmp = Builder->CreateICmpEQ(II->getOperand(1), RHS);
+ return new ZExtInst(Cmp, II->getType());
+ }
+ }
+
+ return 0;
}
Instruction *InstCombiner::visitAShr(BinaryOperator &I) {
diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 74a1b68..5e9a52f 100644
--- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -107,7 +107,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
assert((TD || !isa<PointerType>(VTy)) &&
"SimplifyDemandedBits needs to know bit widths!");
assert((!TD || TD->getTypeSizeInBits(VTy->getScalarType()) == BitWidth) &&
- (!VTy->isIntOrIntVector() ||
+ (!VTy->isIntOrIntVectorTy() ||
VTy->getScalarSizeInBits() == BitWidth) &&
KnownZero.getBitWidth() == BitWidth &&
KnownOne.getBitWidth() == BitWidth &&
@@ -138,11 +138,11 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
return 0;
APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
- APInt &RHSKnownZero = KnownZero, &RHSKnownOne = KnownOne;
+ APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
Instruction *I = dyn_cast<Instruction>(V);
if (!I) {
- ComputeMaskedBits(V, DemandedMask, RHSKnownZero, RHSKnownOne, Depth);
+ ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth);
return 0; // Only analyze instructions.
}
@@ -219,7 +219,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
switch (I->getOpcode()) {
default:
- ComputeMaskedBits(I, DemandedMask, RHSKnownZero, RHSKnownOne, Depth);
+ ComputeMaskedBits(I, DemandedMask, KnownZero, KnownOne, Depth);
break;
case Instruction::And:
// If either the LHS or the RHS are Zero, the result is zero.
@@ -249,9 +249,9 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
return I;
// Output known-1 bits are only known if set in both the LHS & RHS.
- RHSKnownOne &= LHSKnownOne;
+ KnownOne = RHSKnownOne & LHSKnownOne;
// Output known-0 are known to be clear if zero in either the LHS | RHS.
- RHSKnownZero |= LHSKnownZero;
+ KnownZero = RHSKnownZero | LHSKnownZero;
break;
case Instruction::Or:
// If either the LHS or the RHS are One, the result is One.
@@ -286,9 +286,9 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
return I;
// Output known-0 bits are only known if clear in both the LHS & RHS.
- RHSKnownZero &= LHSKnownZero;
+ KnownZero = RHSKnownZero & LHSKnownZero;
// Output known-1 are known to be set if set in either the LHS | RHS.
- RHSKnownOne |= LHSKnownOne;
+ KnownOne = RHSKnownOne | LHSKnownOne;
break;
case Instruction::Xor: {
if (SimplifyDemandedBits(I->getOperandUse(1), DemandedMask,
@@ -306,13 +306,6 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
if ((DemandedMask & LHSKnownZero) == DemandedMask)
return I->getOperand(1);
- // Output known-0 bits are known if clear or set in both the LHS & RHS.
- APInt KnownZeroOut = (RHSKnownZero & LHSKnownZero) |
- (RHSKnownOne & LHSKnownOne);
- // Output known-1 are known to be set if set in only one of the LHS, RHS.
- APInt KnownOneOut = (RHSKnownZero & LHSKnownOne) |
- (RHSKnownOne & LHSKnownZero);
-
// If all of the demanded bits are known to be zero on one side or the
// other, turn this into an *inclusive* or.
// e.g. (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
@@ -368,10 +361,11 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
BinaryOperator::CreateXor(NewAnd, XorC, "tmp");
return InsertNewInstBefore(NewXor, *I);
}
-
-
- RHSKnownZero = KnownZeroOut;
- RHSKnownOne = KnownOneOut;
+
+ // Output known-0 bits are known if clear or set in both the LHS & RHS.
+ KnownZero= (RHSKnownZero & LHSKnownZero) | (RHSKnownOne & LHSKnownOne);
+ // Output known-1 are known to be set if set in only one of the LHS, RHS.
+ KnownOne = (RHSKnownZero & LHSKnownOne) | (RHSKnownOne & LHSKnownZero);
break;
}
case Instruction::Select:
@@ -389,61 +383,61 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
return I;
// Only known if known in both the LHS and RHS.
- RHSKnownOne &= LHSKnownOne;
- RHSKnownZero &= LHSKnownZero;
+ KnownOne = RHSKnownOne & LHSKnownOne;
+ KnownZero = RHSKnownZero & LHSKnownZero;
break;
case Instruction::Trunc: {
unsigned truncBf = I->getOperand(0)->getType()->getScalarSizeInBits();
DemandedMask.zext(truncBf);
- RHSKnownZero.zext(truncBf);
- RHSKnownOne.zext(truncBf);
+ KnownZero.zext(truncBf);
+ KnownOne.zext(truncBf);
if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMask,
- RHSKnownZero, RHSKnownOne, Depth+1))
+ KnownZero, KnownOne, Depth+1))
return I;
DemandedMask.trunc(BitWidth);
- RHSKnownZero.trunc(BitWidth);
- RHSKnownOne.trunc(BitWidth);
- assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
+ KnownZero.trunc(BitWidth);
+ KnownOne.trunc(BitWidth);
+ assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?");
break;
}
case Instruction::BitCast:
- if (!I->getOperand(0)->getType()->isIntOrIntVector())
- return false; // vector->int or fp->int?
+ if (!I->getOperand(0)->getType()->isIntOrIntVectorTy())
+ return 0; // vector->int or fp->int?
if (const VectorType *DstVTy = dyn_cast<VectorType>(I->getType())) {
if (const VectorType *SrcVTy =
dyn_cast<VectorType>(I->getOperand(0)->getType())) {
if (DstVTy->getNumElements() != SrcVTy->getNumElements())
// Don't touch a bitcast between vectors of different element counts.
- return false;
+ return 0;
} else
// Don't touch a scalar-to-vector bitcast.
- return false;
+ return 0;
} else if (isa<VectorType>(I->getOperand(0)->getType()))
// Don't touch a vector-to-scalar bitcast.
- return false;
+ return 0;
if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMask,
- RHSKnownZero, RHSKnownOne, Depth+1))
+ KnownZero, KnownOne, Depth+1))
return I;
- assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
+ assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?");
break;
case Instruction::ZExt: {
// Compute the bits in the result that are not present in the input.
unsigned SrcBitWidth =I->getOperand(0)->getType()->getScalarSizeInBits();
DemandedMask.trunc(SrcBitWidth);
- RHSKnownZero.trunc(SrcBitWidth);
- RHSKnownOne.trunc(SrcBitWidth);
+ KnownZero.trunc(SrcBitWidth);
+ KnownOne.trunc(SrcBitWidth);
if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMask,
- RHSKnownZero, RHSKnownOne, Depth+1))
+ KnownZero, KnownOne, Depth+1))
return I;
DemandedMask.zext(BitWidth);
- RHSKnownZero.zext(BitWidth);
- RHSKnownOne.zext(BitWidth);
- assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
+ KnownZero.zext(BitWidth);
+ KnownOne.zext(BitWidth);
+ assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?");
// The top bits are known to be zero.
- RHSKnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth);
+ KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth);
break;
}
case Instruction::SExt: {
@@ -460,27 +454,27 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
InputDemandedBits.set(SrcBitWidth-1);
InputDemandedBits.trunc(SrcBitWidth);
- RHSKnownZero.trunc(SrcBitWidth);
- RHSKnownOne.trunc(SrcBitWidth);
+ KnownZero.trunc(SrcBitWidth);
+ KnownOne.trunc(SrcBitWidth);
if (SimplifyDemandedBits(I->getOperandUse(0), InputDemandedBits,
- RHSKnownZero, RHSKnownOne, Depth+1))
+ KnownZero, KnownOne, Depth+1))
return I;
InputDemandedBits.zext(BitWidth);
- RHSKnownZero.zext(BitWidth);
- RHSKnownOne.zext(BitWidth);
- assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
+ KnownZero.zext(BitWidth);
+ KnownOne.zext(BitWidth);
+ assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?");
// If the sign bit of the input is known set or clear, then we know the
// top bits of the result.
// If the input sign bit is known zero, or if the NewBits are not demanded
// convert this into a zero extension.
- if (RHSKnownZero[SrcBitWidth-1] || (NewBits & ~DemandedMask) == NewBits) {
+ if (KnownZero[SrcBitWidth-1] || (NewBits & ~DemandedMask) == NewBits) {
// Convert to ZExt cast
CastInst *NewCast = new ZExtInst(I->getOperand(0), VTy, I->getName());
return InsertNewInstBefore(NewCast, *I);
- } else if (RHSKnownOne[SrcBitWidth-1]) { // Input sign bit known set
- RHSKnownOne |= NewBits;
+ } else if (KnownOne[SrcBitWidth-1]) { // Input sign bit known set
+ KnownOne |= NewBits;
}
break;
}
@@ -540,12 +534,12 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
// Bits are known one if they are known zero in one operand and one in the
// other, and there is no input carry.
- RHSKnownOne = ((LHSKnownZero & RHSVal) |
- (LHSKnownOne & ~RHSVal)) & ~CarryBits;
+ KnownOne = ((LHSKnownZero & RHSVal) |
+ (LHSKnownOne & ~RHSVal)) & ~CarryBits;
// Bits are known zero if they are known zero in both operands and there
// is no input carry.
- RHSKnownZero = LHSKnownZero & ~RHSVal & ~CarryBits;
+ KnownZero = LHSKnownZero & ~RHSVal & ~CarryBits;
} else {
// If the high-bits of this ADD are not demanded, then it does not demand
// the high bits of its LHS or RHS.
@@ -578,21 +572,21 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
}
// Otherwise just hand the sub off to ComputeMaskedBits to fill in
// the known zeros and ones.
- ComputeMaskedBits(V, DemandedMask, RHSKnownZero, RHSKnownOne, Depth);
+ ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth);
break;
case Instruction::Shl:
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
uint64_t ShiftAmt = SA->getLimitedValue(BitWidth);
APInt DemandedMaskIn(DemandedMask.lshr(ShiftAmt));
if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMaskIn,
- RHSKnownZero, RHSKnownOne, Depth+1))
+ KnownZero, KnownOne, Depth+1))
return I;
- assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
- RHSKnownZero <<= ShiftAmt;
- RHSKnownOne <<= ShiftAmt;
+ assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?");
+ KnownZero <<= ShiftAmt;
+ KnownOne <<= ShiftAmt;
// low bits known zero.
if (ShiftAmt)
- RHSKnownZero |= APInt::getLowBitsSet(BitWidth, ShiftAmt);
+ KnownZero |= APInt::getLowBitsSet(BitWidth, ShiftAmt);
}
break;
case Instruction::LShr:
@@ -603,15 +597,15 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
// Unsigned shift right.
APInt DemandedMaskIn(DemandedMask.shl(ShiftAmt));
if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMaskIn,
- RHSKnownZero, RHSKnownOne, Depth+1))
+ KnownZero, KnownOne, Depth+1))
return I;
- assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
- RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt);
- RHSKnownOne = APIntOps::lshr(RHSKnownOne, ShiftAmt);
+ assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?");
+ KnownZero = APIntOps::lshr(KnownZero, ShiftAmt);
+ KnownOne = APIntOps::lshr(KnownOne, ShiftAmt);
if (ShiftAmt) {
// Compute the new bits that are at the top now.
APInt HighBits(APInt::getHighBitsSet(BitWidth, ShiftAmt));
- RHSKnownZero |= HighBits; // high bits known zero.
+ KnownZero |= HighBits; // high bits known zero.
}
}
break;
@@ -642,13 +636,13 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
if (DemandedMask.countLeadingZeros() <= ShiftAmt)
DemandedMaskIn.set(BitWidth-1);
if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMaskIn,
- RHSKnownZero, RHSKnownOne, Depth+1))
+ KnownZero, KnownOne, Depth+1))
return I;
- assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?");
+ assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?");
// Compute the new bits that are at the top now.
APInt HighBits(APInt::getHighBitsSet(BitWidth, ShiftAmt));
- RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt);
- RHSKnownOne = APIntOps::lshr(RHSKnownOne, ShiftAmt);
+ KnownZero = APIntOps::lshr(KnownZero, ShiftAmt);
+ KnownOne = APIntOps::lshr(KnownOne, ShiftAmt);
// Handle the sign bits.
APInt SignBit(APInt::getSignBit(BitWidth));
@@ -657,14 +651,14 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
// If the input sign bit is known to be zero, or if none of the top bits
// are demanded, turn this into an unsigned shift right.
- if (BitWidth <= ShiftAmt || RHSKnownZero[BitWidth-ShiftAmt-1] ||
+ if (BitWidth <= ShiftAmt || KnownZero[BitWidth-ShiftAmt-1] ||
(HighBits & ~DemandedMask) == HighBits) {
// Perform the logical shift right.
Instruction *NewVal = BinaryOperator::CreateLShr(
I->getOperand(0), SA, I->getName());
return InsertNewInstBefore(NewVal, *I);
- } else if ((RHSKnownOne & SignBit) != 0) { // New bits are known one.
- RHSKnownOne |= HighBits;
+ } else if ((KnownOne & SignBit) != 0) { // New bits are known one.
+ KnownOne |= HighBits;
}
}
break;
@@ -681,10 +675,19 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
LHSKnownZero, LHSKnownOne, Depth+1))
return I;
+ // The low bits of LHS are unchanged by the srem.
+ KnownZero = LHSKnownZero & LowBits;
+ KnownOne = LHSKnownOne & LowBits;
+
+ // If LHS is non-negative or has all low bits zero, then the upper bits
+ // are all zero.
if (LHSKnownZero[BitWidth-1] || ((LHSKnownZero & LowBits) == LowBits))
- LHSKnownZero |= ~LowBits;
+ KnownZero |= ~LowBits;
- KnownZero |= LHSKnownZero & DemandedMask;
+ // If LHS is negative and not all low bits are zero, then the upper bits
+ // are all one.
+ if (LHSKnownOne[BitWidth-1] && ((LHSKnownOne & LowBits) != 0))
+ KnownOne |= ~LowBits;
assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?");
}
@@ -743,15 +746,15 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
}
}
}
- ComputeMaskedBits(V, DemandedMask, RHSKnownZero, RHSKnownOne, Depth);
+ ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth);
break;
}
// If the client is only demanding bits that we know, return the known
// constant.
- if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask)
- return Constant::getIntegerValue(VTy, RHSKnownOne);
- return false;
+ if ((DemandedMask & (KnownZero|KnownOne)) == DemandedMask)
+ return Constant::getIntegerValue(VTy, KnownOne);
+ return 0;
}
@@ -764,7 +767,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
/// operation, the operation is simplified, then the resultant value is
/// returned. This returns null if no change was made.
Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,
- APInt& UndefElts,
+ APInt &UndefElts,
unsigned Depth) {
unsigned VWidth = cast<VectorType>(V->getType())->getNumElements();
APInt EltMask(APInt::getAllOnesValue(VWidth));
@@ -774,13 +777,15 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,
// If the entire vector is undefined, just return this info.
UndefElts = EltMask;
return 0;
- } else if (DemandedElts == 0) { // If nothing is demanded, provide undef.
+ }
+
+ if (DemandedElts == 0) { // If nothing is demanded, provide undef.
UndefElts = EltMask;
return UndefValue::get(V->getType());
}
UndefElts = 0;
- if (ConstantVector *CP = dyn_cast<ConstantVector>(V)) {
+ if (ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
const Type *EltTy = cast<VectorType>(V->getType())->getElementType();
Constant *Undef = UndefValue::get(EltTy);
@@ -789,23 +794,25 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,
if (!DemandedElts[i]) { // If not demanded, set to undef.
Elts.push_back(Undef);
UndefElts.set(i);
- } else if (isa<UndefValue>(CP->getOperand(i))) { // Already undef.
+ } else if (isa<UndefValue>(CV->getOperand(i))) { // Already undef.
Elts.push_back(Undef);
UndefElts.set(i);
} else { // Otherwise, defined.
- Elts.push_back(CP->getOperand(i));
+ Elts.push_back(CV->getOperand(i));
}
// If we changed the constant, return it.
Constant *NewCP = ConstantVector::get(Elts);
- return NewCP != CP ? NewCP : 0;
- } else if (isa<ConstantAggregateZero>(V)) {
+ return NewCP != CV ? NewCP : 0;
+ }
+
+ if (isa<ConstantAggregateZero>(V)) {
// Simplify the CAZ to a ConstantVector where the non-demanded elements are
// set to undef.
// Check if this is identity. If so, return 0 since we are not simplifying
// anything.
- if (DemandedElts == ((1ULL << VWidth) -1))
+ if (DemandedElts.isAllOnesValue())
return 0;
const Type *EltTy = cast<VectorType>(V->getType())->getElementType();
diff --git a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index f11f557..20fda1a 100644
--- a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -162,7 +162,8 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
// property.
if (EI.getOperand(0)->hasOneUse() && VectorWidth != 1) {
APInt UndefElts(VectorWidth, 0);
- APInt DemandedMask(VectorWidth, 1 << IndexVal);
+ APInt DemandedMask(VectorWidth, 0);
+ DemandedMask.set(IndexVal);
if (Value *V = SimplifyDemandedVectorElts(EI.getOperand(0),
DemandedMask, UndefElts)) {
EI.setOperand(0, V);
diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp
index 93b1961..96c0342 100644
--- a/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -158,7 +158,7 @@ Value *InstCombiner::dyn_castNegVal(Value *V) const {
return ConstantExpr::getNeg(C);
if (ConstantVector *C = dyn_cast<ConstantVector>(V))
- if (C->getType()->getElementType()->isInteger())
+ if (C->getType()->getElementType()->isIntegerTy())
return ConstantExpr::getNeg(C);
return 0;
@@ -177,7 +177,7 @@ Value *InstCombiner::dyn_castFNegVal(Value *V) const {
return ConstantExpr::getFNeg(C);
if (ConstantVector *C = dyn_cast<ConstantVector>(V))
- if (C->getType()->getElementType()->isFloatingPoint())
+ if (C->getType()->getElementType()->isFloatingPointTy())
return ConstantExpr::getFNeg(C);
return 0;
@@ -226,7 +226,7 @@ Instruction *InstCombiner::FoldOpIntoSelect(Instruction &Op, SelectInst *SI) {
if (isa<Constant>(TV) || isa<Constant>(FV)) {
// Bool selects with constant operands can be folded to logical ops.
- if (SI->getType()->isInteger(1)) return 0;
+ if (SI->getType()->isIntegerTy(1)) return 0;
Value *SelectTrueVal = FoldOperationIntoSelectOperand(Op, TV, this);
Value *SelectFalseVal = FoldOperationIntoSelectOperand(Op, FV, this);
@@ -596,7 +596,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
// (where tmp = 8*tmp2) into:
// getelementptr [100 x double]* %arr, i32 0, i32 %tmp2; bitcast
- if (TD && isa<ArrayType>(SrcElTy) && ResElTy->isInteger(8)) {
+ if (TD && isa<ArrayType>(SrcElTy) && ResElTy->isIntegerTy(8)) {
uint64_t ArrayEltSize =
TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType());
diff --git a/lib/Transforms/InstCombine/Makefile b/lib/Transforms/InstCombine/Makefile
index f9de42a..0c488e78 100644
--- a/lib/Transforms/InstCombine/Makefile
+++ b/lib/Transforms/InstCombine/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMInstCombine
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/Instrumentation/Makefile b/lib/Transforms/Instrumentation/Makefile
index 1238896..6cbc7a9 100644
--- a/lib/Transforms/Instrumentation/Makefile
+++ b/lib/Transforms/Instrumentation/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMInstrumentation
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/Instrumentation/ProfilingUtils.cpp b/lib/Transforms/Instrumentation/ProfilingUtils.cpp
index 3214c8c..8662a82 100644
--- a/lib/Transforms/Instrumentation/ProfilingUtils.cpp
+++ b/lib/Transforms/Instrumentation/ProfilingUtils.cpp
@@ -84,7 +84,7 @@ void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName,
AI = MainFn->arg_begin();
// If the program looked at argc, have it look at the return value of the
// init call instead.
- if (!AI->getType()->isInteger(32)) {
+ if (!AI->getType()->isIntegerTy(32)) {
Instruction::CastOps opcode;
if (!AI->use_empty()) {
opcode = CastInst::getCastOpcode(InitCall, true, AI->getType(), true);
diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp
index c3139a5..21e6f89 100644
--- a/lib/Transforms/Scalar/CodeGenPrepare.cpp
+++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp
@@ -32,7 +32,6 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CallSite.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/PatternMatch.h"
@@ -40,9 +39,6 @@
using namespace llvm;
using namespace llvm::PatternMatch;
-static cl::opt<bool> FactorCommonPreds("split-critical-paths-tweak",
- cl::init(false), cl::Hidden);
-
namespace {
class CodeGenPrepare : public FunctionPass {
/// TLI - Keep a pointer of a TargetLowering to consult for determining
@@ -63,6 +59,10 @@ namespace {
AU.addPreserved<ProfileInfo>();
}
+ virtual void releaseMemory() {
+ BackEdges.clear();
+ }
+
private:
bool EliminateMostlyEmptyBlocks(Function &F);
bool CanMergeBlocks(const BasicBlock *BB, const BasicBlock *DestBB) const;
@@ -297,6 +297,70 @@ void CodeGenPrepare::EliminateMostlyEmptyBlock(BasicBlock *BB) {
DEBUG(dbgs() << "AFTER:\n" << *DestBB << "\n\n\n");
}
+/// FindReusablePredBB - Check all of the predecessors of the block DestPHI
+/// lives in to see if there is a block that we can reuse as a critical edge
+/// from TIBB.
+static BasicBlock *FindReusablePredBB(PHINode *DestPHI, BasicBlock *TIBB) {
+ BasicBlock *Dest = DestPHI->getParent();
+
+ /// TIPHIValues - This array is lazily computed to determine the values of
+ /// PHIs in Dest that TI would provide.
+ SmallVector<Value*, 32> TIPHIValues;
+
+ /// TIBBEntryNo - This is a cache to speed up pred queries for TIBB.
+ unsigned TIBBEntryNo = 0;
+
+ // Check to see if Dest has any blocks that can be used as a split edge for
+ // this terminator.
+ for (unsigned pi = 0, e = DestPHI->getNumIncomingValues(); pi != e; ++pi) {
+ BasicBlock *Pred = DestPHI->getIncomingBlock(pi);
+ // To be usable, the pred has to end with an uncond branch to the dest.
+ BranchInst *PredBr = dyn_cast<BranchInst>(Pred->getTerminator());
+ if (!PredBr || !PredBr->isUnconditional())
+ continue;
+ // Must be empty other than the branch and debug info.
+ BasicBlock::iterator I = Pred->begin();
+ while (isa<DbgInfoIntrinsic>(I))
+ I++;
+ if (&*I != PredBr)
+ continue;
+ // Cannot be the entry block; its label does not get emitted.
+ if (Pred == &Dest->getParent()->getEntryBlock())
+ continue;
+
+ // Finally, since we know that Dest has phi nodes in it, we have to make
+ // sure that jumping to Pred will have the same effect as going to Dest in
+ // terms of PHI values.
+ PHINode *PN;
+ unsigned PHINo = 0;
+ unsigned PredEntryNo = pi;
+
+ bool FoundMatch = true;
+ for (BasicBlock::iterator I = Dest->begin();
+ (PN = dyn_cast<PHINode>(I)); ++I, ++PHINo) {
+ if (PHINo == TIPHIValues.size()) {
+ if (PN->getIncomingBlock(TIBBEntryNo) != TIBB)
+ TIBBEntryNo = PN->getBasicBlockIndex(TIBB);
+ TIPHIValues.push_back(PN->getIncomingValue(TIBBEntryNo));
+ }
+
+ // If the PHI entry doesn't work, we can't use this pred.
+ if (PN->getIncomingBlock(PredEntryNo) != Pred)
+ PredEntryNo = PN->getBasicBlockIndex(Pred);
+
+ if (TIPHIValues[PHINo] != PN->getIncomingValue(PredEntryNo)) {
+ FoundMatch = false;
+ break;
+ }
+ }
+
+ // If we found a workable predecessor, change TI to branch to Succ.
+ if (FoundMatch)
+ return Pred;
+ }
+ return 0;
+}
+
/// SplitEdgeNicely - Split the critical edge from TI to its specified
/// successor if it will improve codegen. We only do this if the successor has
@@ -311,13 +375,12 @@ static void SplitEdgeNicely(TerminatorInst *TI, unsigned SuccNum,
BasicBlock *Dest = TI->getSuccessor(SuccNum);
assert(isa<PHINode>(Dest->begin()) &&
"This should only be called if Dest has a PHI!");
+ PHINode *DestPHI = cast<PHINode>(Dest->begin());
// Do not split edges to EH landing pads.
- if (InvokeInst *Invoke = dyn_cast<InvokeInst>(TI)) {
+ if (InvokeInst *Invoke = dyn_cast<InvokeInst>(TI))
if (Invoke->getSuccessor(1) == Dest)
return;
- }
-
// As a hack, never split backedges of loops. Even though the copy for any
// PHIs inserted on the backedge would be dead for exits from the loop, we
@@ -325,92 +388,16 @@ static void SplitEdgeNicely(TerminatorInst *TI, unsigned SuccNum,
if (BackEdges.count(std::make_pair(TIBB, Dest)))
return;
- if (!FactorCommonPreds) {
- /// TIPHIValues - This array is lazily computed to determine the values of
- /// PHIs in Dest that TI would provide.
- SmallVector<Value*, 32> TIPHIValues;
-
- // Check to see if Dest has any blocks that can be used as a split edge for
- // this terminator.
- for (pred_iterator PI = pred_begin(Dest), E = pred_end(Dest); PI != E; ++PI) {
- BasicBlock *Pred = *PI;
- // To be usable, the pred has to end with an uncond branch to the dest.
- BranchInst *PredBr = dyn_cast<BranchInst>(Pred->getTerminator());
- if (!PredBr || !PredBr->isUnconditional())
- continue;
- // Must be empty other than the branch and debug info.
- BasicBlock::iterator I = Pred->begin();
- while (isa<DbgInfoIntrinsic>(I))
- I++;
- if (dyn_cast<Instruction>(I) != PredBr)
- continue;
- // Cannot be the entry block; its label does not get emitted.
- if (Pred == &(Dest->getParent()->getEntryBlock()))
- continue;
-
- // Finally, since we know that Dest has phi nodes in it, we have to make
- // sure that jumping to Pred will have the same effect as going to Dest in
- // terms of PHI values.
- PHINode *PN;
- unsigned PHINo = 0;
- bool FoundMatch = true;
- for (BasicBlock::iterator I = Dest->begin();
- (PN = dyn_cast<PHINode>(I)); ++I, ++PHINo) {
- if (PHINo == TIPHIValues.size())
- TIPHIValues.push_back(PN->getIncomingValueForBlock(TIBB));
-
- // If the PHI entry doesn't work, we can't use this pred.
- if (TIPHIValues[PHINo] != PN->getIncomingValueForBlock(Pred)) {
- FoundMatch = false;
- break;
- }
- }
-
- // If we found a workable predecessor, change TI to branch to Succ.
- if (FoundMatch) {
- ProfileInfo *PFI = P->getAnalysisIfAvailable<ProfileInfo>();
- if (PFI)
- PFI->splitEdge(TIBB, Dest, Pred);
- Dest->removePredecessor(TIBB);
- TI->setSuccessor(SuccNum, Pred);
- return;
- }
- }
-
- SplitCriticalEdge(TI, SuccNum, P, true);
+ if (BasicBlock *ReuseBB = FindReusablePredBB(DestPHI, TIBB)) {
+ ProfileInfo *PFI = P->getAnalysisIfAvailable<ProfileInfo>();
+ if (PFI)
+ PFI->splitEdge(TIBB, Dest, ReuseBB);
+ Dest->removePredecessor(TIBB);
+ TI->setSuccessor(SuccNum, ReuseBB);
return;
}
- PHINode *PN;
- SmallVector<Value*, 8> TIPHIValues;
- for (BasicBlock::iterator I = Dest->begin();
- (PN = dyn_cast<PHINode>(I)); ++I)
- TIPHIValues.push_back(PN->getIncomingValueForBlock(TIBB));
-
- SmallVector<BasicBlock*, 8> IdenticalPreds;
- for (pred_iterator PI = pred_begin(Dest), E = pred_end(Dest); PI != E; ++PI) {
- BasicBlock *Pred = *PI;
- if (BackEdges.count(std::make_pair(Pred, Dest)))
- continue;
- if (PI == TIBB)
- IdenticalPreds.push_back(Pred);
- else {
- bool Identical = true;
- unsigned PHINo = 0;
- for (BasicBlock::iterator I = Dest->begin();
- (PN = dyn_cast<PHINode>(I)); ++I, ++PHINo)
- if (TIPHIValues[PHINo] != PN->getIncomingValueForBlock(Pred)) {
- Identical = false;
- break;
- }
- if (Identical)
- IdenticalPreds.push_back(Pred);
- }
- }
-
- assert(!IdenticalPreds.empty());
- SplitBlockPredecessors(Dest, &IdenticalPreds[0], IdenticalPreds.size(),
- ".critedge", P);
+ SplitCriticalEdge(TI, SuccNum, P, true);
}
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 320afa1..09c01d3 100644
--- a/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -44,8 +44,14 @@ namespace {
virtual bool runOnFunction(Function &F) {
bool Changed = false;
+
+ DominatorTree &DT = getAnalysis<DominatorTree>();
+
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
- Changed |= runOnBasicBlock(*I);
+ // Only check non-dead blocks. Dead blocks may have strange pointer
+ // cycles that will confuse alias analysis.
+ if (DT.isReachableFromEntry(I))
+ Changed |= runOnBasicBlock(*I);
return Changed;
}
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index b29fe74..3ce7482 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -60,6 +60,7 @@ STATISTIC(NumPRELoad, "Number of loads PRE'd");
static cl::opt<bool> EnablePRE("enable-pre",
cl::init(true), cl::Hidden);
static cl::opt<bool> EnableLoadPRE("enable-load-pre", cl::init(true));
+static cl::opt<bool> EnableFullLoadPRE("enable-full-load-pre", cl::init(false));
//===----------------------------------------------------------------------===//
// ValueTable Class
@@ -1522,8 +1523,6 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
while (TmpBB->getSinglePredecessor()) {
isSinglePred = true;
TmpBB = TmpBB->getSinglePredecessor();
- if (!TmpBB) // If haven't found any, bail now.
- return false;
if (TmpBB == LoadBB) // Infinite (unreachable) loop.
return false;
if (Blockers.count(TmpBB))
@@ -1539,10 +1538,12 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
// at least one of the values is LI. Since this means that we won't be able
// to eliminate LI even if we insert uses in the other predecessors, we will
// end up increasing code size. Reject this by scanning for LI.
- for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i)
- if (ValuesPerBlock[i].isSimpleValue() &&
- ValuesPerBlock[i].getSimpleValue() == LI)
- return false;
+ if (!EnableFullLoadPRE) {
+ for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i)
+ if (ValuesPerBlock[i].isSimpleValue() &&
+ ValuesPerBlock[i].getSimpleValue() == LI)
+ return false;
+ }
// FIXME: It is extremely unclear what this loop is doing, other than
// artificially restricting loadpre.
@@ -1566,13 +1567,9 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
return false;
}
- // Okay, we have some hope :). Check to see if the loaded value is fully
- // available in all but one predecessor.
- // FIXME: If we could restructure the CFG, we could make a common pred with
- // all the preds that don't have an available LI and insert a new load into
- // that one block.
- BasicBlock *UnavailablePred = 0;
-
+ // Check to see how many predecessors have the loaded value fully
+ // available.
+ DenseMap<BasicBlock*, Value*> PredLoads;
DenseMap<BasicBlock*, char> FullyAvailableBlocks;
for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i)
FullyAvailableBlocks[ValuesPerBlock[i].BB] = true;
@@ -1581,79 +1578,93 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB);
PI != E; ++PI) {
- if (IsValueFullyAvailableInBlock(*PI, FullyAvailableBlocks))
+ BasicBlock *Pred = *PI;
+ if (IsValueFullyAvailableInBlock(Pred, FullyAvailableBlocks)) {
continue;
-
- // If this load is not available in multiple predecessors, reject it.
- if (UnavailablePred && UnavailablePred != *PI)
+ }
+ PredLoads[Pred] = 0;
+ // We don't currently handle critical edges :(
+ if (Pred->getTerminator()->getNumSuccessors() != 1) {
+ DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF CRITICAL EDGE '"
+ << Pred->getName() << "': " << *LI << '\n');
return false;
- UnavailablePred = *PI;
+ }
}
- assert(UnavailablePred != 0 &&
+ // Decide whether PRE is profitable for this load.
+ unsigned NumUnavailablePreds = PredLoads.size();
+ assert(NumUnavailablePreds != 0 &&
"Fully available value should be eliminated above!");
-
- // We don't currently handle critical edges :(
- if (UnavailablePred->getTerminator()->getNumSuccessors() != 1) {
- DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF CRITICAL EDGE '"
- << UnavailablePred->getName() << "': " << *LI << '\n');
- return false;
+ if (!EnableFullLoadPRE) {
+ // If this load is unavailable in multiple predecessors, reject it.
+ // FIXME: If we could restructure the CFG, we could make a common pred with
+ // all the preds that don't have an available LI and insert a new load into
+ // that one block.
+ if (NumUnavailablePreds != 1)
+ return false;
}
-
- // Do PHI translation to get its value in the predecessor if necessary. The
- // returned pointer (if non-null) is guaranteed to dominate UnavailablePred.
- //
+
+ // Check if the load can safely be moved to all the unavailable predecessors.
+ bool CanDoPRE = true;
SmallVector<Instruction*, 8> NewInsts;
-
- // If all preds have a single successor, then we know it is safe to insert the
- // load on the pred (?!?), so we can insert code to materialize the pointer if
- // it is not available.
- PHITransAddr Address(LI->getOperand(0), TD);
- Value *LoadPtr = 0;
- if (allSingleSucc) {
- LoadPtr = Address.PHITranslateWithInsertion(LoadBB, UnavailablePred,
- *DT, NewInsts);
- } else {
- Address.PHITranslateValue(LoadBB, UnavailablePred);
- LoadPtr = Address.getAddr();
+ for (DenseMap<BasicBlock*, Value*>::iterator I = PredLoads.begin(),
+ E = PredLoads.end(); I != E; ++I) {
+ BasicBlock *UnavailablePred = I->first;
+
+ // Do PHI translation to get its value in the predecessor if necessary. The
+ // returned pointer (if non-null) is guaranteed to dominate UnavailablePred.
+
+ // If all preds have a single successor, then we know it is safe to insert
+ // the load on the pred (?!?), so we can insert code to materialize the
+ // pointer if it is not available.
+ PHITransAddr Address(LI->getOperand(0), TD);
+ Value *LoadPtr = 0;
+ if (allSingleSucc) {
+ LoadPtr = Address.PHITranslateWithInsertion(LoadBB, UnavailablePred,
+ *DT, NewInsts);
+ } else {
+ Address.PHITranslateValue(LoadBB, UnavailablePred);
+ LoadPtr = Address.getAddr();
- // Make sure the value is live in the predecessor.
- if (Instruction *Inst = dyn_cast_or_null<Instruction>(LoadPtr))
- if (!DT->dominates(Inst->getParent(), UnavailablePred))
- LoadPtr = 0;
- }
+ // Make sure the value is live in the predecessor.
+ if (Instruction *Inst = dyn_cast_or_null<Instruction>(LoadPtr))
+ if (!DT->dominates(Inst->getParent(), UnavailablePred))
+ LoadPtr = 0;
+ }
- // If we couldn't find or insert a computation of this phi translated value,
- // we fail PRE.
- if (LoadPtr == 0) {
- assert(NewInsts.empty() && "Shouldn't insert insts on failure");
- DEBUG(dbgs() << "COULDN'T INSERT PHI TRANSLATED VALUE OF: "
- << *LI->getOperand(0) << "\n");
- return false;
- }
+ // If we couldn't find or insert a computation of this phi translated value,
+ // we fail PRE.
+ if (LoadPtr == 0) {
+ DEBUG(dbgs() << "COULDN'T INSERT PHI TRANSLATED VALUE OF: "
+ << *LI->getOperand(0) << "\n");
+ CanDoPRE = false;
+ break;
+ }
- // Assign value numbers to these new instructions.
- for (unsigned i = 0, e = NewInsts.size(); i != e; ++i) {
- // FIXME: We really _ought_ to insert these value numbers into their
- // parent's availability map. However, in doing so, we risk getting into
- // ordering issues. If a block hasn't been processed yet, we would be
- // marking a value as AVAIL-IN, which isn't what we intend.
- VN.lookup_or_add(NewInsts[i]);
+ // Make sure it is valid to move this load here. We have to watch out for:
+ // @1 = getelementptr (i8* p, ...
+ // test p and branch if == 0
+ // load @1
+ // It is valid to have the getelementptr before the test, even if p can be 0,
+ // as getelementptr only does address arithmetic.
+ // If we are not pushing the value through any multiple-successor blocks
+ // we do not have this case. Otherwise, check that the load is safe to
+ // put anywhere; this can be improved, but should be conservatively safe.
+ if (!allSingleSucc &&
+ // FIXME: REEVALUTE THIS.
+ !isSafeToLoadUnconditionally(LoadPtr,
+ UnavailablePred->getTerminator(),
+ LI->getAlignment(), TD)) {
+ CanDoPRE = false;
+ break;
+ }
+
+ I->second = LoadPtr;
}
-
- // Make sure it is valid to move this load here. We have to watch out for:
- // @1 = getelementptr (i8* p, ...
- // test p and branch if == 0
- // load @1
- // It is valid to have the getelementptr before the test, even if p can be 0,
- // as getelementptr only does address arithmetic.
- // If we are not pushing the value through any multiple-successor blocks
- // we do not have this case. Otherwise, check that the load is safe to
- // put anywhere; this can be improved, but should be conservatively safe.
- if (!allSingleSucc &&
- // FIXME: REEVALUTE THIS.
- !isSafeToLoadUnconditionally(LoadPtr, UnavailablePred->getTerminator())) {
- assert(NewInsts.empty() && "Should not have inserted instructions");
+
+ if (!CanDoPRE) {
+ while (!NewInsts.empty())
+ NewInsts.pop_back_val()->eraseFromParent();
return false;
}
@@ -1665,12 +1676,28 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
dbgs() << "INSERTED " << NewInsts.size() << " INSTS: "
<< *NewInsts.back() << '\n');
- Value *NewLoad = new LoadInst(LoadPtr, LI->getName()+".pre", false,
- LI->getAlignment(),
- UnavailablePred->getTerminator());
+ // Assign value numbers to the new instructions.
+ for (unsigned i = 0, e = NewInsts.size(); i != e; ++i) {
+ // FIXME: We really _ought_ to insert these value numbers into their
+ // parent's availability map. However, in doing so, we risk getting into
+ // ordering issues. If a block hasn't been processed yet, we would be
+ // marking a value as AVAIL-IN, which isn't what we intend.
+ VN.lookup_or_add(NewInsts[i]);
+ }
- // Add the newly created load.
- ValuesPerBlock.push_back(AvailableValueInBlock::get(UnavailablePred,NewLoad));
+ for (DenseMap<BasicBlock*, Value*>::iterator I = PredLoads.begin(),
+ E = PredLoads.end(); I != E; ++I) {
+ BasicBlock *UnavailablePred = I->first;
+ Value *LoadPtr = I->second;
+
+ Value *NewLoad = new LoadInst(LoadPtr, LI->getName()+".pre", false,
+ LI->getAlignment(),
+ UnavailablePred->getTerminator());
+
+ // Add the newly created load.
+ ValuesPerBlock.push_back(AvailableValueInBlock::get(UnavailablePred,
+ NewLoad));
+ }
// Perform PHI construction.
Value *V = ConstructSSAForLoadSet(LI, ValuesPerBlock, TD, *DT,
@@ -1864,6 +1891,10 @@ Value *GVN::lookupNumber(BasicBlock *BB, uint32_t num) {
/// by inserting it into the appropriate sets
bool GVN::processInstruction(Instruction *I,
SmallVectorImpl<Instruction*> &toErase) {
+ // Ignore dbg info intrinsics.
+ if (isa<DbgInfoIntrinsic>(I))
+ return false;
+
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
bool Changed = processLoad(LI, toErase);
@@ -2075,7 +2106,7 @@ bool GVN::performPRE(Function &F) {
for (pred_iterator PI = pred_begin(CurrentBlock),
PE = pred_end(CurrentBlock); PI != PE; ++PI) {
// We're not interested in PRE where the block is its
- // own predecessor, on in blocks with predecessors
+ // own predecessor, or in blocks with predecessors
// that are not reachable.
if (*PI == CurrentBlock) {
NumWithout = 2;
@@ -2123,10 +2154,10 @@ bool GVN::performPRE(Function &F) {
continue;
}
- // Instantiate the expression the in predecessor that lacked it.
+ // Instantiate the expression in the predecessor that lacked it.
// Because we are going top-down through the block, all value numbers
// will be available in the predecessor by the time we need them. Any
- // that weren't original present will have been instantiated earlier
+ // that weren't originally present will have been instantiated earlier
// in this loop.
Instruction *PREInstr = CurInst->clone();
bool success = true;
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index 17f7d98..5302fdc 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -364,23 +364,17 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
if (ExitingBlock)
NeedCannIV = true;
}
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- const SCEV *Stride = IU->StrideOrder[i];
- const Type *Ty = SE->getEffectiveSCEVType(Stride->getType());
+ for (IVUsers::const_iterator I = IU->begin(), E = IU->end(); I != E; ++I) {
+ const Type *Ty =
+ SE->getEffectiveSCEVType(I->getOperandValToReplace()->getType());
if (!LargestType ||
SE->getTypeSizeInBits(Ty) >
SE->getTypeSizeInBits(LargestType))
LargestType = Ty;
-
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[i]);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
-
- if (!SI->second->Users.empty())
- NeedCannIV = true;
+ NeedCannIV = true;
}
- // Now that we know the largest of of the induction variable expressions
+ // Now that we know the largest of the induction variable expressions
// in this loop, insert a canonical induction variable of the largest size.
Value *IndVar = 0;
if (NeedCannIV) {
@@ -455,72 +449,64 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
// add the offsets to the primary induction variable and cast, avoiding
// the need for the code evaluation methods to insert induction variables
// of different sizes.
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- const SCEV *Stride = IU->StrideOrder[i];
-
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[i]);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
- ilist<IVStrideUse> &List = SI->second->Users;
- for (ilist<IVStrideUse>::iterator UI = List.begin(),
- E = List.end(); UI != E; ++UI) {
- Value *Op = UI->getOperandValToReplace();
- const Type *UseTy = Op->getType();
- Instruction *User = UI->getUser();
-
- // Compute the final addrec to expand into code.
- const SCEV *AR = IU->getReplacementExpr(*UI);
-
- // Evaluate the expression out of the loop, if possible.
- if (!L->contains(UI->getUser())) {
- const SCEV *ExitVal = SE->getSCEVAtScope(AR, L->getParentLoop());
- if (ExitVal->isLoopInvariant(L))
- AR = ExitVal;
- }
+ for (IVUsers::iterator UI = IU->begin(), E = IU->end(); UI != E; ++UI) {
+ const SCEV *Stride = UI->getStride();
+ Value *Op = UI->getOperandValToReplace();
+ const Type *UseTy = Op->getType();
+ Instruction *User = UI->getUser();
+
+ // Compute the final addrec to expand into code.
+ const SCEV *AR = IU->getReplacementExpr(*UI);
+
+ // Evaluate the expression out of the loop, if possible.
+ if (!L->contains(UI->getUser())) {
+ const SCEV *ExitVal = SE->getSCEVAtScope(AR, L->getParentLoop());
+ if (ExitVal->isLoopInvariant(L))
+ AR = ExitVal;
+ }
- // FIXME: It is an extremely bad idea to indvar substitute anything more
- // complex than affine induction variables. Doing so will put expensive
- // polynomial evaluations inside of the loop, and the str reduction pass
- // currently can only reduce affine polynomials. For now just disable
- // indvar subst on anything more complex than an affine addrec, unless
- // it can be expanded to a trivial value.
- if (!AR->isLoopInvariant(L) && !Stride->isLoopInvariant(L))
- continue;
+ // FIXME: It is an extremely bad idea to indvar substitute anything more
+ // complex than affine induction variables. Doing so will put expensive
+ // polynomial evaluations inside of the loop, and the str reduction pass
+ // currently can only reduce affine polynomials. For now just disable
+ // indvar subst on anything more complex than an affine addrec, unless
+ // it can be expanded to a trivial value.
+ if (!AR->isLoopInvariant(L) && !Stride->isLoopInvariant(L))
+ continue;
- // Determine the insertion point for this user. By default, insert
- // immediately before the user. The SCEVExpander class will automatically
- // hoist loop invariants out of the loop. For PHI nodes, there may be
- // multiple uses, so compute the nearest common dominator for the
- // incoming blocks.
- Instruction *InsertPt = User;
- if (PHINode *PHI = dyn_cast<PHINode>(InsertPt))
- for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
- if (PHI->getIncomingValue(i) == Op) {
- if (InsertPt == User)
- InsertPt = PHI->getIncomingBlock(i)->getTerminator();
- else
- InsertPt =
- DT->findNearestCommonDominator(InsertPt->getParent(),
- PHI->getIncomingBlock(i))
- ->getTerminator();
- }
-
- // Now expand it into actual Instructions and patch it into place.
- Value *NewVal = Rewriter.expandCodeFor(AR, UseTy, InsertPt);
-
- // Patch the new value into place.
- if (Op->hasName())
- NewVal->takeName(Op);
- User->replaceUsesOfWith(Op, NewVal);
- UI->setOperandValToReplace(NewVal);
- DEBUG(dbgs() << "INDVARS: Rewrote IV '" << *AR << "' " << *Op << '\n'
- << " into = " << *NewVal << "\n");
- ++NumRemoved;
- Changed = true;
-
- // The old value may be dead now.
- DeadInsts.push_back(Op);
- }
+ // Determine the insertion point for this user. By default, insert
+ // immediately before the user. The SCEVExpander class will automatically
+ // hoist loop invariants out of the loop. For PHI nodes, there may be
+ // multiple uses, so compute the nearest common dominator for the
+ // incoming blocks.
+ Instruction *InsertPt = User;
+ if (PHINode *PHI = dyn_cast<PHINode>(InsertPt))
+ for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
+ if (PHI->getIncomingValue(i) == Op) {
+ if (InsertPt == User)
+ InsertPt = PHI->getIncomingBlock(i)->getTerminator();
+ else
+ InsertPt =
+ DT->findNearestCommonDominator(InsertPt->getParent(),
+ PHI->getIncomingBlock(i))
+ ->getTerminator();
+ }
+
+ // Now expand it into actual Instructions and patch it into place.
+ Value *NewVal = Rewriter.expandCodeFor(AR, UseTy, InsertPt);
+
+ // Patch the new value into place.
+ if (Op->hasName())
+ NewVal->takeName(Op);
+ User->replaceUsesOfWith(Op, NewVal);
+ UI->setOperandValToReplace(NewVal);
+ DEBUG(dbgs() << "INDVARS: Rewrote IV '" << *AR << "' " << *Op << '\n'
+ << " into = " << *NewVal << "\n");
+ ++NumRemoved;
+ Changed = true;
+
+ // The old value may be dead now.
+ DeadInsts.push_back(Op);
}
// Clear the rewriter cache, because values that are in the rewriter's cache
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp
index 9531311..8f21aac 100644
--- a/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/lib/Transforms/Scalar/JumpThreading.cpp
@@ -336,13 +336,18 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){
else
InterestingVal = ConstantInt::getFalse(I->getContext());
- // Scan for the sentinel.
+ // Scan for the sentinel. If we find an undef, force it to the
+ // interesting value: x|undef -> true and x&undef -> false.
for (unsigned i = 0, e = LHSVals.size(); i != e; ++i)
- if (LHSVals[i].first == InterestingVal || LHSVals[i].first == 0)
+ if (LHSVals[i].first == InterestingVal || LHSVals[i].first == 0) {
Result.push_back(LHSVals[i]);
+ Result.back().first = InterestingVal;
+ }
for (unsigned i = 0, e = RHSVals.size(); i != e; ++i)
- if (RHSVals[i].first == InterestingVal || RHSVals[i].first == 0)
+ if (RHSVals[i].first == InterestingVal || RHSVals[i].first == 0) {
Result.push_back(RHSVals[i]);
+ Result.back().first = InterestingVal;
+ }
return !Result.empty();
}
@@ -400,7 +405,7 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){
// If comparing a live-in value against a constant, see if we know the
// live-in value on any predecessors.
if (LVI && isa<Constant>(Cmp->getOperand(1)) &&
- Cmp->getType()->isInteger() && // Not vector compare.
+ Cmp->getType()->isIntegerTy() && // Not vector compare.
(!isa<Instruction>(Cmp->getOperand(0)) ||
cast<Instruction>(Cmp->getOperand(0))->getParent() != BB)) {
Constant *RHSCst = cast<Constant>(Cmp->getOperand(1));
@@ -451,6 +456,12 @@ static unsigned GetBestDestForJumpOnUndef(BasicBlock *BB) {
/// ProcessBlock - If there are any predecessors whose control can be threaded
/// through to a successor, transform them now.
bool JumpThreading::ProcessBlock(BasicBlock *BB) {
+ // If the block is trivially dead, just return and let the caller nuke it.
+ // This simplifies other transformations.
+ if (pred_begin(BB) == pred_end(BB) &&
+ BB != &BB->getParent()->getEntryBlock())
+ return false;
+
// If this block has a single predecessor, and if that pred has a single
// successor, merge the blocks. This encourages recursive jump threading
// because now the condition in this block can be threaded through
@@ -1117,6 +1128,11 @@ bool JumpThreading::ProcessBranchOnXOR(BinaryOperator *BO) {
isa<ConstantInt>(BO->getOperand(1)))
return false;
+ // If the first instruction in BB isn't a phi, we won't be able to infer
+ // anything special about any particular predecessor.
+ if (!isa<PHINode>(BB->front()))
+ return false;
+
// If we have a xor as the branch input to this block, and we know that the
// LHS or RHS of the xor in any predecessor is true/false, then we can clone
// the condition into the predecessor and fix that value to true, saving some
@@ -1174,6 +1190,26 @@ bool JumpThreading::ProcessBranchOnXOR(BinaryOperator *BO) {
BlocksToFoldInto.push_back(XorOpValues[i].second);
}
+ // If we inferred a value for all of the predecessors, then duplication won't
+ // help us. However, we can just replace the LHS or RHS with the constant.
+ if (BlocksToFoldInto.size() ==
+ cast<PHINode>(BB->front()).getNumIncomingValues()) {
+ if (SplitVal == 0) {
+ // If all preds provide undef, just nuke the xor, because it is undef too.
+ BO->replaceAllUsesWith(UndefValue::get(BO->getType()));
+ BO->eraseFromParent();
+ } else if (SplitVal->isZero()) {
+ // If all preds provide 0, replace the xor with the other input.
+ BO->replaceAllUsesWith(BO->getOperand(isLHS));
+ BO->eraseFromParent();
+ } else {
+ // If all preds provide 1, set the computed value to 1.
+ BO->setOperand(!isLHS, SplitVal);
+ }
+
+ return true;
+ }
+
// Try to duplicate BB into PredBB.
return DuplicateCondBranchOnPHIIntoPred(BB, BlocksToFoldInto);
}
@@ -1393,9 +1429,9 @@ bool JumpThreading::DuplicateCondBranchOnPHIIntoPred(BasicBlock *BB,
// Unless PredBB ends with an unconditional branch, split the edge so that we
// can just clone the bits from BB into the end of the new PredBB.
- BranchInst *OldPredBranch = cast<BranchInst>(PredBB->getTerminator());
+ BranchInst *OldPredBranch = dyn_cast<BranchInst>(PredBB->getTerminator());
- if (!OldPredBranch->isUnconditional()) {
+ if (OldPredBranch == 0 || !OldPredBranch->isUnconditional()) {
PredBB = SplitEdge(PredBB, BB, this);
OldPredBranch = cast<BranchInst>(PredBB->getTerminator());
}
diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index fa820ed..240b298 100644
--- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -17,6 +17,40 @@
// available on the target, and it performs a variety of other optimizations
// related to loop induction variables.
//
+// Terminology note: this code has a lot of handling for "post-increment" or
+// "post-inc" users. This is not talking about post-increment addressing modes;
+// it is instead talking about code like this:
+//
+// %i = phi [ 0, %entry ], [ %i.next, %latch ]
+// ...
+// %i.next = add %i, 1
+// %c = icmp eq %i.next, %n
+//
+// The SCEV for %i is {0,+,1}<%L>. The SCEV for %i.next is {1,+,1}<%L>, however
+// it's useful to think about these as the same register, with some uses using
+// the value of the register before the add and some using // it after. In this
+// example, the icmp is a post-increment user, since it uses %i.next, which is
+// the value of the induction variable after the increment. The other common
+// case of post-increment users is users outside the loop.
+//
+// TODO: More sophistication in the way Formulae are generated and filtered.
+//
+// TODO: Handle multiple loops at a time.
+//
+// TODO: Should TargetLowering::AddrMode::BaseGV be changed to a ConstantExpr
+// instead of a GlobalValue?
+//
+// TODO: When truncation is free, truncate ICmp users' operands to make it a
+// smaller encoding (on x86 at least).
+//
+// TODO: When a negated register is used by an add (such as in a list of
+// multiple base registers, or as the increment expression in an addrec),
+// we may not actually need both reg and (-1 * reg) in registers; the
+// negation can be implemented by using a sub instead of an add. The
+// lack of support for taking this into consideration when making
+// register pressure decisions is partly worked around by the "Special"
+// use kind.
+//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "loop-reduce"
@@ -26,208 +60,401 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/IVUsers.h"
+#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionExpander.h"
-#include "llvm/Transforms/Utils/AddrModeMatcher.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLowering.h"
#include <algorithm>
using namespace llvm;
-STATISTIC(NumReduced , "Number of IV uses strength reduced");
-STATISTIC(NumInserted, "Number of PHIs inserted");
-STATISTIC(NumVariable, "Number of PHIs with variable strides");
-STATISTIC(NumEliminated, "Number of strides eliminated");
-STATISTIC(NumShadow, "Number of Shadow IVs optimized");
-STATISTIC(NumImmSunk, "Number of common expr immediates sunk into uses");
-STATISTIC(NumLoopCond, "Number of loop terminating conds optimized");
-STATISTIC(NumCountZero, "Number of count iv optimized to count toward zero");
+namespace {
+
+/// RegSortData - This class holds data which is used to order reuse candidates.
+class RegSortData {
+public:
+ /// UsedByIndices - This represents the set of LSRUse indices which reference
+ /// a particular register.
+ SmallBitVector UsedByIndices;
+
+ RegSortData() {}
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
-static cl::opt<bool> EnableFullLSRMode("enable-full-lsr",
- cl::init(false),
- cl::Hidden);
+}
+
+void RegSortData::print(raw_ostream &OS) const {
+ OS << "[NumUses=" << UsedByIndices.count() << ']';
+}
+
+void RegSortData::dump() const {
+ print(errs()); errs() << '\n';
+}
namespace {
- struct BasedUser;
+/// RegUseTracker - Map register candidates to information about how they are
+/// used.
+class RegUseTracker {
+ typedef DenseMap<const SCEV *, RegSortData> RegUsesTy;
- /// IVInfo - This structure keeps track of one IV expression inserted during
- /// StrengthReduceStridedIVUsers. It contains the stride, the common base, as
- /// well as the PHI node and increment value created for rewrite.
- struct IVExpr {
- const SCEV *Stride;
- const SCEV *Base;
- PHINode *PHI;
+ RegUsesTy RegUses;
+ SmallVector<const SCEV *, 16> RegSequence;
- IVExpr(const SCEV *const stride, const SCEV *const base, PHINode *phi)
- : Stride(stride), Base(base), PHI(phi) {}
- };
+public:
+ void CountRegister(const SCEV *Reg, size_t LUIdx);
+
+ bool isRegUsedByUsesOtherThan(const SCEV *Reg, size_t LUIdx) const;
+
+ const SmallBitVector &getUsedByIndices(const SCEV *Reg) const;
+
+ void clear();
+
+ typedef SmallVectorImpl<const SCEV *>::iterator iterator;
+ typedef SmallVectorImpl<const SCEV *>::const_iterator const_iterator;
+ iterator begin() { return RegSequence.begin(); }
+ iterator end() { return RegSequence.end(); }
+ const_iterator begin() const { return RegSequence.begin(); }
+ const_iterator end() const { return RegSequence.end(); }
+};
+
+}
- /// IVsOfOneStride - This structure keeps track of all IV expression inserted
- /// during StrengthReduceStridedIVUsers for a particular stride of the IV.
- struct IVsOfOneStride {
- std::vector<IVExpr> IVs;
+void
+RegUseTracker::CountRegister(const SCEV *Reg, size_t LUIdx) {
+ std::pair<RegUsesTy::iterator, bool> Pair =
+ RegUses.insert(std::make_pair(Reg, RegSortData()));
+ RegSortData &RSD = Pair.first->second;
+ if (Pair.second)
+ RegSequence.push_back(Reg);
+ RSD.UsedByIndices.resize(std::max(RSD.UsedByIndices.size(), LUIdx + 1));
+ RSD.UsedByIndices.set(LUIdx);
+}
+
+bool
+RegUseTracker::isRegUsedByUsesOtherThan(const SCEV *Reg, size_t LUIdx) const {
+ if (!RegUses.count(Reg)) return false;
+ const SmallBitVector &UsedByIndices =
+ RegUses.find(Reg)->second.UsedByIndices;
+ int i = UsedByIndices.find_first();
+ if (i == -1) return false;
+ if ((size_t)i != LUIdx) return true;
+ return UsedByIndices.find_next(i) != -1;
+}
+
+const SmallBitVector &RegUseTracker::getUsedByIndices(const SCEV *Reg) const {
+ RegUsesTy::const_iterator I = RegUses.find(Reg);
+ assert(I != RegUses.end() && "Unknown register!");
+ return I->second.UsedByIndices;
+}
+
+void RegUseTracker::clear() {
+ RegUses.clear();
+ RegSequence.clear();
+}
+
+namespace {
+
+/// Formula - This class holds information that describes a formula for
+/// computing satisfying a use. It may include broken-out immediates and scaled
+/// registers.
+struct Formula {
+ /// AM - This is used to represent complex addressing, as well as other kinds
+ /// of interesting uses.
+ TargetLowering::AddrMode AM;
+
+ /// BaseRegs - The list of "base" registers for this use. When this is
+ /// non-empty, AM.HasBaseReg should be set to true.
+ SmallVector<const SCEV *, 2> BaseRegs;
- void addIV(const SCEV *const Stride, const SCEV *const Base, PHINode *PHI) {
- IVs.push_back(IVExpr(Stride, Base, PHI));
+ /// ScaledReg - The 'scaled' register for this use. This should be non-null
+ /// when AM.Scale is not zero.
+ const SCEV *ScaledReg;
+
+ Formula() : ScaledReg(0) {}
+
+ void InitialMatch(const SCEV *S, Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT);
+
+ unsigned getNumRegs() const;
+ const Type *getType() const;
+
+ bool referencesReg(const SCEV *S) const;
+ bool hasRegsUsedByUsesOtherThan(size_t LUIdx,
+ const RegUseTracker &RegUses) const;
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
+
+}
+
+/// DoInitialMatch - Recurrsion helper for InitialMatch.
+static void DoInitialMatch(const SCEV *S, Loop *L,
+ SmallVectorImpl<const SCEV *> &Good,
+ SmallVectorImpl<const SCEV *> &Bad,
+ ScalarEvolution &SE, DominatorTree &DT) {
+ // Collect expressions which properly dominate the loop header.
+ if (S->properlyDominates(L->getHeader(), &DT)) {
+ Good.push_back(S);
+ return;
+ }
+
+ // Look at add operands.
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+ for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
+ I != E; ++I)
+ DoInitialMatch(*I, L, Good, Bad, SE, DT);
+ return;
+ }
+
+ // Look at addrec operands.
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S))
+ if (!AR->getStart()->isZero()) {
+ DoInitialMatch(AR->getStart(), L, Good, Bad, SE, DT);
+ DoInitialMatch(SE.getAddRecExpr(SE.getIntegerSCEV(0, AR->getType()),
+ AR->getStepRecurrence(SE),
+ AR->getLoop()),
+ L, Good, Bad, SE, DT);
+ return;
}
- };
- class LoopStrengthReduce : public LoopPass {
- IVUsers *IU;
- ScalarEvolution *SE;
- bool Changed;
-
- /// IVsByStride - Keep track of all IVs that have been inserted for a
- /// particular stride.
- std::map<const SCEV *, IVsOfOneStride> IVsByStride;
-
- /// DeadInsts - Keep track of instructions we may have made dead, so that
- /// we can remove them after we are done working.
- SmallVector<WeakVH, 16> DeadInsts;
-
- /// TLI - Keep a pointer of a TargetLowering to consult for determining
- /// transformation profitability.
- const TargetLowering *TLI;
-
- public:
- static char ID; // Pass ID, replacement for typeid
- explicit LoopStrengthReduce(const TargetLowering *tli = NULL) :
- LoopPass(&ID), TLI(tli) {}
-
- bool runOnLoop(Loop *L, LPPassManager &LPM);
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- // We split critical edges, so we change the CFG. However, we do update
- // many analyses if they are around.
- AU.addPreservedID(LoopSimplifyID);
- AU.addPreserved("loops");
- AU.addPreserved("domfrontier");
- AU.addPreserved("domtree");
-
- AU.addRequiredID(LoopSimplifyID);
- AU.addRequired<ScalarEvolution>();
- AU.addPreserved<ScalarEvolution>();
- AU.addRequired<IVUsers>();
- AU.addPreserved<IVUsers>();
+ // Handle a multiplication by -1 (negation) if it didn't fold.
+ if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S))
+ if (Mul->getOperand(0)->isAllOnesValue()) {
+ SmallVector<const SCEV *, 4> Ops(Mul->op_begin()+1, Mul->op_end());
+ const SCEV *NewMul = SE.getMulExpr(Ops);
+
+ SmallVector<const SCEV *, 4> MyGood;
+ SmallVector<const SCEV *, 4> MyBad;
+ DoInitialMatch(NewMul, L, MyGood, MyBad, SE, DT);
+ const SCEV *NegOne = SE.getSCEV(ConstantInt::getAllOnesValue(
+ SE.getEffectiveSCEVType(NewMul->getType())));
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = MyGood.begin(),
+ E = MyGood.end(); I != E; ++I)
+ Good.push_back(SE.getMulExpr(NegOne, *I));
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = MyBad.begin(),
+ E = MyBad.end(); I != E; ++I)
+ Bad.push_back(SE.getMulExpr(NegOne, *I));
+ return;
}
- private:
- void OptimizeIndvars(Loop *L);
-
- /// OptimizeLoopTermCond - Change loop terminating condition to use the
- /// postinc iv when possible.
- void OptimizeLoopTermCond(Loop *L);
-
- /// OptimizeShadowIV - If IV is used in a int-to-float cast
- /// inside the loop then try to eliminate the cast opeation.
- void OptimizeShadowIV(Loop *L);
-
- /// OptimizeMax - Rewrite the loop's terminating condition
- /// if it uses a max computation.
- ICmpInst *OptimizeMax(Loop *L, ICmpInst *Cond,
- IVStrideUse* &CondUse);
-
- /// OptimizeLoopCountIV - If, after all sharing of IVs, the IV used for
- /// deciding when to exit the loop is used only for that purpose, try to
- /// rearrange things so it counts down to a test against zero.
- bool OptimizeLoopCountIV(Loop *L);
- bool OptimizeLoopCountIVOfStride(const SCEV* &Stride,
- IVStrideUse* &CondUse, Loop *L);
-
- /// StrengthReduceIVUsersOfStride - Strength reduce all of the users of a
- /// single stride of IV. All of the users may have different starting
- /// values, and this may not be the only stride.
- void StrengthReduceIVUsersOfStride(const SCEV *Stride,
- IVUsersOfOneStride &Uses,
- Loop *L);
- void StrengthReduceIVUsers(Loop *L);
-
- ICmpInst *ChangeCompareStride(Loop *L, ICmpInst *Cond,
- IVStrideUse* &CondUse,
- const SCEV* &CondStride,
- bool PostPass = false);
-
- bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
- const SCEV* &CondStride);
- bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
- const SCEV *CheckForIVReuse(bool, bool, bool, const SCEV *,
- IVExpr&, const Type*,
- const std::vector<BasedUser>& UsersToProcess);
- bool ValidScale(bool, int64_t,
- const std::vector<BasedUser>& UsersToProcess);
- bool ValidOffset(bool, int64_t, int64_t,
- const std::vector<BasedUser>& UsersToProcess);
- const SCEV *CollectIVUsers(const SCEV *Stride,
- IVUsersOfOneStride &Uses,
- Loop *L,
- bool &AllUsesAreAddresses,
- bool &AllUsesAreOutsideLoop,
- std::vector<BasedUser> &UsersToProcess);
- bool StrideMightBeShared(const SCEV *Stride, Loop *L, bool CheckPreInc);
- bool ShouldUseFullStrengthReductionMode(
- const std::vector<BasedUser> &UsersToProcess,
- const Loop *L,
- bool AllUsesAreAddresses,
- const SCEV *Stride);
- void PrepareToStrengthReduceFully(
- std::vector<BasedUser> &UsersToProcess,
- const SCEV *Stride,
- const SCEV *CommonExprs,
- const Loop *L,
- SCEVExpander &PreheaderRewriter);
- void PrepareToStrengthReduceFromSmallerStride(
- std::vector<BasedUser> &UsersToProcess,
- Value *CommonBaseV,
- const IVExpr &ReuseIV,
- Instruction *PreInsertPt);
- void PrepareToStrengthReduceWithNewPhi(
- std::vector<BasedUser> &UsersToProcess,
- const SCEV *Stride,
- const SCEV *CommonExprs,
- Value *CommonBaseV,
- Instruction *IVIncInsertPt,
- const Loop *L,
- SCEVExpander &PreheaderRewriter);
-
- void DeleteTriviallyDeadInstructions();
- };
+ // Ok, we can't do anything interesting. Just stuff the whole thing into a
+ // register and hope for the best.
+ Bad.push_back(S);
}
-char LoopStrengthReduce::ID = 0;
-static RegisterPass<LoopStrengthReduce>
-X("loop-reduce", "Loop Strength Reduction");
+/// InitialMatch - Incorporate loop-variant parts of S into this Formula,
+/// attempting to keep all loop-invariant and loop-computable values in a
+/// single base register.
+void Formula::InitialMatch(const SCEV *S, Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT) {
+ SmallVector<const SCEV *, 4> Good;
+ SmallVector<const SCEV *, 4> Bad;
+ DoInitialMatch(S, L, Good, Bad, SE, DT);
+ if (!Good.empty()) {
+ BaseRegs.push_back(SE.getAddExpr(Good));
+ AM.HasBaseReg = true;
+ }
+ if (!Bad.empty()) {
+ BaseRegs.push_back(SE.getAddExpr(Bad));
+ AM.HasBaseReg = true;
+ }
+}
-Pass *llvm::createLoopStrengthReducePass(const TargetLowering *TLI) {
- return new LoopStrengthReduce(TLI);
+/// getNumRegs - Return the total number of register operands used by this
+/// formula. This does not include register uses implied by non-constant
+/// addrec strides.
+unsigned Formula::getNumRegs() const {
+ return !!ScaledReg + BaseRegs.size();
}
-/// DeleteTriviallyDeadInstructions - If any of the instructions is the
-/// specified set are trivially dead, delete them and see if this makes any of
-/// their operands subsequently dead.
-void LoopStrengthReduce::DeleteTriviallyDeadInstructions() {
- while (!DeadInsts.empty()) {
- Instruction *I = dyn_cast_or_null<Instruction>(DeadInsts.pop_back_val());
+/// getType - Return the type of this formula, if it has one, or null
+/// otherwise. This type is meaningless except for the bit size.
+const Type *Formula::getType() const {
+ return !BaseRegs.empty() ? BaseRegs.front()->getType() :
+ ScaledReg ? ScaledReg->getType() :
+ AM.BaseGV ? AM.BaseGV->getType() :
+ 0;
+}
- if (I == 0 || !isInstructionTriviallyDead(I))
- continue;
+/// referencesReg - Test if this formula references the given register.
+bool Formula::referencesReg(const SCEV *S) const {
+ return S == ScaledReg ||
+ std::find(BaseRegs.begin(), BaseRegs.end(), S) != BaseRegs.end();
+}
- for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI)
- if (Instruction *U = dyn_cast<Instruction>(*OI)) {
- *OI = 0;
- if (U->use_empty())
- DeadInsts.push_back(U);
+/// hasRegsUsedByUsesOtherThan - Test whether this formula uses registers
+/// which are used by uses other than the use with the given index.
+bool Formula::hasRegsUsedByUsesOtherThan(size_t LUIdx,
+ const RegUseTracker &RegUses) const {
+ if (ScaledReg)
+ if (RegUses.isRegUsedByUsesOtherThan(ScaledReg, LUIdx))
+ return true;
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = BaseRegs.begin(),
+ E = BaseRegs.end(); I != E; ++I)
+ if (RegUses.isRegUsedByUsesOtherThan(*I, LUIdx))
+ return true;
+ return false;
+}
+
+void Formula::print(raw_ostream &OS) const {
+ bool First = true;
+ if (AM.BaseGV) {
+ if (!First) OS << " + "; else First = false;
+ WriteAsOperand(OS, AM.BaseGV, /*PrintType=*/false);
+ }
+ if (AM.BaseOffs != 0) {
+ if (!First) OS << " + "; else First = false;
+ OS << AM.BaseOffs;
+ }
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = BaseRegs.begin(),
+ E = BaseRegs.end(); I != E; ++I) {
+ if (!First) OS << " + "; else First = false;
+ OS << "reg(" << **I << ')';
+ }
+ if (AM.Scale != 0) {
+ if (!First) OS << " + "; else First = false;
+ OS << AM.Scale << "*reg(";
+ if (ScaledReg)
+ OS << *ScaledReg;
+ else
+ OS << "<unknown>";
+ OS << ')';
+ }
+}
+
+void Formula::dump() const {
+ print(errs()); errs() << '\n';
+}
+
+/// getSDiv - Return an expression for LHS /s RHS, if it can be determined,
+/// or null otherwise. If IgnoreSignificantBits is true, expressions like
+/// (X * Y) /s Y are simplified to Y, ignoring that the multiplication may
+/// overflow, which is useful when the result will be used in a context where
+/// the most significant bits are ignored.
+static const SCEV *getSDiv(const SCEV *LHS, const SCEV *RHS,
+ ScalarEvolution &SE,
+ bool IgnoreSignificantBits = false) {
+ // Handle the trivial case, which works for any SCEV type.
+ if (LHS == RHS)
+ return SE.getIntegerSCEV(1, LHS->getType());
+
+ // Handle x /s -1 as x * -1, to give ScalarEvolution a chance to do some
+ // folding.
+ if (RHS->isAllOnesValue())
+ return SE.getMulExpr(LHS, RHS);
+
+ // Check for a division of a constant by a constant.
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(LHS)) {
+ const SCEVConstant *RC = dyn_cast<SCEVConstant>(RHS);
+ if (!RC)
+ return 0;
+ if (C->getValue()->getValue().srem(RC->getValue()->getValue()) != 0)
+ return 0;
+ return SE.getConstant(C->getValue()->getValue()
+ .sdiv(RC->getValue()->getValue()));
+ }
+
+ // Distribute the sdiv over addrec operands.
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHS)) {
+ const SCEV *Start = getSDiv(AR->getStart(), RHS, SE,
+ IgnoreSignificantBits);
+ if (!Start) return 0;
+ const SCEV *Step = getSDiv(AR->getStepRecurrence(SE), RHS, SE,
+ IgnoreSignificantBits);
+ if (!Step) return 0;
+ return SE.getAddRecExpr(Start, Step, AR->getLoop());
+ }
+
+ // Distribute the sdiv over add operands.
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(LHS)) {
+ SmallVector<const SCEV *, 8> Ops;
+ for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
+ I != E; ++I) {
+ const SCEV *Op = getSDiv(*I, RHS, SE,
+ IgnoreSignificantBits);
+ if (!Op) return 0;
+ Ops.push_back(Op);
+ }
+ return SE.getAddExpr(Ops);
+ }
+
+ // Check for a multiply operand that we can pull RHS out of.
+ if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(LHS))
+ if (IgnoreSignificantBits || Mul->hasNoSignedWrap()) {
+ SmallVector<const SCEV *, 4> Ops;
+ bool Found = false;
+ for (SCEVMulExpr::op_iterator I = Mul->op_begin(), E = Mul->op_end();
+ I != E; ++I) {
+ if (!Found)
+ if (const SCEV *Q = getSDiv(*I, RHS, SE, IgnoreSignificantBits)) {
+ Ops.push_back(Q);
+ Found = true;
+ continue;
+ }
+ Ops.push_back(*I);
}
+ return Found ? SE.getMulExpr(Ops) : 0;
+ }
- I->eraseFromParent();
- Changed = true;
+ // Otherwise we don't know.
+ return 0;
+}
+
+/// ExtractImmediate - If S involves the addition of a constant integer value,
+/// return that integer value, and mutate S to point to a new SCEV with that
+/// value excluded.
+static int64_t ExtractImmediate(const SCEV *&S, ScalarEvolution &SE) {
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S)) {
+ if (C->getValue()->getValue().getMinSignedBits() <= 64) {
+ S = SE.getIntegerSCEV(0, C->getType());
+ return C->getValue()->getSExtValue();
+ }
+ } else if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+ SmallVector<const SCEV *, 8> NewOps(Add->op_begin(), Add->op_end());
+ int64_t Result = ExtractImmediate(NewOps.front(), SE);
+ S = SE.getAddExpr(NewOps);
+ return Result;
+ } else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
+ SmallVector<const SCEV *, 8> NewOps(AR->op_begin(), AR->op_end());
+ int64_t Result = ExtractImmediate(NewOps.front(), SE);
+ S = SE.getAddRecExpr(NewOps, AR->getLoop());
+ return Result;
+ }
+ return 0;
+}
+
+/// ExtractSymbol - If S involves the addition of a GlobalValue address,
+/// return that symbol, and mutate S to point to a new SCEV with that
+/// value excluded.
+static GlobalValue *ExtractSymbol(const SCEV *&S, ScalarEvolution &SE) {
+ if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(U->getValue())) {
+ S = SE.getIntegerSCEV(0, GV->getType());
+ return GV;
+ }
+ } else if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+ SmallVector<const SCEV *, 8> NewOps(Add->op_begin(), Add->op_end());
+ GlobalValue *Result = ExtractSymbol(NewOps.back(), SE);
+ S = SE.getAddExpr(NewOps);
+ return Result;
+ } else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
+ SmallVector<const SCEV *, 8> NewOps(AR->op_begin(), AR->op_end());
+ GlobalValue *Result = ExtractSymbol(NewOps.front(), SE);
+ S = SE.getAddRecExpr(NewOps, AR->getLoop());
+ return Result;
}
+ return 0;
}
/// isAddressUse - Returns true if the specified instruction is using the
@@ -276,1775 +503,832 @@ static const Type *getAccessType(const Instruction *Inst) {
break;
}
}
- return AccessTy;
-}
-
-namespace {
- /// BasedUser - For a particular base value, keep information about how we've
- /// partitioned the expression so far.
- struct BasedUser {
- /// Base - The Base value for the PHI node that needs to be inserted for
- /// this use. As the use is processed, information gets moved from this
- /// field to the Imm field (below). BasedUser values are sorted by this
- /// field.
- const SCEV *Base;
-
- /// Inst - The instruction using the induction variable.
- Instruction *Inst;
-
- /// OperandValToReplace - The operand value of Inst to replace with the
- /// EmittedBase.
- Value *OperandValToReplace;
-
- /// Imm - The immediate value that should be added to the base immediately
- /// before Inst, because it will be folded into the imm field of the
- /// instruction. This is also sometimes used for loop-variant values that
- /// must be added inside the loop.
- const SCEV *Imm;
-
- /// Phi - The induction variable that performs the striding that
- /// should be used for this user.
- PHINode *Phi;
-
- // isUseOfPostIncrementedValue - True if this should use the
- // post-incremented version of this IV, not the preincremented version.
- // This can only be set in special cases, such as the terminating setcc
- // instruction for a loop and uses outside the loop that are dominated by
- // the loop.
- bool isUseOfPostIncrementedValue;
-
- BasedUser(IVStrideUse &IVSU, ScalarEvolution *se)
- : Base(IVSU.getOffset()), Inst(IVSU.getUser()),
- OperandValToReplace(IVSU.getOperandValToReplace()),
- Imm(se->getIntegerSCEV(0, Base->getType())),
- isUseOfPostIncrementedValue(IVSU.isUseOfPostIncrementedValue()) {}
-
- // Once we rewrite the code to insert the new IVs we want, update the
- // operands of Inst to use the new expression 'NewBase', with 'Imm' added
- // to it.
- void RewriteInstructionToUseNewBase(const SCEV *NewBase,
- Instruction *InsertPt,
- SCEVExpander &Rewriter, Loop *L, Pass *P,
- SmallVectorImpl<WeakVH> &DeadInsts,
- ScalarEvolution *SE);
-
- Value *InsertCodeForBaseAtPosition(const SCEV *NewBase,
- const Type *Ty,
- SCEVExpander &Rewriter,
- Instruction *IP,
- ScalarEvolution *SE);
- void dump() const;
- };
-}
-
-void BasedUser::dump() const {
- dbgs() << " Base=" << *Base;
- dbgs() << " Imm=" << *Imm;
- dbgs() << " Inst: " << *Inst;
-}
-
-Value *BasedUser::InsertCodeForBaseAtPosition(const SCEV *NewBase,
- const Type *Ty,
- SCEVExpander &Rewriter,
- Instruction *IP,
- ScalarEvolution *SE) {
- Value *Base = Rewriter.expandCodeFor(NewBase, 0, IP);
- // Wrap the base in a SCEVUnknown so that ScalarEvolution doesn't try to
- // re-analyze it.
- const SCEV *NewValSCEV = SE->getUnknown(Base);
+ // All pointers have the same requirements, so canonicalize them to an
+ // arbitrary pointer type to minimize variation.
+ if (const PointerType *PTy = dyn_cast<PointerType>(AccessTy))
+ AccessTy = PointerType::get(IntegerType::get(PTy->getContext(), 1),
+ PTy->getAddressSpace());
- // Always emit the immediate into the same block as the user.
- NewValSCEV = SE->getAddExpr(NewValSCEV, Imm);
-
- return Rewriter.expandCodeFor(NewValSCEV, Ty, IP);
+ return AccessTy;
}
+/// DeleteTriviallyDeadInstructions - If any of the instructions is the
+/// specified set are trivially dead, delete them and see if this makes any of
+/// their operands subsequently dead.
+static bool
+DeleteTriviallyDeadInstructions(SmallVectorImpl<WeakVH> &DeadInsts) {
+ bool Changed = false;
-// Once we rewrite the code to insert the new IVs we want, update the
-// operands of Inst to use the new expression 'NewBase', with 'Imm' added
-// to it. NewBasePt is the last instruction which contributes to the
-// value of NewBase in the case that it's a diffferent instruction from
-// the PHI that NewBase is computed from, or null otherwise.
-//
-void BasedUser::RewriteInstructionToUseNewBase(const SCEV *NewBase,
- Instruction *NewBasePt,
- SCEVExpander &Rewriter, Loop *L, Pass *P,
- SmallVectorImpl<WeakVH> &DeadInsts,
- ScalarEvolution *SE) {
- if (!isa<PHINode>(Inst)) {
- // By default, insert code at the user instruction.
- BasicBlock::iterator InsertPt = Inst;
-
- // However, if the Operand is itself an instruction, the (potentially
- // complex) inserted code may be shared by many users. Because of this, we
- // want to emit code for the computation of the operand right before its old
- // computation. This is usually safe, because we obviously used to use the
- // computation when it was computed in its current block. However, in some
- // cases (e.g. use of a post-incremented induction variable) the NewBase
- // value will be pinned to live somewhere after the original computation.
- // In this case, we have to back off.
- //
- // If this is a use outside the loop (which means after, since it is based
- // on a loop indvar) we use the post-incremented value, so that we don't
- // artificially make the preinc value live out the bottom of the loop.
- if (!isUseOfPostIncrementedValue && L->contains(Inst)) {
- if (NewBasePt && isa<PHINode>(OperandValToReplace)) {
- InsertPt = NewBasePt;
- ++InsertPt;
- } else if (Instruction *OpInst
- = dyn_cast<Instruction>(OperandValToReplace)) {
- InsertPt = OpInst;
- while (isa<PHINode>(InsertPt)) ++InsertPt;
- }
- }
- Value *NewVal = InsertCodeForBaseAtPosition(NewBase,
- OperandValToReplace->getType(),
- Rewriter, InsertPt, SE);
- // Replace the use of the operand Value with the new Phi we just created.
- Inst->replaceUsesOfWith(OperandValToReplace, NewVal);
-
- DEBUG(dbgs() << " Replacing with ");
- DEBUG(WriteAsOperand(dbgs(), NewVal, /*PrintType=*/false));
- DEBUG(dbgs() << ", which has value " << *NewBase << " plus IMM "
- << *Imm << "\n");
- return;
- }
+ while (!DeadInsts.empty()) {
+ Instruction *I = dyn_cast_or_null<Instruction>(DeadInsts.pop_back_val());
- // PHI nodes are more complex. We have to insert one copy of the NewBase+Imm
- // expression into each operand block that uses it. Note that PHI nodes can
- // have multiple entries for the same predecessor. We use a map to make sure
- // that a PHI node only has a single Value* for each predecessor (which also
- // prevents us from inserting duplicate code in some blocks).
- DenseMap<BasicBlock*, Value*> InsertedCode;
- PHINode *PN = cast<PHINode>(Inst);
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- if (PN->getIncomingValue(i) == OperandValToReplace) {
- // If the original expression is outside the loop, put the replacement
- // code in the same place as the original expression,
- // which need not be an immediate predecessor of this PHI. This way we
- // need only one copy of it even if it is referenced multiple times in
- // the PHI. We don't do this when the original expression is inside the
- // loop because multiple copies sometimes do useful sinking of code in
- // that case(?).
- Instruction *OldLoc = dyn_cast<Instruction>(OperandValToReplace);
- BasicBlock *PHIPred = PN->getIncomingBlock(i);
- if (L->contains(OldLoc)) {
- // If this is a critical edge, split the edge so that we do not insert
- // the code on all predecessor/successor paths. We do this unless this
- // is the canonical backedge for this loop, as this can make some
- // inserted code be in an illegal position.
- if (e != 1 && PHIPred->getTerminator()->getNumSuccessors() > 1 &&
- !isa<IndirectBrInst>(PHIPred->getTerminator()) &&
- (PN->getParent() != L->getHeader() || !L->contains(PHIPred))) {
-
- // First step, split the critical edge.
- BasicBlock *NewBB = SplitCriticalEdge(PHIPred, PN->getParent(),
- P, false);
-
- // Next step: move the basic block. In particular, if the PHI node
- // is outside of the loop, and PredTI is in the loop, we want to
- // move the block to be immediately before the PHI block, not
- // immediately after PredTI.
- if (L->contains(PHIPred) && !L->contains(PN))
- NewBB->moveBefore(PN->getParent());
+ if (I == 0 || !isInstructionTriviallyDead(I))
+ continue;
- // Splitting the edge can reduce the number of PHI entries we have.
- e = PN->getNumIncomingValues();
- PHIPred = NewBB;
- i = PN->getBasicBlockIndex(PHIPred);
- }
- }
- Value *&Code = InsertedCode[PHIPred];
- if (!Code) {
- // Insert the code into the end of the predecessor block.
- Instruction *InsertPt = (L->contains(OldLoc)) ?
- PHIPred->getTerminator() :
- OldLoc->getParent()->getTerminator();
- Code = InsertCodeForBaseAtPosition(NewBase, PN->getType(),
- Rewriter, InsertPt, SE);
-
- DEBUG(dbgs() << " Changing PHI use to ");
- DEBUG(WriteAsOperand(dbgs(), Code, /*PrintType=*/false));
- DEBUG(dbgs() << ", which has value " << *NewBase << " plus IMM "
- << *Imm << "\n");
+ for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI)
+ if (Instruction *U = dyn_cast<Instruction>(*OI)) {
+ *OI = 0;
+ if (U->use_empty())
+ DeadInsts.push_back(U);
}
- // Replace the use of the operand Value with the new Phi we just created.
- PN->setIncomingValue(i, Code);
- Rewriter.clear();
- }
+ I->eraseFromParent();
+ Changed = true;
}
- // PHI node might have become a constant value after SplitCriticalEdge.
- DeadInsts.push_back(Inst);
+ return Changed;
}
+namespace {
-/// fitsInAddressMode - Return true if V can be subsumed within an addressing
-/// mode, and does not need to be put in a register first.
-static bool fitsInAddressMode(const SCEV *V, const Type *AccessTy,
- const TargetLowering *TLI, bool HasBaseReg) {
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(V)) {
- int64_t VC = SC->getValue()->getSExtValue();
- if (TLI) {
- TargetLowering::AddrMode AM;
- AM.BaseOffs = VC;
- AM.HasBaseReg = HasBaseReg;
- return TLI->isLegalAddressingMode(AM, AccessTy);
- } else {
- // Defaults to PPC. PPC allows a sign-extended 16-bit immediate field.
- return (VC > -(1 << 16) && VC < (1 << 16)-1);
- }
- }
-
- if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(V))
- if (GlobalValue *GV = dyn_cast<GlobalValue>(SU->getValue())) {
- if (TLI) {
- TargetLowering::AddrMode AM;
- AM.BaseGV = GV;
- AM.HasBaseReg = HasBaseReg;
- return TLI->isLegalAddressingMode(AM, AccessTy);
- } else {
- // Default: assume global addresses are not legal.
- }
- }
+/// Cost - This class is used to measure and compare candidate formulae.
+class Cost {
+ /// TODO: Some of these could be merged. Also, a lexical ordering
+ /// isn't always optimal.
+ unsigned NumRegs;
+ unsigned AddRecCost;
+ unsigned NumIVMuls;
+ unsigned NumBaseAdds;
+ unsigned ImmCost;
+ unsigned SetupCost;
+
+public:
+ Cost()
+ : NumRegs(0), AddRecCost(0), NumIVMuls(0), NumBaseAdds(0), ImmCost(0),
+ SetupCost(0) {}
+
+ unsigned getNumRegs() const { return NumRegs; }
+
+ bool operator<(const Cost &Other) const;
+
+ void Loose();
+
+ void RateFormula(const Formula &F,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const DenseSet<const SCEV *> &VisitedRegs,
+ const Loop *L,
+ const SmallVectorImpl<int64_t> &Offsets,
+ ScalarEvolution &SE, DominatorTree &DT);
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+
+private:
+ void RateRegister(const SCEV *Reg,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT);
+ void RatePrimaryRegister(const SCEV *Reg,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT);
+};
- return false;
}
-/// MoveLoopVariantsToImmediateField - Move any subexpressions from Val that are
-/// loop varying to the Imm operand.
-static void MoveLoopVariantsToImmediateField(const SCEV *&Val, const SCEV *&Imm,
- Loop *L, ScalarEvolution *SE) {
- if (Val->isLoopInvariant(L)) return; // Nothing to do.
-
- if (const SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
- SmallVector<const SCEV *, 4> NewOps;
- NewOps.reserve(SAE->getNumOperands());
+/// RateRegister - Tally up interesting quantities from the given register.
+void Cost::RateRegister(const SCEV *Reg,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT) {
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Reg)) {
+ if (AR->getLoop() == L)
+ AddRecCost += 1; /// TODO: This should be a function of the stride.
+
+ // If this is an addrec for a loop that's already been visited by LSR,
+ // don't second-guess its addrec phi nodes. LSR isn't currently smart
+ // enough to reason about more than one loop at a time. Consider these
+ // registers free and leave them alone.
+ else if (L->contains(AR->getLoop()) ||
+ (!AR->getLoop()->contains(L) &&
+ DT.dominates(L->getHeader(), AR->getLoop()->getHeader()))) {
+ for (BasicBlock::iterator I = AR->getLoop()->getHeader()->begin();
+ PHINode *PN = dyn_cast<PHINode>(I); ++I)
+ if (SE.isSCEVable(PN->getType()) &&
+ (SE.getEffectiveSCEVType(PN->getType()) ==
+ SE.getEffectiveSCEVType(AR->getType())) &&
+ SE.getSCEV(PN) == AR)
+ return;
- for (unsigned i = 0; i != SAE->getNumOperands(); ++i)
- if (!SAE->getOperand(i)->isLoopInvariant(L)) {
- // If this is a loop-variant expression, it must stay in the immediate
- // field of the expression.
- Imm = SE->getAddExpr(Imm, SAE->getOperand(i));
- } else {
- NewOps.push_back(SAE->getOperand(i));
- }
+ // If this isn't one of the addrecs that the loop already has, it
+ // would require a costly new phi and add. TODO: This isn't
+ // precisely modeled right now.
+ ++NumBaseAdds;
+ if (!Regs.count(AR->getStart()))
+ RateRegister(AR->getStart(), Regs, L, SE, DT);
+ }
- if (NewOps.empty())
- Val = SE->getIntegerSCEV(0, Val->getType());
- else
- Val = SE->getAddExpr(NewOps);
- } else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
- // Try to pull immediates out of the start value of nested addrec's.
- const SCEV *Start = SARE->getStart();
- MoveLoopVariantsToImmediateField(Start, Imm, L, SE);
-
- SmallVector<const SCEV *, 4> Ops(SARE->op_begin(), SARE->op_end());
- Ops[0] = Start;
- Val = SE->getAddRecExpr(Ops, SARE->getLoop());
- } else {
- // Otherwise, all of Val is variant, move the whole thing over.
- Imm = SE->getAddExpr(Imm, Val);
- Val = SE->getIntegerSCEV(0, Val->getType());
+ // Add the step value register, if it needs one.
+ // TODO: The non-affine case isn't precisely modeled here.
+ if (!AR->isAffine() || !isa<SCEVConstant>(AR->getOperand(1)))
+ if (!Regs.count(AR->getStart()))
+ RateRegister(AR->getOperand(1), Regs, L, SE, DT);
}
+ ++NumRegs;
+
+ // Rough heuristic; favor registers which don't require extra setup
+ // instructions in the preheader.
+ if (!isa<SCEVUnknown>(Reg) &&
+ !isa<SCEVConstant>(Reg) &&
+ !(isa<SCEVAddRecExpr>(Reg) &&
+ (isa<SCEVUnknown>(cast<SCEVAddRecExpr>(Reg)->getStart()) ||
+ isa<SCEVConstant>(cast<SCEVAddRecExpr>(Reg)->getStart()))))
+ ++SetupCost;
}
+/// RatePrimaryRegister - Record this register in the set. If we haven't seen it
+/// before, rate it.
+void Cost::RatePrimaryRegister(const SCEV *Reg,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const Loop *L,
+ ScalarEvolution &SE, DominatorTree &DT) {
+ if (Regs.insert(Reg))
+ RateRegister(Reg, Regs, L, SE, DT);
+}
-/// MoveImmediateValues - Look at Val, and pull out any additions of constants
-/// that can fit into the immediate field of instructions in the target.
-/// Accumulate these immediate values into the Imm value.
-static void MoveImmediateValues(const TargetLowering *TLI,
- const Type *AccessTy,
- const SCEV *&Val, const SCEV *&Imm,
- bool isAddress, Loop *L,
- ScalarEvolution *SE) {
- if (const SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
- SmallVector<const SCEV *, 4> NewOps;
- NewOps.reserve(SAE->getNumOperands());
-
- for (unsigned i = 0; i != SAE->getNumOperands(); ++i) {
- const SCEV *NewOp = SAE->getOperand(i);
- MoveImmediateValues(TLI, AccessTy, NewOp, Imm, isAddress, L, SE);
-
- if (!NewOp->isLoopInvariant(L)) {
- // If this is a loop-variant expression, it must stay in the immediate
- // field of the expression.
- Imm = SE->getAddExpr(Imm, NewOp);
- } else {
- NewOps.push_back(NewOp);
- }
- }
-
- if (NewOps.empty())
- Val = SE->getIntegerSCEV(0, Val->getType());
- else
- Val = SE->getAddExpr(NewOps);
- return;
- } else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
- // Try to pull immediates out of the start value of nested addrec's.
- const SCEV *Start = SARE->getStart();
- MoveImmediateValues(TLI, AccessTy, Start, Imm, isAddress, L, SE);
-
- if (Start != SARE->getStart()) {
- SmallVector<const SCEV *, 4> Ops(SARE->op_begin(), SARE->op_end());
- Ops[0] = Start;
- Val = SE->getAddRecExpr(Ops, SARE->getLoop());
+void Cost::RateFormula(const Formula &F,
+ SmallPtrSet<const SCEV *, 16> &Regs,
+ const DenseSet<const SCEV *> &VisitedRegs,
+ const Loop *L,
+ const SmallVectorImpl<int64_t> &Offsets,
+ ScalarEvolution &SE, DominatorTree &DT) {
+ // Tally up the registers.
+ if (const SCEV *ScaledReg = F.ScaledReg) {
+ if (VisitedRegs.count(ScaledReg)) {
+ Loose();
+ return;
}
- return;
- } else if (const SCEVMulExpr *SME = dyn_cast<SCEVMulExpr>(Val)) {
- // Transform "8 * (4 + v)" -> "32 + 8*V" if "32" fits in the immed field.
- if (isAddress &&
- fitsInAddressMode(SME->getOperand(0), AccessTy, TLI, false) &&
- SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) {
-
- const SCEV *SubImm = SE->getIntegerSCEV(0, Val->getType());
- const SCEV *NewOp = SME->getOperand(1);
- MoveImmediateValues(TLI, AccessTy, NewOp, SubImm, isAddress, L, SE);
-
- // If we extracted something out of the subexpressions, see if we can
- // simplify this!
- if (NewOp != SME->getOperand(1)) {
- // Scale SubImm up by "8". If the result is a target constant, we are
- // good.
- SubImm = SE->getMulExpr(SubImm, SME->getOperand(0));
- if (fitsInAddressMode(SubImm, AccessTy, TLI, false)) {
- // Accumulate the immediate.
- Imm = SE->getAddExpr(Imm, SubImm);
-
- // Update what is left of 'Val'.
- Val = SE->getMulExpr(SME->getOperand(0), NewOp);
- return;
- }
- }
+ RatePrimaryRegister(ScaledReg, Regs, L, SE, DT);
+ }
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(),
+ E = F.BaseRegs.end(); I != E; ++I) {
+ const SCEV *BaseReg = *I;
+ if (VisitedRegs.count(BaseReg)) {
+ Loose();
+ return;
}
+ RatePrimaryRegister(BaseReg, Regs, L, SE, DT);
+
+ NumIVMuls += isa<SCEVMulExpr>(BaseReg) &&
+ BaseReg->hasComputableLoopEvolution(L);
}
- // Loop-variant expressions must stay in the immediate field of the
- // expression.
- if ((isAddress && fitsInAddressMode(Val, AccessTy, TLI, false)) ||
- !Val->isLoopInvariant(L)) {
- Imm = SE->getAddExpr(Imm, Val);
- Val = SE->getIntegerSCEV(0, Val->getType());
- return;
+ if (F.BaseRegs.size() > 1)
+ NumBaseAdds += F.BaseRegs.size() - 1;
+
+ // Tally up the non-zero immediates.
+ for (SmallVectorImpl<int64_t>::const_iterator I = Offsets.begin(),
+ E = Offsets.end(); I != E; ++I) {
+ int64_t Offset = (uint64_t)*I + F.AM.BaseOffs;
+ if (F.AM.BaseGV)
+ ImmCost += 64; // Handle symbolic values conservatively.
+ // TODO: This should probably be the pointer size.
+ else if (Offset != 0)
+ ImmCost += APInt(64, Offset, true).getMinSignedBits();
}
+}
- // Otherwise, no immediates to move.
+/// Loose - Set this cost to a loosing value.
+void Cost::Loose() {
+ NumRegs = ~0u;
+ AddRecCost = ~0u;
+ NumIVMuls = ~0u;
+ NumBaseAdds = ~0u;
+ ImmCost = ~0u;
+ SetupCost = ~0u;
}
-static void MoveImmediateValues(const TargetLowering *TLI,
- Instruction *User,
- const SCEV *&Val, const SCEV *&Imm,
- bool isAddress, Loop *L,
- ScalarEvolution *SE) {
- const Type *AccessTy = getAccessType(User);
- MoveImmediateValues(TLI, AccessTy, Val, Imm, isAddress, L, SE);
+/// operator< - Choose the lower cost.
+bool Cost::operator<(const Cost &Other) const {
+ if (NumRegs != Other.NumRegs)
+ return NumRegs < Other.NumRegs;
+ if (AddRecCost != Other.AddRecCost)
+ return AddRecCost < Other.AddRecCost;
+ if (NumIVMuls != Other.NumIVMuls)
+ return NumIVMuls < Other.NumIVMuls;
+ if (NumBaseAdds != Other.NumBaseAdds)
+ return NumBaseAdds < Other.NumBaseAdds;
+ if (ImmCost != Other.ImmCost)
+ return ImmCost < Other.ImmCost;
+ if (SetupCost != Other.SetupCost)
+ return SetupCost < Other.SetupCost;
+ return false;
}
-/// SeparateSubExprs - Decompose Expr into all of the subexpressions that are
-/// added together. This is used to reassociate common addition subexprs
-/// together for maximal sharing when rewriting bases.
-static void SeparateSubExprs(SmallVector<const SCEV *, 16> &SubExprs,
- const SCEV *Expr,
- ScalarEvolution *SE) {
- if (const SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Expr)) {
- for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
- SeparateSubExprs(SubExprs, AE->getOperand(j), SE);
- } else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Expr)) {
- const SCEV *Zero = SE->getIntegerSCEV(0, Expr->getType());
- if (SARE->getOperand(0) == Zero) {
- SubExprs.push_back(Expr);
- } else {
- // Compute the addrec with zero as its base.
- SmallVector<const SCEV *, 4> Ops(SARE->op_begin(), SARE->op_end());
- Ops[0] = Zero; // Start with zero base.
- SubExprs.push_back(SE->getAddRecExpr(Ops, SARE->getLoop()));
+void Cost::print(raw_ostream &OS) const {
+ OS << NumRegs << " reg" << (NumRegs == 1 ? "" : "s");
+ if (AddRecCost != 0)
+ OS << ", with addrec cost " << AddRecCost;
+ if (NumIVMuls != 0)
+ OS << ", plus " << NumIVMuls << " IV mul" << (NumIVMuls == 1 ? "" : "s");
+ if (NumBaseAdds != 0)
+ OS << ", plus " << NumBaseAdds << " base add"
+ << (NumBaseAdds == 1 ? "" : "s");
+ if (ImmCost != 0)
+ OS << ", plus " << ImmCost << " imm cost";
+ if (SetupCost != 0)
+ OS << ", plus " << SetupCost << " setup cost";
+}
+void Cost::dump() const {
+ print(errs()); errs() << '\n';
+}
- SeparateSubExprs(SubExprs, SARE->getOperand(0), SE);
- }
- } else if (!Expr->isZero()) {
- // Do not add zero.
- SubExprs.push_back(Expr);
- }
-}
-
-// This is logically local to the following function, but C++ says we have
-// to make it file scope.
-struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; };
-
-/// RemoveCommonExpressionsFromUseBases - Look through all of the Bases of all
-/// the Uses, removing any common subexpressions, except that if all such
-/// subexpressions can be folded into an addressing mode for all uses inside
-/// the loop (this case is referred to as "free" in comments herein) we do
-/// not remove anything. This looks for things like (a+b+c) and
-/// (a+c+d) and computes the common (a+c) subexpression. The common expression
-/// is *removed* from the Bases and returned.
-static const SCEV *
-RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
- ScalarEvolution *SE, Loop *L,
- const TargetLowering *TLI) {
- unsigned NumUses = Uses.size();
-
- // Only one use? This is a very common case, so we handle it specially and
- // cheaply.
- const SCEV *Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType());
- const SCEV *Result = Zero;
- const SCEV *FreeResult = Zero;
- if (NumUses == 1) {
- // If the use is inside the loop, use its base, regardless of what it is:
- // it is clearly shared across all the IV's. If the use is outside the loop
- // (which means after it) we don't want to factor anything *into* the loop,
- // so just use 0 as the base.
- if (L->contains(Uses[0].Inst))
- std::swap(Result, Uses[0].Base);
- return Result;
- }
+namespace {
- // To find common subexpressions, count how many of Uses use each expression.
- // If any subexpressions are used Uses.size() times, they are common.
- // Also track whether all uses of each expression can be moved into an
- // an addressing mode "for free"; such expressions are left within the loop.
- // struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; };
- std::map<const SCEV *, SubExprUseData> SubExpressionUseData;
-
- // UniqueSubExprs - Keep track of all of the subexpressions we see in the
- // order we see them.
- SmallVector<const SCEV *, 16> UniqueSubExprs;
-
- SmallVector<const SCEV *, 16> SubExprs;
- unsigned NumUsesInsideLoop = 0;
- for (unsigned i = 0; i != NumUses; ++i) {
- // If the user is outside the loop, just ignore it for base computation.
- // Since the user is outside the loop, it must be *after* the loop (if it
- // were before, it could not be based on the loop IV). We don't want users
- // after the loop to affect base computation of values *inside* the loop,
- // because we can always add their offsets to the result IV after the loop
- // is done, ensuring we get good code inside the loop.
- if (!L->contains(Uses[i].Inst))
- continue;
- NumUsesInsideLoop++;
+/// LSRFixup - An operand value in an instruction which is to be replaced
+/// with some equivalent, possibly strength-reduced, replacement.
+struct LSRFixup {
+ /// UserInst - The instruction which will be updated.
+ Instruction *UserInst;
- // If the base is zero (which is common), return zero now, there are no
- // CSEs we can find.
- if (Uses[i].Base == Zero) return Zero;
+ /// OperandValToReplace - The operand of the instruction which will
+ /// be replaced. The operand may be used more than once; every instance
+ /// will be replaced.
+ Value *OperandValToReplace;
- // If this use is as an address we may be able to put CSEs in the addressing
- // mode rather than hoisting them.
- bool isAddrUse = isAddressUse(Uses[i].Inst, Uses[i].OperandValToReplace);
- // We may need the AccessTy below, but only when isAddrUse, so compute it
- // only in that case.
- const Type *AccessTy = 0;
- if (isAddrUse)
- AccessTy = getAccessType(Uses[i].Inst);
-
- // Split the expression into subexprs.
- SeparateSubExprs(SubExprs, Uses[i].Base, SE);
- // Add one to SubExpressionUseData.Count for each subexpr present, and
- // if the subexpr is not a valid immediate within an addressing mode use,
- // set SubExpressionUseData.notAllUsesAreFree. We definitely want to
- // hoist these out of the loop (if they are common to all uses).
- for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) {
- if (++SubExpressionUseData[SubExprs[j]].Count == 1)
- UniqueSubExprs.push_back(SubExprs[j]);
- if (!isAddrUse || !fitsInAddressMode(SubExprs[j], AccessTy, TLI, false))
- SubExpressionUseData[SubExprs[j]].notAllUsesAreFree = true;
- }
- SubExprs.clear();
- }
-
- // Now that we know how many times each is used, build Result. Iterate over
- // UniqueSubexprs so that we have a stable ordering.
- for (unsigned i = 0, e = UniqueSubExprs.size(); i != e; ++i) {
- std::map<const SCEV *, SubExprUseData>::iterator I =
- SubExpressionUseData.find(UniqueSubExprs[i]);
- assert(I != SubExpressionUseData.end() && "Entry not found?");
- if (I->second.Count == NumUsesInsideLoop) { // Found CSE!
- if (I->second.notAllUsesAreFree)
- Result = SE->getAddExpr(Result, I->first);
- else
- FreeResult = SE->getAddExpr(FreeResult, I->first);
- } else
- // Remove non-cse's from SubExpressionUseData.
- SubExpressionUseData.erase(I);
- }
-
- if (FreeResult != Zero) {
- // We have some subexpressions that can be subsumed into addressing
- // modes in every use inside the loop. However, it's possible that
- // there are so many of them that the combined FreeResult cannot
- // be subsumed, or that the target cannot handle both a FreeResult
- // and a Result in the same instruction (for example because it would
- // require too many registers). Check this.
- for (unsigned i=0; i<NumUses; ++i) {
- if (!L->contains(Uses[i].Inst))
- continue;
- // We know this is an addressing mode use; if there are any uses that
- // are not, FreeResult would be Zero.
- const Type *AccessTy = getAccessType(Uses[i].Inst);
- if (!fitsInAddressMode(FreeResult, AccessTy, TLI, Result!=Zero)) {
- // FIXME: could split up FreeResult into pieces here, some hoisted
- // and some not. There is no obvious advantage to this.
- Result = SE->getAddExpr(Result, FreeResult);
- FreeResult = Zero;
- break;
- }
- }
- }
+ /// PostIncLoop - If this user is to use the post-incremented value of an
+ /// induction variable, this variable is non-null and holds the loop
+ /// associated with the induction variable.
+ const Loop *PostIncLoop;
- // If we found no CSE's, return now.
- if (Result == Zero) return Result;
+ /// LUIdx - The index of the LSRUse describing the expression which
+ /// this fixup needs, minus an offset (below).
+ size_t LUIdx;
- // If we still have a FreeResult, remove its subexpressions from
- // SubExpressionUseData. This means they will remain in the use Bases.
- if (FreeResult != Zero) {
- SeparateSubExprs(SubExprs, FreeResult, SE);
- for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) {
- std::map<const SCEV *, SubExprUseData>::iterator I =
- SubExpressionUseData.find(SubExprs[j]);
- SubExpressionUseData.erase(I);
- }
- SubExprs.clear();
- }
+ /// Offset - A constant offset to be added to the LSRUse expression.
+ /// This allows multiple fixups to share the same LSRUse with different
+ /// offsets, for example in an unrolled loop.
+ int64_t Offset;
- // Otherwise, remove all of the CSE's we found from each of the base values.
- for (unsigned i = 0; i != NumUses; ++i) {
- // Uses outside the loop don't necessarily include the common base, but
- // the final IV value coming into those uses does. Instead of trying to
- // remove the pieces of the common base, which might not be there,
- // subtract off the base to compensate for this.
- if (!L->contains(Uses[i].Inst)) {
- Uses[i].Base = SE->getMinusSCEV(Uses[i].Base, Result);
- continue;
- }
+ LSRFixup();
- // Split the expression into subexprs.
- SeparateSubExprs(SubExprs, Uses[i].Base, SE);
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
- // Remove any common subexpressions.
- for (unsigned j = 0, e = SubExprs.size(); j != e; ++j)
- if (SubExpressionUseData.count(SubExprs[j])) {
- SubExprs.erase(SubExprs.begin()+j);
- --j; --e;
- }
+}
- // Finally, add the non-shared expressions together.
- if (SubExprs.empty())
- Uses[i].Base = Zero;
- else
- Uses[i].Base = SE->getAddExpr(SubExprs);
- SubExprs.clear();
+LSRFixup::LSRFixup()
+ : UserInst(0), OperandValToReplace(0), PostIncLoop(0),
+ LUIdx(~size_t(0)), Offset(0) {}
+
+void LSRFixup::print(raw_ostream &OS) const {
+ OS << "UserInst=";
+ // Store is common and interesting enough to be worth special-casing.
+ if (StoreInst *Store = dyn_cast<StoreInst>(UserInst)) {
+ OS << "store ";
+ WriteAsOperand(OS, Store->getOperand(0), /*PrintType=*/false);
+ } else if (UserInst->getType()->isVoidTy())
+ OS << UserInst->getOpcodeName();
+ else
+ WriteAsOperand(OS, UserInst, /*PrintType=*/false);
+
+ OS << ", OperandValToReplace=";
+ WriteAsOperand(OS, OperandValToReplace, /*PrintType=*/false);
+
+ if (PostIncLoop) {
+ OS << ", PostIncLoop=";
+ WriteAsOperand(OS, PostIncLoop->getHeader(), /*PrintType=*/false);
}
- return Result;
-}
+ if (LUIdx != ~size_t(0))
+ OS << ", LUIdx=" << LUIdx;
-/// ValidScale - Check whether the given Scale is valid for all loads and
-/// stores in UsersToProcess.
-///
-bool LoopStrengthReduce::ValidScale(bool HasBaseReg, int64_t Scale,
- const std::vector<BasedUser>& UsersToProcess) {
- if (!TLI)
- return true;
+ if (Offset != 0)
+ OS << ", Offset=" << Offset;
+}
- for (unsigned i = 0, e = UsersToProcess.size(); i!=e; ++i) {
- // If this is a load or other access, pass the type of the access in.
- const Type *AccessTy =
- Type::getVoidTy(UsersToProcess[i].Inst->getContext());
- if (isAddressUse(UsersToProcess[i].Inst,
- UsersToProcess[i].OperandValToReplace))
- AccessTy = getAccessType(UsersToProcess[i].Inst);
- else if (isa<PHINode>(UsersToProcess[i].Inst))
- continue;
+void LSRFixup::dump() const {
+ print(errs()); errs() << '\n';
+}
- TargetLowering::AddrMode AM;
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(UsersToProcess[i].Imm))
- AM.BaseOffs = SC->getValue()->getSExtValue();
- AM.HasBaseReg = HasBaseReg || !UsersToProcess[i].Base->isZero();
- AM.Scale = Scale;
+namespace {
- // If load[imm+r*scale] is illegal, bail out.
- if (!TLI->isLegalAddressingMode(AM, AccessTy))
- return false;
+/// UniquifierDenseMapInfo - A DenseMapInfo implementation for holding
+/// DenseMaps and DenseSets of sorted SmallVectors of const SCEV*.
+struct UniquifierDenseMapInfo {
+ static SmallVector<const SCEV *, 2> getEmptyKey() {
+ SmallVector<const SCEV *, 2> V;
+ V.push_back(reinterpret_cast<const SCEV *>(-1));
+ return V;
}
- return true;
-}
-
-/// ValidOffset - Check whether the given Offset is valid for all loads and
-/// stores in UsersToProcess.
-///
-bool LoopStrengthReduce::ValidOffset(bool HasBaseReg,
- int64_t Offset,
- int64_t Scale,
- const std::vector<BasedUser>& UsersToProcess) {
- if (!TLI)
- return true;
- for (unsigned i=0, e = UsersToProcess.size(); i!=e; ++i) {
- // If this is a load or other access, pass the type of the access in.
- const Type *AccessTy =
- Type::getVoidTy(UsersToProcess[i].Inst->getContext());
- if (isAddressUse(UsersToProcess[i].Inst,
- UsersToProcess[i].OperandValToReplace))
- AccessTy = getAccessType(UsersToProcess[i].Inst);
- else if (isa<PHINode>(UsersToProcess[i].Inst))
- continue;
+ static SmallVector<const SCEV *, 2> getTombstoneKey() {
+ SmallVector<const SCEV *, 2> V;
+ V.push_back(reinterpret_cast<const SCEV *>(-2));
+ return V;
+ }
- TargetLowering::AddrMode AM;
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(UsersToProcess[i].Imm))
- AM.BaseOffs = SC->getValue()->getSExtValue();
- AM.BaseOffs = (uint64_t)AM.BaseOffs + (uint64_t)Offset;
- AM.HasBaseReg = HasBaseReg || !UsersToProcess[i].Base->isZero();
- AM.Scale = Scale;
+ static unsigned getHashValue(const SmallVector<const SCEV *, 2> &V) {
+ unsigned Result = 0;
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = V.begin(),
+ E = V.end(); I != E; ++I)
+ Result ^= DenseMapInfo<const SCEV *>::getHashValue(*I);
+ return Result;
+ }
- // If load[imm+r*scale] is illegal, bail out.
- if (!TLI->isLegalAddressingMode(AM, AccessTy))
- return false;
+ static bool isEqual(const SmallVector<const SCEV *, 2> &LHS,
+ const SmallVector<const SCEV *, 2> &RHS) {
+ return LHS == RHS;
}
- return true;
-}
+};
+
+/// LSRUse - This class holds the state that LSR keeps for each use in
+/// IVUsers, as well as uses invented by LSR itself. It includes information
+/// about what kinds of things can be folded into the user, information about
+/// the user itself, and information about how the use may be satisfied.
+/// TODO: Represent multiple users of the same expression in common?
+class LSRUse {
+ DenseSet<SmallVector<const SCEV *, 2>, UniquifierDenseMapInfo> Uniquifier;
+
+public:
+ /// KindType - An enum for a kind of use, indicating what types of
+ /// scaled and immediate operands it might support.
+ enum KindType {
+ Basic, ///< A normal use, with no folding.
+ Special, ///< A special case of basic, allowing -1 scales.
+ Address, ///< An address use; folding according to TargetLowering
+ ICmpZero ///< An equality icmp with both operands folded into one.
+ // TODO: Add a generic icmp too?
+ };
-/// RequiresTypeConversion - Returns true if converting Ty1 to Ty2 is not
-/// a nop.
-bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty1,
- const Type *Ty2) {
- if (Ty1 == Ty2)
- return false;
- Ty1 = SE->getEffectiveSCEVType(Ty1);
- Ty2 = SE->getEffectiveSCEVType(Ty2);
- if (Ty1 == Ty2)
- return false;
- if (Ty1->canLosslesslyBitCastTo(Ty2))
- return false;
- if (TLI && TLI->isTruncateFree(Ty1, Ty2))
- return false;
- return true;
-}
+ KindType Kind;
+ const Type *AccessTy;
-/// CheckForIVReuse - Returns the multiple if the stride is the multiple
-/// of a previous stride and it is a legal value for the target addressing
-/// mode scale component and optional base reg. This allows the users of
-/// this stride to be rewritten as prev iv * factor. It returns 0 if no
-/// reuse is possible. Factors can be negative on same targets, e.g. ARM.
-///
-/// If all uses are outside the loop, we don't require that all multiplies
-/// be folded into the addressing mode, nor even that the factor be constant;
-/// a multiply (executed once) outside the loop is better than another IV
-/// within. Well, usually.
-const SCEV *LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
- bool AllUsesAreAddresses,
- bool AllUsesAreOutsideLoop,
- const SCEV *Stride,
- IVExpr &IV, const Type *Ty,
- const std::vector<BasedUser>& UsersToProcess) {
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(Stride)) {
- int64_t SInt = SC->getValue()->getSExtValue();
- for (unsigned NewStride = 0, e = IU->StrideOrder.size();
- NewStride != e; ++NewStride) {
- std::map<const SCEV *, IVsOfOneStride>::iterator SI =
- IVsByStride.find(IU->StrideOrder[NewStride]);
- if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first))
- continue;
- // The other stride has no uses, don't reuse it.
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator UI =
- IU->IVUsesByStride.find(IU->StrideOrder[NewStride]);
- if (UI->second->Users.empty())
- continue;
- int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
- if (SI->first != Stride &&
- (unsigned(abs64(SInt)) < SSInt || (SInt % SSInt) != 0))
- continue;
- int64_t Scale = SInt / SSInt;
- // Check that this stride is valid for all the types used for loads and
- // stores; if it can be used for some and not others, we might as well use
- // the original stride everywhere, since we have to create the IV for it
- // anyway. If the scale is 1, then we don't need to worry about folding
- // multiplications.
- if (Scale == 1 ||
- (AllUsesAreAddresses &&
- ValidScale(HasBaseReg, Scale, UsersToProcess))) {
- // Prefer to reuse an IV with a base of zero.
- for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
- IE = SI->second.IVs.end(); II != IE; ++II)
- // Only reuse previous IV if it would not require a type conversion
- // and if the base difference can be folded.
- if (II->Base->isZero() &&
- !RequiresTypeConversion(II->Base->getType(), Ty)) {
- IV = *II;
- return SE->getIntegerSCEV(Scale, Stride->getType());
- }
- // Otherwise, settle for an IV with a foldable base.
- if (AllUsesAreAddresses)
- for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
- IE = SI->second.IVs.end(); II != IE; ++II)
- // Only reuse previous IV if it would not require a type conversion
- // and if the base difference can be folded.
- if (SE->getEffectiveSCEVType(II->Base->getType()) ==
- SE->getEffectiveSCEVType(Ty) &&
- isa<SCEVConstant>(II->Base)) {
- int64_t Base =
- cast<SCEVConstant>(II->Base)->getValue()->getSExtValue();
- if (Base > INT32_MIN && Base <= INT32_MAX &&
- ValidOffset(HasBaseReg, -Base * Scale,
- Scale, UsersToProcess)) {
- IV = *II;
- return SE->getIntegerSCEV(Scale, Stride->getType());
- }
- }
- }
- }
- } else if (AllUsesAreOutsideLoop) {
- // Accept nonconstant strides here; it is really really right to substitute
- // an existing IV if we can.
- for (unsigned NewStride = 0, e = IU->StrideOrder.size();
- NewStride != e; ++NewStride) {
- std::map<const SCEV *, IVsOfOneStride>::iterator SI =
- IVsByStride.find(IU->StrideOrder[NewStride]);
- if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first))
- continue;
- int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
- if (SI->first != Stride && SSInt != 1)
- continue;
- for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
- IE = SI->second.IVs.end(); II != IE; ++II)
- // Accept nonzero base here.
- // Only reuse previous IV if it would not require a type conversion.
- if (!RequiresTypeConversion(II->Base->getType(), Ty)) {
- IV = *II;
- return Stride;
- }
- }
- // Special case, old IV is -1*x and this one is x. Can treat this one as
- // -1*old.
- for (unsigned NewStride = 0, e = IU->StrideOrder.size();
- NewStride != e; ++NewStride) {
- std::map<const SCEV *, IVsOfOneStride>::iterator SI =
- IVsByStride.find(IU->StrideOrder[NewStride]);
- if (SI == IVsByStride.end())
- continue;
- if (const SCEVMulExpr *ME = dyn_cast<SCEVMulExpr>(SI->first))
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(ME->getOperand(0)))
- if (Stride == ME->getOperand(1) &&
- SC->getValue()->getSExtValue() == -1LL)
- for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
- IE = SI->second.IVs.end(); II != IE; ++II)
- // Accept nonzero base here.
- // Only reuse previous IV if it would not require type conversion.
- if (!RequiresTypeConversion(II->Base->getType(), Ty)) {
- IV = *II;
- return SE->getIntegerSCEV(-1LL, Stride->getType());
- }
- }
- }
- return SE->getIntegerSCEV(0, Stride->getType());
-}
-
-/// PartitionByIsUseOfPostIncrementedValue - Simple boolean predicate that
-/// returns true if Val's isUseOfPostIncrementedValue is true.
-static bool PartitionByIsUseOfPostIncrementedValue(const BasedUser &Val) {
- return Val.isUseOfPostIncrementedValue;
-}
-
-/// isNonConstantNegative - Return true if the specified scev is negated, but
-/// not a constant.
-static bool isNonConstantNegative(const SCEV *Expr) {
- const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(Expr);
- if (!Mul) return false;
-
- // If there is a constant factor, it will be first.
- const SCEVConstant *SC = dyn_cast<SCEVConstant>(Mul->getOperand(0));
- if (!SC) return false;
-
- // Return true if the value is negative, this matches things like (-42 * V).
- return SC->getValue()->getValue().isNegative();
-}
-
-/// CollectIVUsers - Transform our list of users and offsets to a bit more
-/// complex table. In this new vector, each 'BasedUser' contains 'Base', the
-/// base of the strided accesses, as well as the old information from Uses. We
-/// progressively move information from the Base field to the Imm field, until
-/// we eventually have the full access expression to rewrite the use.
-const SCEV *LoopStrengthReduce::CollectIVUsers(const SCEV *Stride,
- IVUsersOfOneStride &Uses,
- Loop *L,
- bool &AllUsesAreAddresses,
- bool &AllUsesAreOutsideLoop,
- std::vector<BasedUser> &UsersToProcess) {
- // FIXME: Generalize to non-affine IV's.
- if (!Stride->isLoopInvariant(L))
- return SE->getIntegerSCEV(0, Stride->getType());
-
- UsersToProcess.reserve(Uses.Users.size());
- for (ilist<IVStrideUse>::iterator I = Uses.Users.begin(),
- E = Uses.Users.end(); I != E; ++I) {
- UsersToProcess.push_back(BasedUser(*I, SE));
-
- // Move any loop variant operands from the offset field to the immediate
- // field of the use, so that we don't try to use something before it is
- // computed.
- MoveLoopVariantsToImmediateField(UsersToProcess.back().Base,
- UsersToProcess.back().Imm, L, SE);
- assert(UsersToProcess.back().Base->isLoopInvariant(L) &&
- "Base value is not loop invariant!");
- }
-
- // We now have a whole bunch of uses of like-strided induction variables, but
- // they might all have different bases. We want to emit one PHI node for this
- // stride which we fold as many common expressions (between the IVs) into as
- // possible. Start by identifying the common expressions in the base values
- // for the strides (e.g. if we have "A+C+B" and "A+B+D" as our bases, find
- // "A+B"), emit it to the preheader, then remove the expression from the
- // UsersToProcess base values.
- const SCEV *CommonExprs =
- RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L, TLI);
-
- // Next, figure out what we can represent in the immediate fields of
- // instructions. If we can represent anything there, move it to the imm
- // fields of the BasedUsers. We do this so that it increases the commonality
- // of the remaining uses.
- unsigned NumPHI = 0;
- bool HasAddress = false;
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
- // If the user is not in the current loop, this means it is using the exit
- // value of the IV. Do not put anything in the base, make sure it's all in
- // the immediate field to allow as much factoring as possible.
- if (!L->contains(UsersToProcess[i].Inst)) {
- UsersToProcess[i].Imm = SE->getAddExpr(UsersToProcess[i].Imm,
- UsersToProcess[i].Base);
- UsersToProcess[i].Base =
- SE->getIntegerSCEV(0, UsersToProcess[i].Base->getType());
- } else {
- // Not all uses are outside the loop.
- AllUsesAreOutsideLoop = false;
-
- // Addressing modes can be folded into loads and stores. Be careful that
- // the store is through the expression, not of the expression though.
- bool isPHI = false;
- bool isAddress = isAddressUse(UsersToProcess[i].Inst,
- UsersToProcess[i].OperandValToReplace);
- if (isa<PHINode>(UsersToProcess[i].Inst)) {
- isPHI = true;
- ++NumPHI;
- }
+ SmallVector<int64_t, 8> Offsets;
+ int64_t MinOffset;
+ int64_t MaxOffset;
- if (isAddress)
- HasAddress = true;
+ /// AllFixupsOutsideLoop - This records whether all of the fixups using this
+ /// LSRUse are outside of the loop, in which case some special-case heuristics
+ /// may be used.
+ bool AllFixupsOutsideLoop;
- // If this use isn't an address, then not all uses are addresses.
- if (!isAddress && !isPHI)
- AllUsesAreAddresses = false;
+ /// Formulae - A list of ways to build a value that can satisfy this user.
+ /// After the list is populated, one of these is selected heuristically and
+ /// used to formulate a replacement for OperandValToReplace in UserInst.
+ SmallVector<Formula, 12> Formulae;
- MoveImmediateValues(TLI, UsersToProcess[i].Inst, UsersToProcess[i].Base,
- UsersToProcess[i].Imm, isAddress, L, SE);
- }
- }
+ /// Regs - The set of register candidates used by all formulae in this LSRUse.
+ SmallPtrSet<const SCEV *, 4> Regs;
- // If one of the use is a PHI node and all other uses are addresses, still
- // allow iv reuse. Essentially we are trading one constant multiplication
- // for one fewer iv.
- if (NumPHI > 1)
- AllUsesAreAddresses = false;
+ LSRUse(KindType K, const Type *T) : Kind(K), AccessTy(T),
+ MinOffset(INT64_MAX),
+ MaxOffset(INT64_MIN),
+ AllFixupsOutsideLoop(true) {}
- // There are no in-loop address uses.
- if (AllUsesAreAddresses && (!HasAddress && !AllUsesAreOutsideLoop))
- AllUsesAreAddresses = false;
+ bool InsertFormula(size_t LUIdx, const Formula &F);
- return CommonExprs;
-}
+ void check() const;
-/// ShouldUseFullStrengthReductionMode - Test whether full strength-reduction
-/// is valid and profitable for the given set of users of a stride. In
-/// full strength-reduction mode, all addresses at the current stride are
-/// strength-reduced all the way down to pointer arithmetic.
-///
-bool LoopStrengthReduce::ShouldUseFullStrengthReductionMode(
- const std::vector<BasedUser> &UsersToProcess,
- const Loop *L,
- bool AllUsesAreAddresses,
- const SCEV *Stride) {
- if (!EnableFullLSRMode)
- return false;
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
- // The heuristics below aim to avoid increasing register pressure, but
- // fully strength-reducing all the addresses increases the number of
- // add instructions, so don't do this when optimizing for size.
- // TODO: If the loop is large, the savings due to simpler addresses
- // may oughtweight the costs of the extra increment instructions.
- if (L->getHeader()->getParent()->hasFnAttr(Attribute::OptimizeForSize))
- return false;
+/// InsertFormula - If the given formula has not yet been inserted, add it to
+/// the list, and return true. Return false otherwise.
+bool LSRUse::InsertFormula(size_t LUIdx, const Formula &F) {
+ SmallVector<const SCEV *, 2> Key = F.BaseRegs;
+ if (F.ScaledReg) Key.push_back(F.ScaledReg);
+ // Unstable sort by host order ok, because this is only used for uniquifying.
+ std::sort(Key.begin(), Key.end());
- // TODO: For now, don't do full strength reduction if there could
- // potentially be greater-stride multiples of the current stride
- // which could reuse the current stride IV.
- if (IU->StrideOrder.back() != Stride)
+ if (!Uniquifier.insert(Key).second)
return false;
- // Iterate through the uses to find conditions that automatically rule out
- // full-lsr mode.
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ) {
- const SCEV *Base = UsersToProcess[i].Base;
- const SCEV *Imm = UsersToProcess[i].Imm;
- // If any users have a loop-variant component, they can't be fully
- // strength-reduced.
- if (Imm && !Imm->isLoopInvariant(L))
- return false;
- // If there are to users with the same base and the difference between
- // the two Imm values can't be folded into the address, full
- // strength reduction would increase register pressure.
- do {
- const SCEV *CurImm = UsersToProcess[i].Imm;
- if ((CurImm || Imm) && CurImm != Imm) {
- if (!CurImm) CurImm = SE->getIntegerSCEV(0, Stride->getType());
- if (!Imm) Imm = SE->getIntegerSCEV(0, Stride->getType());
- const Instruction *Inst = UsersToProcess[i].Inst;
- const Type *AccessTy = getAccessType(Inst);
- const SCEV *Diff = SE->getMinusSCEV(UsersToProcess[i].Imm, Imm);
- if (!Diff->isZero() &&
- (!AllUsesAreAddresses ||
- !fitsInAddressMode(Diff, AccessTy, TLI, /*HasBaseReg=*/true)))
- return false;
- }
- } while (++i != e && Base == UsersToProcess[i].Base);
- }
+ // Using a register to hold the value of 0 is not profitable.
+ assert((!F.ScaledReg || !F.ScaledReg->isZero()) &&
+ "Zero allocated in a scaled register!");
+#ifndef NDEBUG
+ for (SmallVectorImpl<const SCEV *>::const_iterator I =
+ F.BaseRegs.begin(), E = F.BaseRegs.end(); I != E; ++I)
+ assert(!(*I)->isZero() && "Zero allocated in a base register!");
+#endif
- // If there's exactly one user in this stride, fully strength-reducing it
- // won't increase register pressure. If it's starting from a non-zero base,
- // it'll be simpler this way.
- if (UsersToProcess.size() == 1 && !UsersToProcess[0].Base->isZero())
- return true;
+ // Add the formula to the list.
+ Formulae.push_back(F);
- // Otherwise, if there are any users in this stride that don't require
- // a register for their base, full strength-reduction will increase
- // register pressure.
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
- if (UsersToProcess[i].Base->isZero())
- return false;
+ // Record registers now being used by this use.
+ if (F.ScaledReg) Regs.insert(F.ScaledReg);
+ Regs.insert(F.BaseRegs.begin(), F.BaseRegs.end());
- // Otherwise, go for it.
return true;
}
-/// InsertAffinePhi Create and insert a PHI node for an induction variable
-/// with the specified start and step values in the specified loop.
-///
-/// If NegateStride is true, the stride should be negated by using a
-/// subtract instead of an add.
-///
-/// Return the created phi node.
-///
-static PHINode *InsertAffinePhi(const SCEV *Start, const SCEV *Step,
- Instruction *IVIncInsertPt,
- const Loop *L,
- SCEVExpander &Rewriter) {
- assert(Start->isLoopInvariant(L) && "New PHI start is not loop invariant!");
- assert(Step->isLoopInvariant(L) && "New PHI stride is not loop invariant!");
-
- BasicBlock *Header = L->getHeader();
- BasicBlock *Preheader = L->getLoopPreheader();
- BasicBlock *LatchBlock = L->getLoopLatch();
- const Type *Ty = Start->getType();
- Ty = Rewriter.SE.getEffectiveSCEVType(Ty);
-
- PHINode *PN = PHINode::Create(Ty, "lsr.iv", Header->begin());
- PN->addIncoming(Rewriter.expandCodeFor(Start, Ty, Preheader->getTerminator()),
- Preheader);
-
- // If the stride is negative, insert a sub instead of an add for the
- // increment.
- bool isNegative = isNonConstantNegative(Step);
- const SCEV *IncAmount = Step;
- if (isNegative)
- IncAmount = Rewriter.SE.getNegativeSCEV(Step);
-
- // Insert an add instruction right before the terminator corresponding
- // to the back-edge or just before the only use. The location is determined
- // by the caller and passed in as IVIncInsertPt.
- Value *StepV = Rewriter.expandCodeFor(IncAmount, Ty,
- Preheader->getTerminator());
- Instruction *IncV;
- if (isNegative) {
- IncV = BinaryOperator::CreateSub(PN, StepV, "lsr.iv.next",
- IVIncInsertPt);
- } else {
- IncV = BinaryOperator::CreateAdd(PN, StepV, "lsr.iv.next",
- IVIncInsertPt);
- }
- if (!isa<ConstantInt>(StepV)) ++NumVariable;
-
- PN->addIncoming(IncV, LatchBlock);
-
- ++NumInserted;
- return PN;
-}
-
-static void SortUsersToProcess(std::vector<BasedUser> &UsersToProcess) {
- // We want to emit code for users inside the loop first. To do this, we
- // rearrange BasedUser so that the entries at the end have
- // isUseOfPostIncrementedValue = false, because we pop off the end of the
- // vector (so we handle them first).
- std::partition(UsersToProcess.begin(), UsersToProcess.end(),
- PartitionByIsUseOfPostIncrementedValue);
-
- // Sort this by base, so that things with the same base are handled
- // together. By partitioning first and stable-sorting later, we are
- // guaranteed that within each base we will pop off users from within the
- // loop before users outside of the loop with a particular base.
- //
- // We would like to use stable_sort here, but we can't. The problem is that
- // const SCEV *'s don't have a deterministic ordering w.r.t to each other, so
- // we don't have anything to do a '<' comparison on. Because we think the
- // number of uses is small, do a horrible bubble sort which just relies on
- // ==.
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
- // Get a base value.
- const SCEV *Base = UsersToProcess[i].Base;
-
- // Compact everything with this base to be consecutive with this one.
- for (unsigned j = i+1; j != e; ++j) {
- if (UsersToProcess[j].Base == Base) {
- std::swap(UsersToProcess[i+1], UsersToProcess[j]);
- ++i;
- }
- }
+void LSRUse::print(raw_ostream &OS) const {
+ OS << "LSR Use: Kind=";
+ switch (Kind) {
+ case Basic: OS << "Basic"; break;
+ case Special: OS << "Special"; break;
+ case ICmpZero: OS << "ICmpZero"; break;
+ case Address:
+ OS << "Address of ";
+ if (isa<PointerType>(AccessTy))
+ OS << "pointer"; // the full pointer type could be really verbose
+ else
+ OS << *AccessTy;
}
-}
-/// PrepareToStrengthReduceFully - Prepare to fully strength-reduce
-/// UsersToProcess, meaning lowering addresses all the way down to direct
-/// pointer arithmetic.
-///
-void
-LoopStrengthReduce::PrepareToStrengthReduceFully(
- std::vector<BasedUser> &UsersToProcess,
- const SCEV *Stride,
- const SCEV *CommonExprs,
- const Loop *L,
- SCEVExpander &PreheaderRewriter) {
- DEBUG(dbgs() << " Fully reducing all users\n");
-
- // Rewrite the UsersToProcess records, creating a separate PHI for each
- // unique Base value.
- Instruction *IVIncInsertPt = L->getLoopLatch()->getTerminator();
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ) {
- // TODO: The uses are grouped by base, but not sorted. We arbitrarily
- // pick the first Imm value here to start with, and adjust it for the
- // other uses.
- const SCEV *Imm = UsersToProcess[i].Imm;
- const SCEV *Base = UsersToProcess[i].Base;
- const SCEV *Start = SE->getAddExpr(CommonExprs, Base, Imm);
- PHINode *Phi = InsertAffinePhi(Start, Stride, IVIncInsertPt, L,
- PreheaderRewriter);
- // Loop over all the users with the same base.
- do {
- UsersToProcess[i].Base = SE->getIntegerSCEV(0, Stride->getType());
- UsersToProcess[i].Imm = SE->getMinusSCEV(UsersToProcess[i].Imm, Imm);
- UsersToProcess[i].Phi = Phi;
- assert(UsersToProcess[i].Imm->isLoopInvariant(L) &&
- "ShouldUseFullStrengthReductionMode should reject this!");
- } while (++i != e && Base == UsersToProcess[i].Base);
- }
-}
-
-/// FindIVIncInsertPt - Return the location to insert the increment instruction.
-/// If the only use if a use of postinc value, (must be the loop termination
-/// condition), then insert it just before the use.
-static Instruction *FindIVIncInsertPt(std::vector<BasedUser> &UsersToProcess,
- const Loop *L) {
- if (UsersToProcess.size() == 1 &&
- UsersToProcess[0].isUseOfPostIncrementedValue &&
- L->contains(UsersToProcess[0].Inst))
- return UsersToProcess[0].Inst;
- return L->getLoopLatch()->getTerminator();
-}
-
-/// PrepareToStrengthReduceWithNewPhi - Insert a new induction variable for the
-/// given users to share.
-///
-void
-LoopStrengthReduce::PrepareToStrengthReduceWithNewPhi(
- std::vector<BasedUser> &UsersToProcess,
- const SCEV *Stride,
- const SCEV *CommonExprs,
- Value *CommonBaseV,
- Instruction *IVIncInsertPt,
- const Loop *L,
- SCEVExpander &PreheaderRewriter) {
- DEBUG(dbgs() << " Inserting new PHI:\n");
-
- PHINode *Phi = InsertAffinePhi(SE->getUnknown(CommonBaseV),
- Stride, IVIncInsertPt, L,
- PreheaderRewriter);
-
- // Remember this in case a later stride is multiple of this.
- IVsByStride[Stride].addIV(Stride, CommonExprs, Phi);
-
- // All the users will share this new IV.
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
- UsersToProcess[i].Phi = Phi;
-
- DEBUG(dbgs() << " IV=");
- DEBUG(WriteAsOperand(dbgs(), Phi, /*PrintType=*/false));
- DEBUG(dbgs() << "\n");
-}
-
-/// PrepareToStrengthReduceFromSmallerStride - Prepare for the given users to
-/// reuse an induction variable with a stride that is a factor of the current
-/// induction variable.
-///
-void
-LoopStrengthReduce::PrepareToStrengthReduceFromSmallerStride(
- std::vector<BasedUser> &UsersToProcess,
- Value *CommonBaseV,
- const IVExpr &ReuseIV,
- Instruction *PreInsertPt) {
- DEBUG(dbgs() << " Rewriting in terms of existing IV of STRIDE "
- << *ReuseIV.Stride << " and BASE " << *ReuseIV.Base << "\n");
-
- // All the users will share the reused IV.
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
- UsersToProcess[i].Phi = ReuseIV.PHI;
-
- Constant *C = dyn_cast<Constant>(CommonBaseV);
- if (C &&
- (!C->isNullValue() &&
- !fitsInAddressMode(SE->getUnknown(CommonBaseV), CommonBaseV->getType(),
- TLI, false)))
- // We want the common base emitted into the preheader! This is just
- // using cast as a copy so BitCast (no-op cast) is appropriate
- CommonBaseV = new BitCastInst(CommonBaseV, CommonBaseV->getType(),
- "commonbase", PreInsertPt);
-}
-
-static bool IsImmFoldedIntoAddrMode(GlobalValue *GV, int64_t Offset,
- const Type *AccessTy,
- std::vector<BasedUser> &UsersToProcess,
- const TargetLowering *TLI) {
- SmallVector<Instruction*, 16> AddrModeInsts;
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
- if (UsersToProcess[i].isUseOfPostIncrementedValue)
- continue;
- ExtAddrMode AddrMode =
- AddressingModeMatcher::Match(UsersToProcess[i].OperandValToReplace,
- AccessTy, UsersToProcess[i].Inst,
- AddrModeInsts, *TLI);
- if (GV && GV != AddrMode.BaseGV)
- return false;
- if (Offset && !AddrMode.BaseOffs)
- // FIXME: How to accurate check it's immediate offset is folded.
- return false;
- AddrModeInsts.clear();
+ OS << ", Offsets={";
+ for (SmallVectorImpl<int64_t>::const_iterator I = Offsets.begin(),
+ E = Offsets.end(); I != E; ++I) {
+ OS << *I;
+ if (next(I) != E)
+ OS << ',';
}
- return true;
-}
+ OS << '}';
-/// StrengthReduceIVUsersOfStride - Strength reduce all of the users of a single
-/// stride of IV. All of the users may have different starting values, and this
-/// may not be the only stride.
-void
-LoopStrengthReduce::StrengthReduceIVUsersOfStride(const SCEV *Stride,
- IVUsersOfOneStride &Uses,
- Loop *L) {
- // If all the users are moved to another stride, then there is nothing to do.
- if (Uses.Users.empty())
- return;
+ if (AllFixupsOutsideLoop)
+ OS << ", all-fixups-outside-loop";
+}
- // Keep track if every use in UsersToProcess is an address. If they all are,
- // we may be able to rewrite the entire collection of them in terms of a
- // smaller-stride IV.
- bool AllUsesAreAddresses = true;
-
- // Keep track if every use of a single stride is outside the loop. If so,
- // we want to be more aggressive about reusing a smaller-stride IV; a
- // multiply outside the loop is better than another IV inside. Well, usually.
- bool AllUsesAreOutsideLoop = true;
-
- // Transform our list of users and offsets to a bit more complex table. In
- // this new vector, each 'BasedUser' contains 'Base' the base of the
- // strided accessas well as the old information from Uses. We progressively
- // move information from the Base field to the Imm field, until we eventually
- // have the full access expression to rewrite the use.
- std::vector<BasedUser> UsersToProcess;
- const SCEV *CommonExprs = CollectIVUsers(Stride, Uses, L, AllUsesAreAddresses,
- AllUsesAreOutsideLoop,
- UsersToProcess);
-
- // Sort the UsersToProcess array so that users with common bases are
- // next to each other.
- SortUsersToProcess(UsersToProcess);
-
- // If we managed to find some expressions in common, we'll need to carry
- // their value in a register and add it in for each use. This will take up
- // a register operand, which potentially restricts what stride values are
- // valid.
- bool HaveCommonExprs = !CommonExprs->isZero();
- const Type *ReplacedTy = CommonExprs->getType();
-
- // If all uses are addresses, consider sinking the immediate part of the
- // common expression back into uses if they can fit in the immediate fields.
- if (TLI && HaveCommonExprs && AllUsesAreAddresses) {
- const SCEV *NewCommon = CommonExprs;
- const SCEV *Imm = SE->getIntegerSCEV(0, ReplacedTy);
- MoveImmediateValues(TLI, Type::getVoidTy(
- L->getLoopPreheader()->getContext()),
- NewCommon, Imm, true, L, SE);
- if (!Imm->isZero()) {
- bool DoSink = true;
-
- // If the immediate part of the common expression is a GV, check if it's
- // possible to fold it into the target addressing mode.
- GlobalValue *GV = 0;
- if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(Imm))
- GV = dyn_cast<GlobalValue>(SU->getValue());
- int64_t Offset = 0;
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(Imm))
- Offset = SC->getValue()->getSExtValue();
- if (GV || Offset)
- // Pass VoidTy as the AccessTy to be conservative, because
- // there could be multiple access types among all the uses.
- DoSink = IsImmFoldedIntoAddrMode(GV, Offset,
- Type::getVoidTy(L->getLoopPreheader()->getContext()),
- UsersToProcess, TLI);
-
- if (DoSink) {
- DEBUG(dbgs() << " Sinking " << *Imm << " back down into uses\n");
- for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
- UsersToProcess[i].Imm = SE->getAddExpr(UsersToProcess[i].Imm, Imm);
- CommonExprs = NewCommon;
- HaveCommonExprs = !CommonExprs->isZero();
- ++NumImmSunk;
- }
- }
- }
+void LSRUse::dump() const {
+ print(errs()); errs() << '\n';
+}
- // Now that we know what we need to do, insert the PHI node itself.
- //
- DEBUG(dbgs() << "LSR: Examining IVs of TYPE " << *ReplacedTy << " of STRIDE "
- << *Stride << ":\n"
- << " Common base: " << *CommonExprs << "\n");
+/// isLegalUse - Test whether the use described by AM is "legal", meaning it can
+/// be completely folded into the user instruction at isel time. This includes
+/// address-mode folding and special icmp tricks.
+static bool isLegalUse(const TargetLowering::AddrMode &AM,
+ LSRUse::KindType Kind, const Type *AccessTy,
+ const TargetLowering *TLI) {
+ switch (Kind) {
+ case LSRUse::Address:
+ // If we have low-level target information, ask the target if it can
+ // completely fold this address.
+ if (TLI) return TLI->isLegalAddressingMode(AM, AccessTy);
+
+ // Otherwise, just guess that reg+reg addressing is legal.
+ return !AM.BaseGV && AM.BaseOffs == 0 && AM.Scale <= 1;
+
+ case LSRUse::ICmpZero:
+ // There's not even a target hook for querying whether it would be legal to
+ // fold a GV into an ICmp.
+ if (AM.BaseGV)
+ return false;
- SCEVExpander Rewriter(*SE);
- SCEVExpander PreheaderRewriter(*SE);
+ // ICmp only has two operands; don't allow more than two non-trivial parts.
+ if (AM.Scale != 0 && AM.HasBaseReg && AM.BaseOffs != 0)
+ return false;
- BasicBlock *Preheader = L->getLoopPreheader();
- Instruction *PreInsertPt = Preheader->getTerminator();
- BasicBlock *LatchBlock = L->getLoopLatch();
- Instruction *IVIncInsertPt = LatchBlock->getTerminator();
-
- Value *CommonBaseV = Constant::getNullValue(ReplacedTy);
-
- const SCEV *RewriteFactor = SE->getIntegerSCEV(0, ReplacedTy);
- IVExpr ReuseIV(SE->getIntegerSCEV(0,
- Type::getInt32Ty(Preheader->getContext())),
- SE->getIntegerSCEV(0,
- Type::getInt32Ty(Preheader->getContext())),
- 0);
-
- // Choose a strength-reduction strategy and prepare for it by creating
- // the necessary PHIs and adjusting the bookkeeping.
- if (ShouldUseFullStrengthReductionMode(UsersToProcess, L,
- AllUsesAreAddresses, Stride)) {
- PrepareToStrengthReduceFully(UsersToProcess, Stride, CommonExprs, L,
- PreheaderRewriter);
- } else {
- // Emit the initial base value into the loop preheader.
- CommonBaseV = PreheaderRewriter.expandCodeFor(CommonExprs, ReplacedTy,
- PreInsertPt);
-
- // If all uses are addresses, check if it is possible to reuse an IV. The
- // new IV must have a stride that is a multiple of the old stride; the
- // multiple must be a number that can be encoded in the scale field of the
- // target addressing mode; and we must have a valid instruction after this
- // substitution, including the immediate field, if any.
- RewriteFactor = CheckForIVReuse(HaveCommonExprs, AllUsesAreAddresses,
- AllUsesAreOutsideLoop,
- Stride, ReuseIV, ReplacedTy,
- UsersToProcess);
- if (!RewriteFactor->isZero())
- PrepareToStrengthReduceFromSmallerStride(UsersToProcess, CommonBaseV,
- ReuseIV, PreInsertPt);
- else {
- IVIncInsertPt = FindIVIncInsertPt(UsersToProcess, L);
- PrepareToStrengthReduceWithNewPhi(UsersToProcess, Stride, CommonExprs,
- CommonBaseV, IVIncInsertPt,
- L, PreheaderRewriter);
- }
- }
+ // ICmp only supports no scale or a -1 scale, as we can "fold" a -1 scale by
+ // putting the scaled register in the other operand of the icmp.
+ if (AM.Scale != 0 && AM.Scale != -1)
+ return false;
- // Process all the users now, replacing their strided uses with
- // strength-reduced forms. This outer loop handles all bases, the inner
- // loop handles all users of a particular base.
- while (!UsersToProcess.empty()) {
- const SCEV *Base = UsersToProcess.back().Base;
- Instruction *Inst = UsersToProcess.back().Inst;
-
- // Emit the code for Base into the preheader.
- Value *BaseV = 0;
- if (!Base->isZero()) {
- BaseV = PreheaderRewriter.expandCodeFor(Base, 0, PreInsertPt);
-
- DEBUG(dbgs() << " INSERTING code for BASE = " << *Base << ":");
- if (BaseV->hasName())
- DEBUG(dbgs() << " Result value name = %" << BaseV->getName());
- DEBUG(dbgs() << "\n");
-
- // If BaseV is a non-zero constant, make sure that it gets inserted into
- // the preheader, instead of being forward substituted into the uses. We
- // do this by forcing a BitCast (noop cast) to be inserted into the
- // preheader in this case.
- if (!fitsInAddressMode(Base, getAccessType(Inst), TLI, false) &&
- isa<Constant>(BaseV)) {
- // We want this constant emitted into the preheader! This is just
- // using cast as a copy so BitCast (no-op cast) is appropriate
- BaseV = new BitCastInst(BaseV, BaseV->getType(), "preheaderinsert",
- PreInsertPt);
- }
+ // If we have low-level target information, ask the target if it can fold an
+ // integer immediate on an icmp.
+ if (AM.BaseOffs != 0) {
+ if (TLI) return TLI->isLegalICmpImmediate(-AM.BaseOffs);
+ return false;
}
- // Emit the code to add the immediate offset to the Phi value, just before
- // the instructions that we identified as using this stride and base.
- do {
- // FIXME: Use emitted users to emit other users.
- BasedUser &User = UsersToProcess.back();
-
- DEBUG(dbgs() << " Examining ");
- if (User.isUseOfPostIncrementedValue)
- DEBUG(dbgs() << "postinc");
- else
- DEBUG(dbgs() << "preinc");
- DEBUG(dbgs() << " use ");
- DEBUG(WriteAsOperand(dbgs(), UsersToProcess.back().OperandValToReplace,
- /*PrintType=*/false));
- DEBUG(dbgs() << " in Inst: " << *User.Inst);
-
- // If this instruction wants to use the post-incremented value, move it
- // after the post-inc and use its value instead of the PHI.
- Value *RewriteOp = User.Phi;
- if (User.isUseOfPostIncrementedValue) {
- RewriteOp = User.Phi->getIncomingValueForBlock(LatchBlock);
- // If this user is in the loop, make sure it is the last thing in the
- // loop to ensure it is dominated by the increment. In case it's the
- // only use of the iv, the increment instruction is already before the
- // use.
- if (L->contains(User.Inst) && User.Inst != IVIncInsertPt)
- User.Inst->moveBefore(IVIncInsertPt);
- }
-
- const SCEV *RewriteExpr = SE->getUnknown(RewriteOp);
-
- if (SE->getEffectiveSCEVType(RewriteOp->getType()) !=
- SE->getEffectiveSCEVType(ReplacedTy)) {
- assert(SE->getTypeSizeInBits(RewriteOp->getType()) >
- SE->getTypeSizeInBits(ReplacedTy) &&
- "Unexpected widening cast!");
- RewriteExpr = SE->getTruncateExpr(RewriteExpr, ReplacedTy);
- }
+ return true;
- // If we had to insert new instructions for RewriteOp, we have to
- // consider that they may not have been able to end up immediately
- // next to RewriteOp, because non-PHI instructions may never precede
- // PHI instructions in a block. In this case, remember where the last
- // instruction was inserted so that if we're replacing a different
- // PHI node, we can use the later point to expand the final
- // RewriteExpr.
- Instruction *NewBasePt = dyn_cast<Instruction>(RewriteOp);
- if (RewriteOp == User.Phi) NewBasePt = 0;
-
- // Clear the SCEVExpander's expression map so that we are guaranteed
- // to have the code emitted where we expect it.
- Rewriter.clear();
-
- // If we are reusing the iv, then it must be multiplied by a constant
- // factor to take advantage of the addressing mode scale component.
- if (!RewriteFactor->isZero()) {
- // If we're reusing an IV with a nonzero base (currently this happens
- // only when all reuses are outside the loop) subtract that base here.
- // The base has been used to initialize the PHI node but we don't want
- // it here.
- if (!ReuseIV.Base->isZero()) {
- const SCEV *typedBase = ReuseIV.Base;
- if (SE->getEffectiveSCEVType(RewriteExpr->getType()) !=
- SE->getEffectiveSCEVType(ReuseIV.Base->getType())) {
- // It's possible the original IV is a larger type than the new IV,
- // in which case we have to truncate the Base. We checked in
- // RequiresTypeConversion that this is valid.
- assert(SE->getTypeSizeInBits(RewriteExpr->getType()) <
- SE->getTypeSizeInBits(ReuseIV.Base->getType()) &&
- "Unexpected lengthening conversion!");
- typedBase = SE->getTruncateExpr(ReuseIV.Base,
- RewriteExpr->getType());
- }
- RewriteExpr = SE->getMinusSCEV(RewriteExpr, typedBase);
- }
+ case LSRUse::Basic:
+ // Only handle single-register values.
+ return !AM.BaseGV && AM.Scale == 0 && AM.BaseOffs == 0;
- // Multiply old variable, with base removed, by new scale factor.
- RewriteExpr = SE->getMulExpr(RewriteFactor,
- RewriteExpr);
-
- // The common base is emitted in the loop preheader. But since we
- // are reusing an IV, it has not been used to initialize the PHI node.
- // Add it to the expression used to rewrite the uses.
- // When this use is outside the loop, we earlier subtracted the
- // common base, and are adding it back here. Use the same expression
- // as before, rather than CommonBaseV, so DAGCombiner will zap it.
- if (!CommonExprs->isZero()) {
- if (L->contains(User.Inst))
- RewriteExpr = SE->getAddExpr(RewriteExpr,
- SE->getUnknown(CommonBaseV));
- else
- RewriteExpr = SE->getAddExpr(RewriteExpr, CommonExprs);
- }
- }
-
- // Now that we know what we need to do, insert code before User for the
- // immediate and any loop-variant expressions.
- if (BaseV)
- // Add BaseV to the PHI value if needed.
- RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV));
-
- User.RewriteInstructionToUseNewBase(RewriteExpr, NewBasePt,
- Rewriter, L, this,
- DeadInsts, SE);
-
- // Mark old value we replaced as possibly dead, so that it is eliminated
- // if we just replaced the last use of that value.
- DeadInsts.push_back(User.OperandValToReplace);
-
- UsersToProcess.pop_back();
- ++NumReduced;
-
- // If there are any more users to process with the same base, process them
- // now. We sorted by base above, so we just have to check the last elt.
- } while (!UsersToProcess.empty() && UsersToProcess.back().Base == Base);
- // TODO: Next, find out which base index is the most common, pull it out.
- }
-
- // IMPORTANT TODO: Figure out how to partition the IV's with this stride, but
- // different starting values, into different PHIs.
-}
-
-void LoopStrengthReduce::StrengthReduceIVUsers(Loop *L) {
- // Note: this processes each stride/type pair individually. All users
- // passed into StrengthReduceIVUsersOfStride have the same type AND stride.
- // Also, note that we iterate over IVUsesByStride indirectly by using
- // StrideOrder. This extra layer of indirection makes the ordering of
- // strides deterministic - not dependent on map order.
- for (unsigned Stride = 0, e = IU->StrideOrder.size(); Stride != e; ++Stride) {
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
- // FIXME: Generalize to non-affine IV's.
- if (!SI->first->isLoopInvariant(L))
- continue;
- StrengthReduceIVUsersOfStride(SI->first, *SI->second, L);
+ case LSRUse::Special:
+ // Only handle -1 scales, or no scale.
+ return AM.Scale == 0 || AM.Scale == -1;
}
+
+ return false;
}
-/// FindIVUserForCond - If Cond has an operand that is an expression of an IV,
-/// set the IV user and stride information and return true, otherwise return
-/// false.
-bool LoopStrengthReduce::FindIVUserForCond(ICmpInst *Cond,
- IVStrideUse *&CondUse,
- const SCEV* &CondStride) {
- for (unsigned Stride = 0, e = IU->StrideOrder.size();
- Stride != e && !CondUse; ++Stride) {
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
-
- for (ilist<IVStrideUse>::iterator UI = SI->second->Users.begin(),
- E = SI->second->Users.end(); UI != E; ++UI)
- if (UI->getUser() == Cond) {
- // NOTE: we could handle setcc instructions with multiple uses here, but
- // InstCombine does it as well for simple uses, it's not clear that it
- // occurs enough in real life to handle.
- CondUse = UI;
- CondStride = SI->first;
- return true;
- }
+static bool isLegalUse(TargetLowering::AddrMode AM,
+ int64_t MinOffset, int64_t MaxOffset,
+ LSRUse::KindType Kind, const Type *AccessTy,
+ const TargetLowering *TLI) {
+ // Check for overflow.
+ if (((int64_t)((uint64_t)AM.BaseOffs + MinOffset) > AM.BaseOffs) !=
+ (MinOffset > 0))
+ return false;
+ AM.BaseOffs = (uint64_t)AM.BaseOffs + MinOffset;
+ if (isLegalUse(AM, Kind, AccessTy, TLI)) {
+ AM.BaseOffs = (uint64_t)AM.BaseOffs - MinOffset;
+ // Check for overflow.
+ if (((int64_t)((uint64_t)AM.BaseOffs + MaxOffset) > AM.BaseOffs) !=
+ (MaxOffset > 0))
+ return false;
+ AM.BaseOffs = (uint64_t)AM.BaseOffs + MaxOffset;
+ return isLegalUse(AM, Kind, AccessTy, TLI);
}
return false;
}
-namespace {
- // Constant strides come first which in turns are sorted by their absolute
- // values. If absolute values are the same, then positive strides comes first.
- // e.g.
- // 4, -1, X, 1, 2 ==> 1, -1, 2, 4, X
- struct StrideCompare {
- const ScalarEvolution *SE;
- explicit StrideCompare(const ScalarEvolution *se) : SE(se) {}
-
- bool operator()(const SCEV *LHS, const SCEV *RHS) {
- const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS);
- const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS);
- if (LHSC && RHSC) {
- int64_t LV = LHSC->getValue()->getSExtValue();
- int64_t RV = RHSC->getValue()->getSExtValue();
- uint64_t ALV = (LV < 0) ? -LV : LV;
- uint64_t ARV = (RV < 0) ? -RV : RV;
- if (ALV == ARV) {
- if (LV != RV)
- return LV > RV;
- } else {
- return ALV < ARV;
- }
+static bool isAlwaysFoldable(int64_t BaseOffs,
+ GlobalValue *BaseGV,
+ bool HasBaseReg,
+ LSRUse::KindType Kind, const Type *AccessTy,
+ const TargetLowering *TLI,
+ ScalarEvolution &SE) {
+ // Fast-path: zero is always foldable.
+ if (BaseOffs == 0 && !BaseGV) return true;
+
+ // Conservatively, create an address with an immediate and a
+ // base and a scale.
+ TargetLowering::AddrMode AM;
+ AM.BaseOffs = BaseOffs;
+ AM.BaseGV = BaseGV;
+ AM.HasBaseReg = HasBaseReg;
+ AM.Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
+
+ return isLegalUse(AM, Kind, AccessTy, TLI);
+}
- // If it's the same value but different type, sort by bit width so
- // that we emit larger induction variables before smaller
- // ones, letting the smaller be re-written in terms of larger ones.
- return SE->getTypeSizeInBits(RHS->getType()) <
- SE->getTypeSizeInBits(LHS->getType());
- }
- return LHSC && !RHSC;
- }
- };
+static bool isAlwaysFoldable(const SCEV *S,
+ int64_t MinOffset, int64_t MaxOffset,
+ bool HasBaseReg,
+ LSRUse::KindType Kind, const Type *AccessTy,
+ const TargetLowering *TLI,
+ ScalarEvolution &SE) {
+ // Fast-path: zero is always foldable.
+ if (S->isZero()) return true;
+
+ // Conservatively, create an address with an immediate and a
+ // base and a scale.
+ int64_t BaseOffs = ExtractImmediate(S, SE);
+ GlobalValue *BaseGV = ExtractSymbol(S, SE);
+
+ // If there's anything else involved, it's not foldable.
+ if (!S->isZero()) return false;
+
+ // Fast-path: zero is always foldable.
+ if (BaseOffs == 0 && !BaseGV) return true;
+
+ // Conservatively, create an address with an immediate and a
+ // base and a scale.
+ TargetLowering::AddrMode AM;
+ AM.BaseOffs = BaseOffs;
+ AM.BaseGV = BaseGV;
+ AM.HasBaseReg = HasBaseReg;
+ AM.Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
+
+ return isLegalUse(AM, MinOffset, MaxOffset, Kind, AccessTy, TLI);
}
-/// ChangeCompareStride - If a loop termination compare instruction is the
-/// only use of its stride, and the compaison is against a constant value,
-/// try eliminate the stride by moving the compare instruction to another
-/// stride and change its constant operand accordingly. e.g.
-///
-/// loop:
-/// ...
-/// v1 = v1 + 3
-/// v2 = v2 + 1
-/// if (v2 < 10) goto loop
-/// =>
-/// loop:
-/// ...
-/// v1 = v1 + 3
-/// if (v1 < 30) goto loop
-ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
- IVStrideUse* &CondUse,
- const SCEV* &CondStride,
- bool PostPass) {
- // If there's only one stride in the loop, there's nothing to do here.
- if (IU->StrideOrder.size() < 2)
- return Cond;
- // If there are other users of the condition's stride, don't bother
- // trying to change the condition because the stride will still
- // remain.
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator I =
- IU->IVUsesByStride.find(CondStride);
- if (I == IU->IVUsesByStride.end())
- return Cond;
- if (I->second->Users.size() > 1) {
- for (ilist<IVStrideUse>::iterator II = I->second->Users.begin(),
- EE = I->second->Users.end(); II != EE; ++II) {
- if (II->getUser() == Cond)
- continue;
- if (!isInstructionTriviallyDead(II->getUser()))
- return Cond;
- }
+/// FormulaSorter - This class implements an ordering for formulae which sorts
+/// the by their standalone cost.
+class FormulaSorter {
+ /// These two sets are kept empty, so that we compute standalone costs.
+ DenseSet<const SCEV *> VisitedRegs;
+ SmallPtrSet<const SCEV *, 16> Regs;
+ Loop *L;
+ LSRUse *LU;
+ ScalarEvolution &SE;
+ DominatorTree &DT;
+
+public:
+ FormulaSorter(Loop *l, LSRUse &lu, ScalarEvolution &se, DominatorTree &dt)
+ : L(l), LU(&lu), SE(se), DT(dt) {}
+
+ bool operator()(const Formula &A, const Formula &B) {
+ Cost CostA;
+ CostA.RateFormula(A, Regs, VisitedRegs, L, LU->Offsets, SE, DT);
+ Regs.clear();
+ Cost CostB;
+ CostB.RateFormula(B, Regs, VisitedRegs, L, LU->Offsets, SE, DT);
+ Regs.clear();
+ return CostA < CostB;
+ }
+};
+
+/// LSRInstance - This class holds state for the main loop strength reduction
+/// logic.
+class LSRInstance {
+ IVUsers &IU;
+ ScalarEvolution &SE;
+ DominatorTree &DT;
+ const TargetLowering *const TLI;
+ Loop *const L;
+ bool Changed;
+
+ /// IVIncInsertPos - This is the insert position that the current loop's
+ /// induction variable increment should be placed. In simple loops, this is
+ /// the latch block's terminator. But in more complicated cases, this is a
+ /// position which will dominate all the in-loop post-increment users.
+ Instruction *IVIncInsertPos;
+
+ /// Factors - Interesting factors between use strides.
+ SmallSetVector<int64_t, 8> Factors;
+
+ /// Types - Interesting use types, to facilitate truncation reuse.
+ SmallSetVector<const Type *, 4> Types;
+
+ /// Fixups - The list of operands which are to be replaced.
+ SmallVector<LSRFixup, 16> Fixups;
+
+ /// Uses - The list of interesting uses.
+ SmallVector<LSRUse, 16> Uses;
+
+ /// RegUses - Track which uses use which register candidates.
+ RegUseTracker RegUses;
+
+ void OptimizeShadowIV();
+ bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse);
+ ICmpInst *OptimizeMax(ICmpInst *Cond, IVStrideUse* &CondUse);
+ bool OptimizeLoopTermCond();
+
+ void CollectInterestingTypesAndFactors();
+ void CollectFixupsAndInitialFormulae();
+
+ LSRFixup &getNewFixup() {
+ Fixups.push_back(LSRFixup());
+ return Fixups.back();
}
- // Only handle constant strides for now.
- const SCEVConstant *SC = dyn_cast<SCEVConstant>(CondStride);
- if (!SC) return Cond;
-
- ICmpInst::Predicate Predicate = Cond->getPredicate();
- int64_t CmpSSInt = SC->getValue()->getSExtValue();
- unsigned BitWidth = SE->getTypeSizeInBits(CondStride->getType());
- uint64_t SignBit = 1ULL << (BitWidth-1);
- const Type *CmpTy = Cond->getOperand(0)->getType();
- const Type *NewCmpTy = NULL;
- unsigned TyBits = SE->getTypeSizeInBits(CmpTy);
- unsigned NewTyBits = 0;
- const SCEV *NewStride = NULL;
- Value *NewCmpLHS = NULL;
- Value *NewCmpRHS = NULL;
- int64_t Scale = 1;
- const SCEV *NewOffset = SE->getIntegerSCEV(0, CmpTy);
-
- if (ConstantInt *C = dyn_cast<ConstantInt>(Cond->getOperand(1))) {
- int64_t CmpVal = C->getValue().getSExtValue();
-
- // Check the relevant induction variable for conformance to
- // the pattern.
- const SCEV *IV = SE->getSCEV(Cond->getOperand(0));
- const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
- if (!AR || !AR->isAffine())
- return Cond;
-
- const SCEVConstant *StartC = dyn_cast<SCEVConstant>(AR->getStart());
- // Check stride constant and the comparision constant signs to detect
- // overflow.
- if (StartC) {
- if ((StartC->getValue()->getSExtValue() < CmpVal && CmpSSInt < 0) ||
- (StartC->getValue()->getSExtValue() > CmpVal && CmpSSInt > 0))
- return Cond;
- } else {
- // More restrictive check for the other cases.
- if ((CmpVal & SignBit) != (CmpSSInt & SignBit))
- return Cond;
- }
-
- // Look for a suitable stride / iv as replacement.
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[i]);
- if (!isa<SCEVConstant>(SI->first) || SI->second->Users.empty())
- continue;
- int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
- if (SSInt == CmpSSInt ||
- abs64(SSInt) < abs64(CmpSSInt) ||
- (SSInt % CmpSSInt) != 0)
- continue;
- Scale = SSInt / CmpSSInt;
- int64_t NewCmpVal = CmpVal * Scale;
+ // Support for sharing of LSRUses between LSRFixups.
+ typedef DenseMap<const SCEV *, size_t> UseMapTy;
+ UseMapTy UseMap;
+
+ bool reconcileNewOffset(LSRUse &LU, int64_t NewOffset,
+ LSRUse::KindType Kind, const Type *AccessTy);
+
+ std::pair<size_t, int64_t> getUse(const SCEV *&Expr,
+ LSRUse::KindType Kind,
+ const Type *AccessTy);
+
+public:
+ void InsertInitialFormula(const SCEV *S, Loop *L, LSRUse &LU, size_t LUIdx);
+ void InsertSupplementalFormula(const SCEV *S, LSRUse &LU, size_t LUIdx);
+ void CountRegisters(const Formula &F, size_t LUIdx);
+ bool InsertFormula(LSRUse &LU, unsigned LUIdx, const Formula &F);
+
+ void CollectLoopInvariantFixupsAndFormulae();
+
+ void GenerateReassociations(LSRUse &LU, unsigned LUIdx, Formula Base,
+ unsigned Depth = 0);
+ void GenerateCombinations(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateSymbolicOffsets(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateConstantOffsets(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateTruncates(LSRUse &LU, unsigned LUIdx, Formula Base);
+ void GenerateCrossUseConstantOffsets();
+ void GenerateAllReuseFormulae();
+
+ void FilterOutUndesirableDedicatedRegisters();
+ void NarrowSearchSpaceUsingHeuristics();
+
+ void SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
+ Cost &SolutionCost,
+ SmallVectorImpl<const Formula *> &Workspace,
+ const Cost &CurCost,
+ const SmallPtrSet<const SCEV *, 16> &CurRegs,
+ DenseSet<const SCEV *> &VisitedRegs) const;
+ void Solve(SmallVectorImpl<const Formula *> &Solution) const;
+
+ Value *Expand(const LSRFixup &LF,
+ const Formula &F,
+ BasicBlock::iterator IP, Loop *L, Instruction *IVIncInsertPos,
+ SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakVH> &DeadInsts,
+ ScalarEvolution &SE, DominatorTree &DT) const;
+ void Rewrite(const LSRFixup &LF,
+ const Formula &F,
+ Loop *L, Instruction *IVIncInsertPos,
+ SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakVH> &DeadInsts,
+ ScalarEvolution &SE, DominatorTree &DT,
+ Pass *P) const;
+ void ImplementSolution(const SmallVectorImpl<const Formula *> &Solution,
+ Pass *P);
+
+ LSRInstance(const TargetLowering *tli, Loop *l, Pass *P);
+
+ bool getChanged() const { return Changed; }
+
+ void print_factors_and_types(raw_ostream &OS) const;
+ void print_fixups(raw_ostream &OS) const;
+ void print_uses(raw_ostream &OS) const;
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
- // If old icmp value fits in icmp immediate field, but the new one doesn't
- // try something else.
- if (TLI &&
- TLI->isLegalICmpImmediate(CmpVal) &&
- !TLI->isLegalICmpImmediate(NewCmpVal))
- continue;
+}
- APInt Mul = APInt(BitWidth*2, CmpVal, true);
- Mul = Mul * APInt(BitWidth*2, Scale, true);
- // Check for overflow.
- if (!Mul.isSignedIntN(BitWidth))
- continue;
- // Check for overflow in the stride's type too.
- if (!Mul.isSignedIntN(SE->getTypeSizeInBits(SI->first->getType())))
- continue;
+/// OptimizeShadowIV - If IV is used in a int-to-float cast
+/// inside the loop then try to eliminate the cast opeation.
+void LSRInstance::OptimizeShadowIV() {
+ const SCEV *BackedgeTakenCount = SE.getBackedgeTakenCount(L);
+ if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
+ return;
- // Watch out for overflow.
- if (ICmpInst::isSigned(Predicate) &&
- (CmpVal & SignBit) != (NewCmpVal & SignBit))
- continue;
+ for (IVUsers::const_iterator UI = IU.begin(), E = IU.end();
+ UI != E; /* empty */) {
+ IVUsers::const_iterator CandidateUI = UI;
+ ++UI;
+ Instruction *ShadowUse = CandidateUI->getUser();
+ const Type *DestTy = NULL;
- // Pick the best iv to use trying to avoid a cast.
- NewCmpLHS = NULL;
- for (ilist<IVStrideUse>::iterator UI = SI->second->Users.begin(),
- E = SI->second->Users.end(); UI != E; ++UI) {
- Value *Op = UI->getOperandValToReplace();
-
- // If the IVStrideUse implies a cast, check for an actual cast which
- // can be used to find the original IV expression.
- if (SE->getEffectiveSCEVType(Op->getType()) !=
- SE->getEffectiveSCEVType(SI->first->getType())) {
- CastInst *CI = dyn_cast<CastInst>(Op);
- // If it's not a simple cast, it's complicated.
- if (!CI)
- continue;
- // If it's a cast from a type other than the stride type,
- // it's complicated.
- if (CI->getOperand(0)->getType() != SI->first->getType())
- continue;
- // Ok, we found the IV expression in the stride's type.
- Op = CI->getOperand(0);
- }
+ /* If shadow use is a int->float cast then insert a second IV
+ to eliminate this cast.
- NewCmpLHS = Op;
- if (NewCmpLHS->getType() == CmpTy)
- break;
- }
- if (!NewCmpLHS)
- continue;
+ for (unsigned i = 0; i < n; ++i)
+ foo((double)i);
- NewCmpTy = NewCmpLHS->getType();
- NewTyBits = SE->getTypeSizeInBits(NewCmpTy);
- const Type *NewCmpIntTy = IntegerType::get(Cond->getContext(), NewTyBits);
- if (RequiresTypeConversion(NewCmpTy, CmpTy)) {
- // Check if it is possible to rewrite it using
- // an iv / stride of a smaller integer type.
- unsigned Bits = NewTyBits;
- if (ICmpInst::isSigned(Predicate))
- --Bits;
- uint64_t Mask = (1ULL << Bits) - 1;
- if (((uint64_t)NewCmpVal & Mask) != (uint64_t)NewCmpVal)
- continue;
- }
+ is transformed into
- // Don't rewrite if use offset is non-constant and the new type is
- // of a different type.
- // FIXME: too conservative?
- if (NewTyBits != TyBits && !isa<SCEVConstant>(CondUse->getOffset()))
- continue;
+ double d = 0.0;
+ for (unsigned i = 0; i < n; ++i, ++d)
+ foo(d);
+ */
+ if (UIToFPInst *UCast = dyn_cast<UIToFPInst>(CandidateUI->getUser()))
+ DestTy = UCast->getDestTy();
+ else if (SIToFPInst *SCast = dyn_cast<SIToFPInst>(CandidateUI->getUser()))
+ DestTy = SCast->getDestTy();
+ if (!DestTy) continue;
- if (!PostPass) {
- bool AllUsesAreAddresses = true;
- bool AllUsesAreOutsideLoop = true;
- std::vector<BasedUser> UsersToProcess;
- const SCEV *CommonExprs = CollectIVUsers(SI->first, *SI->second, L,
- AllUsesAreAddresses,
- AllUsesAreOutsideLoop,
- UsersToProcess);
- // Avoid rewriting the compare instruction with an iv of new stride
- // if it's likely the new stride uses will be rewritten using the
- // stride of the compare instruction.
- if (AllUsesAreAddresses &&
- ValidScale(!CommonExprs->isZero(), Scale, UsersToProcess))
- continue;
- }
+ if (TLI) {
+ // If target does not support DestTy natively then do not apply
+ // this transformation.
+ EVT DVT = TLI->getValueType(DestTy);
+ if (!TLI->isTypeLegal(DVT)) continue;
+ }
- // Avoid rewriting the compare instruction with an iv which has
- // implicit extension or truncation built into it.
- // TODO: This is over-conservative.
- if (SE->getTypeSizeInBits(CondUse->getOffset()->getType()) != TyBits)
- continue;
+ PHINode *PH = dyn_cast<PHINode>(ShadowUse->getOperand(0));
+ if (!PH) continue;
+ if (PH->getNumIncomingValues() != 2) continue;
- // If scale is negative, use swapped predicate unless it's testing
- // for equality.
- if (Scale < 0 && !Cond->isEquality())
- Predicate = ICmpInst::getSwappedPredicate(Predicate);
+ const Type *SrcTy = PH->getType();
+ int Mantissa = DestTy->getFPMantissaWidth();
+ if (Mantissa == -1) continue;
+ if ((int)SE.getTypeSizeInBits(SrcTy) > Mantissa)
+ continue;
- NewStride = IU->StrideOrder[i];
- if (!isa<PointerType>(NewCmpTy))
- NewCmpRHS = ConstantInt::get(NewCmpTy, NewCmpVal);
- else {
- Constant *CI = ConstantInt::get(NewCmpIntTy, NewCmpVal);
- NewCmpRHS = ConstantExpr::getIntToPtr(CI, NewCmpTy);
- }
- NewOffset = TyBits == NewTyBits
- ? SE->getMulExpr(CondUse->getOffset(),
- SE->getConstant(CmpTy, Scale))
- : SE->getConstant(NewCmpIntTy,
- cast<SCEVConstant>(CondUse->getOffset())->getValue()
- ->getSExtValue()*Scale);
- break;
+ unsigned Entry, Latch;
+ if (PH->getIncomingBlock(0) == L->getLoopPreheader()) {
+ Entry = 0;
+ Latch = 1;
+ } else {
+ Entry = 1;
+ Latch = 0;
}
- }
- // Forgo this transformation if it the increment happens to be
- // unfortunately positioned after the condition, and the condition
- // has multiple uses which prevent it from being moved immediately
- // before the branch. See
- // test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-*.ll
- // for an example of this situation.
- if (!Cond->hasOneUse()) {
- for (BasicBlock::iterator I = Cond, E = Cond->getParent()->end();
- I != E; ++I)
- if (I == NewCmpLHS)
- return Cond;
- }
+ ConstantInt *Init = dyn_cast<ConstantInt>(PH->getIncomingValue(Entry));
+ if (!Init) continue;
+ Constant *NewInit = ConstantFP::get(DestTy, Init->getZExtValue());
- if (NewCmpRHS) {
- // Create a new compare instruction using new stride / iv.
- ICmpInst *OldCond = Cond;
- // Insert new compare instruction.
- Cond = new ICmpInst(OldCond, Predicate, NewCmpLHS, NewCmpRHS,
- L->getHeader()->getName() + ".termcond");
+ BinaryOperator *Incr =
+ dyn_cast<BinaryOperator>(PH->getIncomingValue(Latch));
+ if (!Incr) continue;
+ if (Incr->getOpcode() != Instruction::Add
+ && Incr->getOpcode() != Instruction::Sub)
+ continue;
+
+ /* Initialize new IV, double d = 0.0 in above example. */
+ ConstantInt *C = NULL;
+ if (Incr->getOperand(0) == PH)
+ C = dyn_cast<ConstantInt>(Incr->getOperand(1));
+ else if (Incr->getOperand(1) == PH)
+ C = dyn_cast<ConstantInt>(Incr->getOperand(0));
+ else
+ continue;
- DEBUG(dbgs() << " Change compare stride in Inst " << *OldCond);
- DEBUG(dbgs() << " to " << *Cond << '\n');
+ if (!C) continue;
- // Remove the old compare instruction. The old indvar is probably dead too.
- DeadInsts.push_back(CondUse->getOperandValToReplace());
- OldCond->replaceAllUsesWith(Cond);
- OldCond->eraseFromParent();
+ // Ignore negative constants, as the code below doesn't handle them
+ // correctly. TODO: Remove this restriction.
+ if (!C->getValue().isStrictlyPositive()) continue;
- IU->IVUsesByStride[NewStride]->addUser(NewOffset, Cond, NewCmpLHS);
- CondUse = &IU->IVUsesByStride[NewStride]->Users.back();
- CondStride = NewStride;
- ++NumEliminated;
- Changed = true;
+ /* Add new PHINode. */
+ PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH);
+
+ /* create new increment. '++d' in above example. */
+ Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue());
+ BinaryOperator *NewIncr =
+ BinaryOperator::Create(Incr->getOpcode() == Instruction::Add ?
+ Instruction::FAdd : Instruction::FSub,
+ NewPH, CFP, "IV.S.next.", Incr);
+
+ NewPH->addIncoming(NewInit, PH->getIncomingBlock(Entry));
+ NewPH->addIncoming(NewIncr, PH->getIncomingBlock(Latch));
+
+ /* Remove cast operation */
+ ShadowUse->replaceAllUsesWith(NewPH);
+ ShadowUse->eraseFromParent();
+ break;
}
+}
- return Cond;
+/// FindIVUserForCond - If Cond has an operand that is an expression of an IV,
+/// set the IV user and stride information and return true, otherwise return
+/// false.
+bool LSRInstance::FindIVUserForCond(ICmpInst *Cond,
+ IVStrideUse *&CondUse) {
+ for (IVUsers::iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI)
+ if (UI->getUser() == Cond) {
+ // NOTE: we could handle setcc instructions with multiple uses here, but
+ // InstCombine does it as well for simple uses, it's not clear that it
+ // occurs enough in real life to handle.
+ CondUse = UI;
+ return true;
+ }
+ return false;
}
/// OptimizeMax - Rewrite the loop's terminating condition if it uses
@@ -2087,7 +1371,7 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
/// are designed around them. The most obvious example of this is the
/// LoopInfo analysis, which doesn't remember trip count values. It
/// expects to be able to rediscover the trip count each time it is
-/// needed, and it does this using a simple analyis that only succeeds if
+/// needed, and it does this using a simple analysis that only succeeds if
/// the loop has a canonical induction variable.
///
/// However, when it comes time to generate code, the maximum operation
@@ -2097,8 +1381,7 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
/// rewriting their conditions from ICMP_NE back to ICMP_SLT, and deleting
/// the instructions for the maximum computation.
///
-ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
- IVStrideUse* &CondUse) {
+ICmpInst *LSRInstance::OptimizeMax(ICmpInst *Cond, IVStrideUse* &CondUse) {
// Check that the loop matches the pattern we're looking for.
if (Cond->getPredicate() != CmpInst::ICMP_EQ &&
Cond->getPredicate() != CmpInst::ICMP_NE)
@@ -2107,19 +1390,19 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
SelectInst *Sel = dyn_cast<SelectInst>(Cond->getOperand(1));
if (!Sel || !Sel->hasOneUse()) return Cond;
- const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
+ const SCEV *BackedgeTakenCount = SE.getBackedgeTakenCount(L);
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
return Cond;
- const SCEV *One = SE->getIntegerSCEV(1, BackedgeTakenCount->getType());
+ const SCEV *One = SE.getIntegerSCEV(1, BackedgeTakenCount->getType());
// Add one to the backedge-taken count to get the trip count.
- const SCEV *IterationCount = SE->getAddExpr(BackedgeTakenCount, One);
+ const SCEV *IterationCount = SE.getAddExpr(BackedgeTakenCount, One);
// Check for a max calculation that matches the pattern.
if (!isa<SCEVSMaxExpr>(IterationCount) && !isa<SCEVUMaxExpr>(IterationCount))
return Cond;
const SCEVNAryExpr *Max = cast<SCEVNAryExpr>(IterationCount);
- if (Max != SE->getSCEV(Sel)) return Cond;
+ if (Max != SE.getSCEV(Sel)) return Cond;
// To handle a max with more than two operands, this optimization would
// require additional checking and setup.
@@ -2129,14 +1412,13 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
const SCEV *MaxLHS = Max->getOperand(0);
const SCEV *MaxRHS = Max->getOperand(1);
if (!MaxLHS || MaxLHS != One) return Cond;
-
// Check the relevant induction variable for conformance to
// the pattern.
- const SCEV *IV = SE->getSCEV(Cond->getOperand(0));
+ const SCEV *IV = SE.getSCEV(Cond->getOperand(0));
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
if (!AR || !AR->isAffine() ||
AR->getStart() != One ||
- AR->getStepRecurrence(*SE) != One)
+ AR->getStepRecurrence(SE) != One)
return Cond;
assert(AR->getLoop() == L &&
@@ -2145,9 +1427,9 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
// Check the right operand of the select, and remember it, as it will
// be used in the new comparison instruction.
Value *NewRHS = 0;
- if (SE->getSCEV(Sel->getOperand(1)) == MaxRHS)
+ if (SE.getSCEV(Sel->getOperand(1)) == MaxRHS)
NewRHS = Sel->getOperand(1);
- else if (SE->getSCEV(Sel->getOperand(2)) == MaxRHS)
+ else if (SE.getSCEV(Sel->getOperand(2)) == MaxRHS)
NewRHS = Sel->getOperand(2);
if (!NewRHS) return Cond;
@@ -2174,552 +1456,1764 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
return NewCond;
}
-/// OptimizeShadowIV - If IV is used in a int-to-float cast
-/// inside the loop then try to eliminate the cast opeation.
-void LoopStrengthReduce::OptimizeShadowIV(Loop *L) {
+/// OptimizeLoopTermCond - Change loop terminating condition to use the
+/// postinc iv when possible.
+bool
+LSRInstance::OptimizeLoopTermCond() {
+ SmallPtrSet<Instruction *, 4> PostIncs;
- const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
- if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
- return;
+ BasicBlock *LatchBlock = L->getLoopLatch();
+ SmallVector<BasicBlock*, 8> ExitingBlocks;
+ L->getExitingBlocks(ExitingBlocks);
+
+ for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
+ BasicBlock *ExitingBlock = ExitingBlocks[i];
+
+ // Get the terminating condition for the loop if possible. If we
+ // can, we want to change it to use a post-incremented version of its
+ // induction variable, to allow coalescing the live ranges for the IV into
+ // one register value.
+
+ BranchInst *TermBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
+ if (!TermBr)
+ continue;
+ // FIXME: Overly conservative, termination condition could be an 'or' etc..
+ if (TermBr->isUnconditional() || !isa<ICmpInst>(TermBr->getCondition()))
+ continue;
- for (unsigned Stride = 0, e = IU->StrideOrder.size(); Stride != e;
- ++Stride) {
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
- if (!isa<SCEVConstant>(SI->first))
+ // Search IVUsesByStride to find Cond's IVUse if there is one.
+ IVStrideUse *CondUse = 0;
+ ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
+ if (!FindIVUserForCond(Cond, CondUse))
continue;
- for (ilist<IVStrideUse>::iterator UI = SI->second->Users.begin(),
- E = SI->second->Users.end(); UI != E; /* empty */) {
- ilist<IVStrideUse>::iterator CandidateUI = UI;
- ++UI;
- Instruction *ShadowUse = CandidateUI->getUser();
- const Type *DestTy = NULL;
-
- /* If shadow use is a int->float cast then insert a second IV
- to eliminate this cast.
-
- for (unsigned i = 0; i < n; ++i)
- foo((double)i);
-
- is transformed into
-
- double d = 0.0;
- for (unsigned i = 0; i < n; ++i, ++d)
- foo(d);
- */
- if (UIToFPInst *UCast = dyn_cast<UIToFPInst>(CandidateUI->getUser()))
- DestTy = UCast->getDestTy();
- else if (SIToFPInst *SCast = dyn_cast<SIToFPInst>(CandidateUI->getUser()))
- DestTy = SCast->getDestTy();
- if (!DestTy) continue;
-
- if (TLI) {
- // If target does not support DestTy natively then do not apply
- // this transformation.
- EVT DVT = TLI->getValueType(DestTy);
- if (!TLI->isTypeLegal(DVT)) continue;
- }
+ // If the trip count is computed in terms of a max (due to ScalarEvolution
+ // being unable to find a sufficient guard, for example), change the loop
+ // comparison to use SLT or ULT instead of NE.
+ // One consequence of doing this now is that it disrupts the count-down
+ // optimization. That's not always a bad thing though, because in such
+ // cases it may still be worthwhile to avoid a max.
+ Cond = OptimizeMax(Cond, CondUse);
+
+ // If this exiting block dominates the latch block, it may also use
+ // the post-inc value if it won't be shared with other uses.
+ // Check for dominance.
+ if (!DT.dominates(ExitingBlock, LatchBlock))
+ continue;
- PHINode *PH = dyn_cast<PHINode>(ShadowUse->getOperand(0));
- if (!PH) continue;
- if (PH->getNumIncomingValues() != 2) continue;
+ // Conservatively avoid trying to use the post-inc value in non-latch
+ // exits if there may be pre-inc users in intervening blocks.
+ if (LatchBlock != ExitingBlock)
+ for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI)
+ // Test if the use is reachable from the exiting block. This dominator
+ // query is a conservative approximation of reachability.
+ if (&*UI != CondUse &&
+ !DT.properlyDominates(UI->getUser()->getParent(), ExitingBlock)) {
+ // Conservatively assume there may be reuse if the quotient of their
+ // strides could be a legal scale.
+ const SCEV *A = CondUse->getStride();
+ const SCEV *B = UI->getStride();
+ if (SE.getTypeSizeInBits(A->getType()) !=
+ SE.getTypeSizeInBits(B->getType())) {
+ if (SE.getTypeSizeInBits(A->getType()) >
+ SE.getTypeSizeInBits(B->getType()))
+ B = SE.getSignExtendExpr(B, A->getType());
+ else
+ A = SE.getSignExtendExpr(A, B->getType());
+ }
+ if (const SCEVConstant *D =
+ dyn_cast_or_null<SCEVConstant>(getSDiv(B, A, SE))) {
+ // Stride of one or negative one can have reuse with non-addresses.
+ if (D->getValue()->isOne() ||
+ D->getValue()->isAllOnesValue())
+ goto decline_post_inc;
+ // Avoid weird situations.
+ if (D->getValue()->getValue().getMinSignedBits() >= 64 ||
+ D->getValue()->getValue().isMinSignedValue())
+ goto decline_post_inc;
+ // Without TLI, assume that any stride might be valid, and so any
+ // use might be shared.
+ if (!TLI)
+ goto decline_post_inc;
+ // Check for possible scaled-address reuse.
+ const Type *AccessTy = getAccessType(UI->getUser());
+ TargetLowering::AddrMode AM;
+ AM.Scale = D->getValue()->getSExtValue();
+ if (TLI->isLegalAddressingMode(AM, AccessTy))
+ goto decline_post_inc;
+ AM.Scale = -AM.Scale;
+ if (TLI->isLegalAddressingMode(AM, AccessTy))
+ goto decline_post_inc;
+ }
+ }
- const Type *SrcTy = PH->getType();
- int Mantissa = DestTy->getFPMantissaWidth();
- if (Mantissa == -1) continue;
- if ((int)SE->getTypeSizeInBits(SrcTy) > Mantissa)
- continue;
+ DEBUG(dbgs() << " Change loop exiting icmp to use postinc iv: "
+ << *Cond << '\n');
- unsigned Entry, Latch;
- if (PH->getIncomingBlock(0) == L->getLoopPreheader()) {
- Entry = 0;
- Latch = 1;
+ // It's possible for the setcc instruction to be anywhere in the loop, and
+ // possible for it to have multiple users. If it is not immediately before
+ // the exiting block branch, move it.
+ if (&*++BasicBlock::iterator(Cond) != TermBr) {
+ if (Cond->hasOneUse()) {
+ Cond->moveBefore(TermBr);
} else {
- Entry = 1;
- Latch = 0;
+ // Clone the terminating condition and insert into the loopend.
+ ICmpInst *OldCond = Cond;
+ Cond = cast<ICmpInst>(Cond->clone());
+ Cond->setName(L->getHeader()->getName() + ".termcond");
+ ExitingBlock->getInstList().insert(TermBr, Cond);
+
+ // Clone the IVUse, as the old use still exists!
+ CondUse = &IU.AddUser(CondUse->getStride(), CondUse->getOffset(),
+ Cond, CondUse->getOperandValToReplace());
+ TermBr->replaceUsesOfWith(OldCond, Cond);
}
+ }
- ConstantInt *Init = dyn_cast<ConstantInt>(PH->getIncomingValue(Entry));
- if (!Init) continue;
- Constant *NewInit = ConstantFP::get(DestTy, Init->getZExtValue());
+ // If we get to here, we know that we can transform the setcc instruction to
+ // use the post-incremented version of the IV, allowing us to coalesce the
+ // live ranges for the IV correctly.
+ CondUse->setOffset(SE.getMinusSCEV(CondUse->getOffset(),
+ CondUse->getStride()));
+ CondUse->setIsUseOfPostIncrementedValue(true);
+ Changed = true;
- BinaryOperator *Incr =
- dyn_cast<BinaryOperator>(PH->getIncomingValue(Latch));
- if (!Incr) continue;
- if (Incr->getOpcode() != Instruction::Add
- && Incr->getOpcode() != Instruction::Sub)
- continue;
+ PostIncs.insert(Cond);
+ decline_post_inc:;
+ }
- /* Initialize new IV, double d = 0.0 in above example. */
- ConstantInt *C = NULL;
- if (Incr->getOperand(0) == PH)
- C = dyn_cast<ConstantInt>(Incr->getOperand(1));
- else if (Incr->getOperand(1) == PH)
- C = dyn_cast<ConstantInt>(Incr->getOperand(0));
- else
- continue;
+ // Determine an insertion point for the loop induction variable increment. It
+ // must dominate all the post-inc comparisons we just set up, and it must
+ // dominate the loop latch edge.
+ IVIncInsertPos = L->getLoopLatch()->getTerminator();
+ for (SmallPtrSet<Instruction *, 4>::const_iterator I = PostIncs.begin(),
+ E = PostIncs.end(); I != E; ++I) {
+ BasicBlock *BB =
+ DT.findNearestCommonDominator(IVIncInsertPos->getParent(),
+ (*I)->getParent());
+ if (BB == (*I)->getParent())
+ IVIncInsertPos = *I;
+ else if (BB != IVIncInsertPos->getParent())
+ IVIncInsertPos = BB->getTerminator();
+ }
- if (!C) continue;
+ return Changed;
+}
+
+bool
+LSRInstance::reconcileNewOffset(LSRUse &LU, int64_t NewOffset,
+ LSRUse::KindType Kind, const Type *AccessTy) {
+ int64_t NewMinOffset = LU.MinOffset;
+ int64_t NewMaxOffset = LU.MaxOffset;
+ const Type *NewAccessTy = AccessTy;
+
+ // Check for a mismatched kind. It's tempting to collapse mismatched kinds to
+ // something conservative, however this can pessimize in the case that one of
+ // the uses will have all its uses outside the loop, for example.
+ if (LU.Kind != Kind)
+ return false;
+ // Conservatively assume HasBaseReg is true for now.
+ if (NewOffset < LU.MinOffset) {
+ if (!isAlwaysFoldable(LU.MaxOffset - NewOffset, 0, /*HasBaseReg=*/true,
+ Kind, AccessTy, TLI, SE))
+ return false;
+ NewMinOffset = NewOffset;
+ } else if (NewOffset > LU.MaxOffset) {
+ if (!isAlwaysFoldable(NewOffset - LU.MinOffset, 0, /*HasBaseReg=*/true,
+ Kind, AccessTy, TLI, SE))
+ return false;
+ NewMaxOffset = NewOffset;
+ }
+ // Check for a mismatched access type, and fall back conservatively as needed.
+ if (Kind == LSRUse::Address && AccessTy != LU.AccessTy)
+ NewAccessTy = Type::getVoidTy(AccessTy->getContext());
+
+ // Update the use.
+ LU.MinOffset = NewMinOffset;
+ LU.MaxOffset = NewMaxOffset;
+ LU.AccessTy = NewAccessTy;
+ if (NewOffset != LU.Offsets.back())
+ LU.Offsets.push_back(NewOffset);
+ return true;
+}
- // Ignore negative constants, as the code below doesn't handle them
- // correctly. TODO: Remove this restriction.
- if (!C->getValue().isStrictlyPositive()) continue;
+/// getUse - Return an LSRUse index and an offset value for a fixup which
+/// needs the given expression, with the given kind and optional access type.
+/// Either reuse an exisitng use or create a new one, as needed.
+std::pair<size_t, int64_t>
+LSRInstance::getUse(const SCEV *&Expr,
+ LSRUse::KindType Kind, const Type *AccessTy) {
+ const SCEV *Copy = Expr;
+ int64_t Offset = ExtractImmediate(Expr, SE);
+
+ // Basic uses can't accept any offset, for example.
+ if (!isAlwaysFoldable(Offset, 0, /*HasBaseReg=*/true,
+ Kind, AccessTy, TLI, SE)) {
+ Expr = Copy;
+ Offset = 0;
+ }
- /* Add new PHINode. */
- PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH);
+ std::pair<UseMapTy::iterator, bool> P =
+ UseMap.insert(std::make_pair(Expr, 0));
+ if (!P.second) {
+ // A use already existed with this base.
+ size_t LUIdx = P.first->second;
+ LSRUse &LU = Uses[LUIdx];
+ if (reconcileNewOffset(LU, Offset, Kind, AccessTy))
+ // Reuse this use.
+ return std::make_pair(LUIdx, Offset);
+ }
- /* create new increment. '++d' in above example. */
- Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue());
- BinaryOperator *NewIncr =
- BinaryOperator::Create(Incr->getOpcode() == Instruction::Add ?
- Instruction::FAdd : Instruction::FSub,
- NewPH, CFP, "IV.S.next.", Incr);
+ // Create a new use.
+ size_t LUIdx = Uses.size();
+ P.first->second = LUIdx;
+ Uses.push_back(LSRUse(Kind, AccessTy));
+ LSRUse &LU = Uses[LUIdx];
- NewPH->addIncoming(NewInit, PH->getIncomingBlock(Entry));
- NewPH->addIncoming(NewIncr, PH->getIncomingBlock(Latch));
+ // We don't need to track redundant offsets, but we don't need to go out
+ // of our way here to avoid them.
+ if (LU.Offsets.empty() || Offset != LU.Offsets.back())
+ LU.Offsets.push_back(Offset);
- /* Remove cast operation */
- ShadowUse->replaceAllUsesWith(NewPH);
- ShadowUse->eraseFromParent();
- NumShadow++;
- break;
+ LU.MinOffset = Offset;
+ LU.MaxOffset = Offset;
+ return std::make_pair(LUIdx, Offset);
+}
+
+void LSRInstance::CollectInterestingTypesAndFactors() {
+ SmallSetVector<const SCEV *, 4> Strides;
+
+ // Collect interesting types and factors.
+ for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI) {
+ const SCEV *Stride = UI->getStride();
+
+ // Collect interesting types.
+ Types.insert(SE.getEffectiveSCEVType(Stride->getType()));
+
+ // Collect interesting factors.
+ for (SmallSetVector<const SCEV *, 4>::const_iterator NewStrideIter =
+ Strides.begin(), SEnd = Strides.end(); NewStrideIter != SEnd;
+ ++NewStrideIter) {
+ const SCEV *OldStride = Stride;
+ const SCEV *NewStride = *NewStrideIter;
+ if (OldStride == NewStride)
+ continue;
+
+ if (SE.getTypeSizeInBits(OldStride->getType()) !=
+ SE.getTypeSizeInBits(NewStride->getType())) {
+ if (SE.getTypeSizeInBits(OldStride->getType()) >
+ SE.getTypeSizeInBits(NewStride->getType()))
+ NewStride = SE.getSignExtendExpr(NewStride, OldStride->getType());
+ else
+ OldStride = SE.getSignExtendExpr(OldStride, NewStride->getType());
+ }
+ if (const SCEVConstant *Factor =
+ dyn_cast_or_null<SCEVConstant>(getSDiv(NewStride, OldStride,
+ SE, true))) {
+ if (Factor->getValue()->getValue().getMinSignedBits() <= 64)
+ Factors.insert(Factor->getValue()->getValue().getSExtValue());
+ } else if (const SCEVConstant *Factor =
+ dyn_cast_or_null<SCEVConstant>(getSDiv(OldStride, NewStride,
+ SE, true))) {
+ if (Factor->getValue()->getValue().getMinSignedBits() <= 64)
+ Factors.insert(Factor->getValue()->getValue().getSExtValue());
+ }
}
+ Strides.insert(Stride);
}
-}
-/// OptimizeIndvars - Now that IVUsesByStride is set up with all of the indvar
-/// uses in the loop, look to see if we can eliminate some, in favor of using
-/// common indvars for the different uses.
-void LoopStrengthReduce::OptimizeIndvars(Loop *L) {
- // TODO: implement optzns here.
+ // If all uses use the same type, don't bother looking for truncation-based
+ // reuse.
+ if (Types.size() == 1)
+ Types.clear();
- OptimizeShadowIV(L);
+ DEBUG(print_factors_and_types(dbgs()));
}
-bool LoopStrengthReduce::StrideMightBeShared(const SCEV* Stride, Loop *L,
- bool CheckPreInc) {
- int64_t SInt = cast<SCEVConstant>(Stride)->getValue()->getSExtValue();
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(IU->StrideOrder[i]);
- const SCEV *Share = SI->first;
- if (!isa<SCEVConstant>(SI->first) || Share == Stride)
- continue;
- int64_t SSInt = cast<SCEVConstant>(Share)->getValue()->getSExtValue();
- if (SSInt == SInt)
- return true; // This can definitely be reused.
- if (unsigned(abs64(SSInt)) < SInt || (SSInt % SInt) != 0)
- continue;
- int64_t Scale = SSInt / SInt;
- bool AllUsesAreAddresses = true;
- bool AllUsesAreOutsideLoop = true;
- std::vector<BasedUser> UsersToProcess;
- const SCEV *CommonExprs = CollectIVUsers(SI->first, *SI->second, L,
- AllUsesAreAddresses,
- AllUsesAreOutsideLoop,
- UsersToProcess);
- if (AllUsesAreAddresses &&
- ValidScale(!CommonExprs->isZero(), Scale, UsersToProcess)) {
- if (!CheckPreInc)
- return true;
- // Any pre-inc iv use?
- IVUsersOfOneStride &StrideUses = *IU->IVUsesByStride[Share];
- for (ilist<IVStrideUse>::iterator I = StrideUses.Users.begin(),
- E = StrideUses.Users.end(); I != E; ++I) {
- if (!I->isUseOfPostIncrementedValue())
- return true;
+void LSRInstance::CollectFixupsAndInitialFormulae() {
+ for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI) {
+ // Record the uses.
+ LSRFixup &LF = getNewFixup();
+ LF.UserInst = UI->getUser();
+ LF.OperandValToReplace = UI->getOperandValToReplace();
+ if (UI->isUseOfPostIncrementedValue())
+ LF.PostIncLoop = L;
+
+ LSRUse::KindType Kind = LSRUse::Basic;
+ const Type *AccessTy = 0;
+ if (isAddressUse(LF.UserInst, LF.OperandValToReplace)) {
+ Kind = LSRUse::Address;
+ AccessTy = getAccessType(LF.UserInst);
+ }
+
+ const SCEV *S = IU.getCanonicalExpr(*UI);
+
+ // Equality (== and !=) ICmps are special. We can rewrite (i == N) as
+ // (N - i == 0), and this allows (N - i) to be the expression that we work
+ // with rather than just N or i, so we can consider the register
+ // requirements for both N and i at the same time. Limiting this code to
+ // equality icmps is not a problem because all interesting loops use
+ // equality icmps, thanks to IndVarSimplify.
+ if (ICmpInst *CI = dyn_cast<ICmpInst>(LF.UserInst))
+ if (CI->isEquality()) {
+ // Swap the operands if needed to put the OperandValToReplace on the
+ // left, for consistency.
+ Value *NV = CI->getOperand(1);
+ if (NV == LF.OperandValToReplace) {
+ CI->setOperand(1, CI->getOperand(0));
+ CI->setOperand(0, NV);
+ }
+
+ // x == y --> x - y == 0
+ const SCEV *N = SE.getSCEV(NV);
+ if (N->isLoopInvariant(L)) {
+ Kind = LSRUse::ICmpZero;
+ S = SE.getMinusSCEV(N, S);
+ }
+
+ // -1 and the negations of all interesting strides (except the negation
+ // of -1) are now also interesting.
+ for (size_t i = 0, e = Factors.size(); i != e; ++i)
+ if (Factors[i] != -1)
+ Factors.insert(-(uint64_t)Factors[i]);
+ Factors.insert(-1);
}
+
+ // Set up the initial formula for this use.
+ std::pair<size_t, int64_t> P = getUse(S, Kind, AccessTy);
+ LF.LUIdx = P.first;
+ LF.Offset = P.second;
+ LSRUse &LU = Uses[LF.LUIdx];
+ LU.AllFixupsOutsideLoop &= !L->contains(LF.UserInst);
+
+ // If this is the first use of this LSRUse, give it a formula.
+ if (LU.Formulae.empty()) {
+ InsertInitialFormula(S, L, LU, LF.LUIdx);
+ CountRegisters(LU.Formulae.back(), LF.LUIdx);
}
}
- return false;
+
+ DEBUG(print_fixups(dbgs()));
}
-/// isUsedByExitBranch - Return true if icmp is used by a loop terminating
-/// conditional branch or it's and / or with other conditions before being used
-/// as the condition.
-static bool isUsedByExitBranch(ICmpInst *Cond, Loop *L) {
- BasicBlock *CondBB = Cond->getParent();
- if (!L->isLoopExiting(CondBB))
- return false;
- BranchInst *TermBr = dyn_cast<BranchInst>(CondBB->getTerminator());
- if (!TermBr || !TermBr->isConditional())
+void
+LSRInstance::InsertInitialFormula(const SCEV *S, Loop *L,
+ LSRUse &LU, size_t LUIdx) {
+ Formula F;
+ F.InitialMatch(S, L, SE, DT);
+ bool Inserted = InsertFormula(LU, LUIdx, F);
+ assert(Inserted && "Initial formula already exists!"); (void)Inserted;
+}
+
+void
+LSRInstance::InsertSupplementalFormula(const SCEV *S,
+ LSRUse &LU, size_t LUIdx) {
+ Formula F;
+ F.BaseRegs.push_back(S);
+ F.AM.HasBaseReg = true;
+ bool Inserted = InsertFormula(LU, LUIdx, F);
+ assert(Inserted && "Supplemental formula already exists!"); (void)Inserted;
+}
+
+/// CountRegisters - Note which registers are used by the given formula,
+/// updating RegUses.
+void LSRInstance::CountRegisters(const Formula &F, size_t LUIdx) {
+ if (F.ScaledReg)
+ RegUses.CountRegister(F.ScaledReg, LUIdx);
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(),
+ E = F.BaseRegs.end(); I != E; ++I)
+ RegUses.CountRegister(*I, LUIdx);
+}
+
+/// InsertFormula - If the given formula has not yet been inserted, add it to
+/// the list, and return true. Return false otherwise.
+bool LSRInstance::InsertFormula(LSRUse &LU, unsigned LUIdx, const Formula &F) {
+ if (!LU.InsertFormula(LUIdx, F))
return false;
- Value *User = *Cond->use_begin();
- Instruction *UserInst = dyn_cast<Instruction>(User);
- while (UserInst &&
- (UserInst->getOpcode() == Instruction::And ||
- UserInst->getOpcode() == Instruction::Or)) {
- if (!UserInst->hasOneUse() || UserInst->getParent() != CondBB)
- return false;
- User = *User->use_begin();
- UserInst = dyn_cast<Instruction>(User);
+ CountRegisters(F, LUIdx);
+ return true;
+}
+
+/// CollectLoopInvariantFixupsAndFormulae - Check for other uses of
+/// loop-invariant values which we're tracking. These other uses will pin these
+/// values in registers, making them less profitable for elimination.
+/// TODO: This currently misses non-constant addrec step registers.
+/// TODO: Should this give more weight to users inside the loop?
+void
+LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
+ SmallVector<const SCEV *, 8> Worklist(RegUses.begin(), RegUses.end());
+ SmallPtrSet<const SCEV *, 8> Inserted;
+
+ while (!Worklist.empty()) {
+ const SCEV *S = Worklist.pop_back_val();
+
+ if (const SCEVNAryExpr *N = dyn_cast<SCEVNAryExpr>(S))
+ Worklist.insert(Worklist.end(), N->op_begin(), N->op_end());
+ else if (const SCEVCastExpr *C = dyn_cast<SCEVCastExpr>(S))
+ Worklist.push_back(C->getOperand());
+ else if (const SCEVUDivExpr *D = dyn_cast<SCEVUDivExpr>(S)) {
+ Worklist.push_back(D->getLHS());
+ Worklist.push_back(D->getRHS());
+ } else if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
+ if (!Inserted.insert(U)) continue;
+ const Value *V = U->getValue();
+ if (const Instruction *Inst = dyn_cast<Instruction>(V))
+ if (L->contains(Inst)) continue;
+ for (Value::use_const_iterator UI = V->use_begin(), UE = V->use_end();
+ UI != UE; ++UI) {
+ const Instruction *UserInst = dyn_cast<Instruction>(*UI);
+ // Ignore non-instructions.
+ if (!UserInst)
+ continue;
+ // Ignore instructions in other functions (as can happen with
+ // Constants).
+ if (UserInst->getParent()->getParent() != L->getHeader()->getParent())
+ continue;
+ // Ignore instructions not dominated by the loop.
+ const BasicBlock *UseBB = !isa<PHINode>(UserInst) ?
+ UserInst->getParent() :
+ cast<PHINode>(UserInst)->getIncomingBlock(
+ PHINode::getIncomingValueNumForOperand(UI.getOperandNo()));
+ if (!DT.dominates(L->getHeader(), UseBB))
+ continue;
+ // Ignore uses which are part of other SCEV expressions, to avoid
+ // analyzing them multiple times.
+ if (SE.isSCEVable(UserInst->getType()) &&
+ !isa<SCEVUnknown>(SE.getSCEV(const_cast<Instruction *>(UserInst))))
+ continue;
+ // Ignore icmp instructions which are already being analyzed.
+ if (const ICmpInst *ICI = dyn_cast<ICmpInst>(UserInst)) {
+ unsigned OtherIdx = !UI.getOperandNo();
+ Value *OtherOp = const_cast<Value *>(ICI->getOperand(OtherIdx));
+ if (SE.getSCEV(OtherOp)->hasComputableLoopEvolution(L))
+ continue;
+ }
+
+ LSRFixup &LF = getNewFixup();
+ LF.UserInst = const_cast<Instruction *>(UserInst);
+ LF.OperandValToReplace = UI.getUse();
+ std::pair<size_t, int64_t> P = getUse(S, LSRUse::Basic, 0);
+ LF.LUIdx = P.first;
+ LF.Offset = P.second;
+ LSRUse &LU = Uses[LF.LUIdx];
+ LU.AllFixupsOutsideLoop &= L->contains(LF.UserInst);
+ InsertSupplementalFormula(U, LU, LF.LUIdx);
+ CountRegisters(LU.Formulae.back(), Uses.size() - 1);
+ break;
+ }
+ }
}
- return User == TermBr;
}
-static bool ShouldCountToZero(ICmpInst *Cond, IVStrideUse* &CondUse,
- ScalarEvolution *SE, Loop *L,
- const TargetLowering *TLI = 0) {
- if (!L->contains(Cond))
- return false;
+/// CollectSubexprs - Split S into subexpressions which can be pulled out into
+/// separate registers. If C is non-null, multiply each subexpression by C.
+static void CollectSubexprs(const SCEV *S, const SCEVConstant *C,
+ SmallVectorImpl<const SCEV *> &Ops,
+ ScalarEvolution &SE) {
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+ // Break out add operands.
+ for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
+ I != E; ++I)
+ CollectSubexprs(*I, C, Ops, SE);
+ return;
+ } else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
+ // Split a non-zero base out of an addrec.
+ if (!AR->getStart()->isZero()) {
+ CollectSubexprs(SE.getAddRecExpr(SE.getIntegerSCEV(0, AR->getType()),
+ AR->getStepRecurrence(SE),
+ AR->getLoop()), C, Ops, SE);
+ CollectSubexprs(AR->getStart(), C, Ops, SE);
+ return;
+ }
+ } else if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {
+ // Break (C * (a + b + c)) into C*a + C*b + C*c.
+ if (Mul->getNumOperands() == 2)
+ if (const SCEVConstant *Op0 =
+ dyn_cast<SCEVConstant>(Mul->getOperand(0))) {
+ CollectSubexprs(Mul->getOperand(1),
+ C ? cast<SCEVConstant>(SE.getMulExpr(C, Op0)) : Op0,
+ Ops, SE);
+ return;
+ }
+ }
- if (!isa<SCEVConstant>(CondUse->getOffset()))
- return false;
+ // Otherwise use the value itself.
+ Ops.push_back(C ? SE.getMulExpr(C, S) : S);
+}
- // Handle only tests for equality for the moment.
- if (!Cond->isEquality() || !Cond->hasOneUse())
- return false;
- if (!isUsedByExitBranch(Cond, L))
- return false;
+/// GenerateReassociations - Split out subexpressions from adds and the bases of
+/// addrecs.
+void LSRInstance::GenerateReassociations(LSRUse &LU, unsigned LUIdx,
+ Formula Base,
+ unsigned Depth) {
+ // Arbitrarily cap recursion to protect compile time.
+ if (Depth >= 3) return;
+
+ for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
+ const SCEV *BaseReg = Base.BaseRegs[i];
+
+ SmallVector<const SCEV *, 8> AddOps;
+ CollectSubexprs(BaseReg, 0, AddOps, SE);
+ if (AddOps.size() == 1) continue;
+
+ for (SmallVectorImpl<const SCEV *>::const_iterator J = AddOps.begin(),
+ JE = AddOps.end(); J != JE; ++J) {
+ // Don't pull a constant into a register if the constant could be folded
+ // into an immediate field.
+ if (isAlwaysFoldable(*J, LU.MinOffset, LU.MaxOffset,
+ Base.getNumRegs() > 1,
+ LU.Kind, LU.AccessTy, TLI, SE))
+ continue;
- Value *CondOp0 = Cond->getOperand(0);
- const SCEV *IV = SE->getSCEV(CondOp0);
- const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
- if (!AR || !AR->isAffine())
- return false;
+ // Collect all operands except *J.
+ SmallVector<const SCEV *, 8> InnerAddOps;
+ for (SmallVectorImpl<const SCEV *>::const_iterator K = AddOps.begin(),
+ KE = AddOps.end(); K != KE; ++K)
+ if (K != J)
+ InnerAddOps.push_back(*K);
+
+ // Don't leave just a constant behind in a register if the constant could
+ // be folded into an immediate field.
+ if (InnerAddOps.size() == 1 &&
+ isAlwaysFoldable(InnerAddOps[0], LU.MinOffset, LU.MaxOffset,
+ Base.getNumRegs() > 1,
+ LU.Kind, LU.AccessTy, TLI, SE))
+ continue;
- const SCEVConstant *SC = dyn_cast<SCEVConstant>(AR->getStepRecurrence(*SE));
- if (!SC || SC->getValue()->getSExtValue() < 0)
- // If it's already counting down, don't do anything.
- return false;
+ Formula F = Base;
+ F.BaseRegs[i] = SE.getAddExpr(InnerAddOps);
+ F.BaseRegs.push_back(*J);
+ if (InsertFormula(LU, LUIdx, F))
+ // If that formula hadn't been seen before, recurse to find more like
+ // it.
+ GenerateReassociations(LU, LUIdx, LU.Formulae.back(), Depth+1);
+ }
+ }
+}
- // If the RHS of the comparison is not an loop invariant, the rewrite
- // cannot be done. Also bail out if it's already comparing against a zero.
- // If we are checking this before cmp stride optimization, check if it's
- // comparing against a already legal immediate.
- Value *RHS = Cond->getOperand(1);
- ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS);
- if (!L->isLoopInvariant(RHS) ||
- (RHSC && RHSC->isZero()) ||
- (RHSC && TLI && TLI->isLegalICmpImmediate(RHSC->getSExtValue())))
- return false;
+/// GenerateCombinations - Generate a formula consisting of all of the
+/// loop-dominating registers added into a single register.
+void LSRInstance::GenerateCombinations(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ // This method is only intersting on a plurality of registers.
+ if (Base.BaseRegs.size() <= 1) return;
+
+ Formula F = Base;
+ F.BaseRegs.clear();
+ SmallVector<const SCEV *, 4> Ops;
+ for (SmallVectorImpl<const SCEV *>::const_iterator
+ I = Base.BaseRegs.begin(), E = Base.BaseRegs.end(); I != E; ++I) {
+ const SCEV *BaseReg = *I;
+ if (BaseReg->properlyDominates(L->getHeader(), &DT) &&
+ !BaseReg->hasComputableLoopEvolution(L))
+ Ops.push_back(BaseReg);
+ else
+ F.BaseRegs.push_back(BaseReg);
+ }
+ if (Ops.size() > 1) {
+ const SCEV *Sum = SE.getAddExpr(Ops);
+ // TODO: If Sum is zero, it probably means ScalarEvolution missed an
+ // opportunity to fold something. For now, just ignore such cases
+ // rather than procede with zero in a register.
+ if (!Sum->isZero()) {
+ F.BaseRegs.push_back(Sum);
+ (void)InsertFormula(LU, LUIdx, F);
+ }
+ }
+}
- // Make sure the IV is only used for counting. Value may be preinc or
- // postinc; 2 uses in either case.
- if (!CondOp0->hasNUses(2))
- return false;
+/// GenerateSymbolicOffsets - Generate reuse formulae using symbolic offsets.
+void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ // We can't add a symbolic offset if the address already contains one.
+ if (Base.AM.BaseGV) return;
- return true;
+ for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
+ const SCEV *G = Base.BaseRegs[i];
+ GlobalValue *GV = ExtractSymbol(G, SE);
+ if (G->isZero() || !GV)
+ continue;
+ Formula F = Base;
+ F.AM.BaseGV = GV;
+ if (!isLegalUse(F.AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI))
+ continue;
+ F.BaseRegs[i] = G;
+ (void)InsertFormula(LU, LUIdx, F);
+ }
}
-/// OptimizeLoopTermCond - Change loop terminating condition to use the
-/// postinc iv when possible.
-void LoopStrengthReduce::OptimizeLoopTermCond(Loop *L) {
- BasicBlock *LatchBlock = L->getLoopLatch();
- bool LatchExit = L->isLoopExiting(LatchBlock);
- SmallVector<BasicBlock*, 8> ExitingBlocks;
- L->getExitingBlocks(ExitingBlocks);
+/// GenerateConstantOffsets - Generate reuse formulae using symbolic offsets.
+void LSRInstance::GenerateConstantOffsets(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ // TODO: For now, just add the min and max offset, because it usually isn't
+ // worthwhile looking at everything inbetween.
+ SmallVector<int64_t, 4> Worklist;
+ Worklist.push_back(LU.MinOffset);
+ if (LU.MaxOffset != LU.MinOffset)
+ Worklist.push_back(LU.MaxOffset);
+
+ for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
+ const SCEV *G = Base.BaseRegs[i];
+
+ for (SmallVectorImpl<int64_t>::const_iterator I = Worklist.begin(),
+ E = Worklist.end(); I != E; ++I) {
+ Formula F = Base;
+ F.AM.BaseOffs = (uint64_t)Base.AM.BaseOffs - *I;
+ if (isLegalUse(F.AM, LU.MinOffset - *I, LU.MaxOffset - *I,
+ LU.Kind, LU.AccessTy, TLI)) {
+ F.BaseRegs[i] = SE.getAddExpr(G, SE.getIntegerSCEV(*I, G->getType()));
+
+ (void)InsertFormula(LU, LUIdx, F);
+ }
+ }
- for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
- BasicBlock *ExitingBlock = ExitingBlocks[i];
+ int64_t Imm = ExtractImmediate(G, SE);
+ if (G->isZero() || Imm == 0)
+ continue;
+ Formula F = Base;
+ F.AM.BaseOffs = (uint64_t)F.AM.BaseOffs + Imm;
+ if (!isLegalUse(F.AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI))
+ continue;
+ F.BaseRegs[i] = G;
+ (void)InsertFormula(LU, LUIdx, F);
+ }
+}
- // Finally, get the terminating condition for the loop if possible. If we
- // can, we want to change it to use a post-incremented version of its
- // induction variable, to allow coalescing the live ranges for the IV into
- // one register value.
+/// GenerateICmpZeroScales - For ICmpZero, check to see if we can scale up
+/// the comparison. For example, x == y -> x*c == y*c.
+void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ if (LU.Kind != LSRUse::ICmpZero) return;
- BranchInst *TermBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
- if (!TermBr)
+ // Determine the integer type for the base formula.
+ const Type *IntTy = Base.getType();
+ if (!IntTy) return;
+ if (SE.getTypeSizeInBits(IntTy) > 64) return;
+
+ // Don't do this if there is more than one offset.
+ if (LU.MinOffset != LU.MaxOffset) return;
+
+ assert(!Base.AM.BaseGV && "ICmpZero use is not legal!");
+
+ // Check each interesting stride.
+ for (SmallSetVector<int64_t, 8>::const_iterator
+ I = Factors.begin(), E = Factors.end(); I != E; ++I) {
+ int64_t Factor = *I;
+ Formula F = Base;
+
+ // Check that the multiplication doesn't overflow.
+ F.AM.BaseOffs = (uint64_t)Base.AM.BaseOffs * Factor;
+ if ((int64_t)F.AM.BaseOffs / Factor != Base.AM.BaseOffs)
continue;
- // FIXME: Overly conservative, termination condition could be an 'or' etc..
- if (TermBr->isUnconditional() || !isa<ICmpInst>(TermBr->getCondition()))
+
+ // Check that multiplying with the use offset doesn't overflow.
+ int64_t Offset = LU.MinOffset;
+ Offset = (uint64_t)Offset * Factor;
+ if ((int64_t)Offset / Factor != LU.MinOffset)
continue;
- // Search IVUsesByStride to find Cond's IVUse if there is one.
- IVStrideUse *CondUse = 0;
- const SCEV *CondStride = 0;
- ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
- if (!FindIVUserForCond(Cond, CondUse, CondStride))
+ // Check that this scale is legal.
+ if (!isLegalUse(F.AM, Offset, Offset, LU.Kind, LU.AccessTy, TLI))
continue;
- // If the latch block is exiting and it's not a single block loop, it's
- // not safe to use postinc iv in other exiting blocks. FIXME: overly
- // conservative? How about icmp stride optimization?
- bool UsePostInc = !(e > 1 && LatchExit && ExitingBlock != LatchBlock);
- if (UsePostInc && ExitingBlock != LatchBlock) {
- if (!Cond->hasOneUse())
- // See below, we don't want the condition to be cloned.
- UsePostInc = false;
- else {
- // If exiting block is the latch block, we know it's safe and profitable
- // to transform the icmp to use post-inc iv. Otherwise do so only if it
- // would not reuse another iv and its iv would be reused by other uses.
- // We are optimizing for the case where the icmp is the only use of the
- // iv.
- IVUsersOfOneStride &StrideUses = *IU->IVUsesByStride[CondStride];
- for (ilist<IVStrideUse>::iterator I = StrideUses.Users.begin(),
- E = StrideUses.Users.end(); I != E; ++I) {
- if (I->getUser() == Cond)
- continue;
- if (!I->isUseOfPostIncrementedValue()) {
- UsePostInc = false;
- break;
- }
+ // Compensate for the use having MinOffset built into it.
+ F.AM.BaseOffs = (uint64_t)F.AM.BaseOffs + Offset - LU.MinOffset;
+
+ const SCEV *FactorS = SE.getIntegerSCEV(Factor, IntTy);
+
+ // Check that multiplying with each base register doesn't overflow.
+ for (size_t i = 0, e = F.BaseRegs.size(); i != e; ++i) {
+ F.BaseRegs[i] = SE.getMulExpr(F.BaseRegs[i], FactorS);
+ if (getSDiv(F.BaseRegs[i], FactorS, SE) != Base.BaseRegs[i])
+ goto next;
+ }
+
+ // Check that multiplying with the scaled register doesn't overflow.
+ if (F.ScaledReg) {
+ F.ScaledReg = SE.getMulExpr(F.ScaledReg, FactorS);
+ if (getSDiv(F.ScaledReg, FactorS, SE) != Base.ScaledReg)
+ continue;
+ }
+
+ // If we make it here and it's legal, add it.
+ (void)InsertFormula(LU, LUIdx, F);
+ next:;
+ }
+}
+
+/// GenerateScales - Generate stride factor reuse formulae by making use of
+/// scaled-offset address modes, for example.
+void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ // Determine the integer type for the base formula.
+ const Type *IntTy = Base.getType();
+ if (!IntTy) return;
+
+ // If this Formula already has a scaled register, we can't add another one.
+ if (Base.AM.Scale != 0) return;
+
+ // Check each interesting stride.
+ for (SmallSetVector<int64_t, 8>::const_iterator
+ I = Factors.begin(), E = Factors.end(); I != E; ++I) {
+ int64_t Factor = *I;
+
+ Base.AM.Scale = Factor;
+ Base.AM.HasBaseReg = Base.BaseRegs.size() > 1;
+ // Check whether this scale is going to be legal.
+ if (!isLegalUse(Base.AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI)) {
+ // As a special-case, handle special out-of-loop Basic users specially.
+ // TODO: Reconsider this special case.
+ if (LU.Kind == LSRUse::Basic &&
+ isLegalUse(Base.AM, LU.MinOffset, LU.MaxOffset,
+ LSRUse::Special, LU.AccessTy, TLI) &&
+ LU.AllFixupsOutsideLoop)
+ LU.Kind = LSRUse::Special;
+ else
+ continue;
+ }
+ // For an ICmpZero, negating a solitary base register won't lead to
+ // new solutions.
+ if (LU.Kind == LSRUse::ICmpZero &&
+ !Base.AM.HasBaseReg && Base.AM.BaseOffs == 0 && !Base.AM.BaseGV)
+ continue;
+ // For each addrec base reg, apply the scale, if possible.
+ for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i)
+ if (const SCEVAddRecExpr *AR =
+ dyn_cast<SCEVAddRecExpr>(Base.BaseRegs[i])) {
+ const SCEV *FactorS = SE.getIntegerSCEV(Factor, IntTy);
+ if (FactorS->isZero())
+ continue;
+ // Divide out the factor, ignoring high bits, since we'll be
+ // scaling the value back up in the end.
+ if (const SCEV *Quotient = getSDiv(AR, FactorS, SE, true)) {
+ // TODO: This could be optimized to avoid all the copying.
+ Formula F = Base;
+ F.ScaledReg = Quotient;
+ std::swap(F.BaseRegs[i], F.BaseRegs.back());
+ F.BaseRegs.pop_back();
+ (void)InsertFormula(LU, LUIdx, F);
}
}
+ }
+}
- // If iv for the stride might be shared and any of the users use pre-inc
- // iv might be used, then it's not safe to use post-inc iv.
- if (UsePostInc &&
- isa<SCEVConstant>(CondStride) &&
- StrideMightBeShared(CondStride, L, true))
- UsePostInc = false;
- }
+/// GenerateTruncates - Generate reuse formulae from different IV types.
+void LSRInstance::GenerateTruncates(LSRUse &LU, unsigned LUIdx,
+ Formula Base) {
+ // This requires TargetLowering to tell us which truncates are free.
+ if (!TLI) return;
+
+ // Don't bother truncating symbolic values.
+ if (Base.AM.BaseGV) return;
+
+ // Determine the integer type for the base formula.
+ const Type *DstTy = Base.getType();
+ if (!DstTy) return;
+ DstTy = SE.getEffectiveSCEVType(DstTy);
+
+ for (SmallSetVector<const Type *, 4>::const_iterator
+ I = Types.begin(), E = Types.end(); I != E; ++I) {
+ const Type *SrcTy = *I;
+ if (SrcTy != DstTy && TLI->isTruncateFree(SrcTy, DstTy)) {
+ Formula F = Base;
+
+ if (F.ScaledReg) F.ScaledReg = SE.getAnyExtendExpr(F.ScaledReg, *I);
+ for (SmallVectorImpl<const SCEV *>::iterator J = F.BaseRegs.begin(),
+ JE = F.BaseRegs.end(); J != JE; ++J)
+ *J = SE.getAnyExtendExpr(*J, SrcTy);
+
+ // TODO: This assumes we've done basic processing on all uses and
+ // have an idea what the register usage is.
+ if (!F.hasRegsUsedByUsesOtherThan(LUIdx, RegUses))
+ continue;
- // If the trip count is computed in terms of a max (due to ScalarEvolution
- // being unable to find a sufficient guard, for example), change the loop
- // comparison to use SLT or ULT instead of NE.
- Cond = OptimizeMax(L, Cond, CondUse);
-
- // If possible, change stride and operands of the compare instruction to
- // eliminate one stride. However, avoid rewriting the compare instruction
- // with an iv of new stride if it's likely the new stride uses will be
- // rewritten using the stride of the compare instruction.
- if (ExitingBlock == LatchBlock && isa<SCEVConstant>(CondStride)) {
- // If the condition stride is a constant and it's the only use, we might
- // want to optimize it first by turning it to count toward zero.
- if (!StrideMightBeShared(CondStride, L, false) &&
- !ShouldCountToZero(Cond, CondUse, SE, L, TLI))
- Cond = ChangeCompareStride(L, Cond, CondUse, CondStride);
+ (void)InsertFormula(LU, LUIdx, F);
}
+ }
+}
+
+namespace {
+
+/// WorkItem - Helper class for GenerateCrossUseConstantOffsets. It's used to
+/// defer modifications so that the search phase doesn't have to worry about
+/// the data structures moving underneath it.
+struct WorkItem {
+ size_t LUIdx;
+ int64_t Imm;
+ const SCEV *OrigReg;
+
+ WorkItem(size_t LI, int64_t I, const SCEV *R)
+ : LUIdx(LI), Imm(I), OrigReg(R) {}
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
+
+}
+
+void WorkItem::print(raw_ostream &OS) const {
+ OS << "in formulae referencing " << *OrigReg << " in use " << LUIdx
+ << " , add offset " << Imm;
+}
+
+void WorkItem::dump() const {
+ print(errs()); errs() << '\n';
+}
+
+/// GenerateCrossUseConstantOffsets - Look for registers which are a constant
+/// distance apart and try to form reuse opportunities between them.
+void LSRInstance::GenerateCrossUseConstantOffsets() {
+ // Group the registers by their value without any added constant offset.
+ typedef std::map<int64_t, const SCEV *> ImmMapTy;
+ typedef DenseMap<const SCEV *, ImmMapTy> RegMapTy;
+ RegMapTy Map;
+ DenseMap<const SCEV *, SmallBitVector> UsedByIndicesMap;
+ SmallVector<const SCEV *, 8> Sequence;
+ for (RegUseTracker::const_iterator I = RegUses.begin(), E = RegUses.end();
+ I != E; ++I) {
+ const SCEV *Reg = *I;
+ int64_t Imm = ExtractImmediate(Reg, SE);
+ std::pair<RegMapTy::iterator, bool> Pair =
+ Map.insert(std::make_pair(Reg, ImmMapTy()));
+ if (Pair.second)
+ Sequence.push_back(Reg);
+ Pair.first->second.insert(std::make_pair(Imm, *I));
+ UsedByIndicesMap[Reg] |= RegUses.getUsedByIndices(*I);
+ }
- if (!UsePostInc)
+ // Now examine each set of registers with the same base value. Build up
+ // a list of work to do and do the work in a separate step so that we're
+ // not adding formulae and register counts while we're searching.
+ SmallVector<WorkItem, 32> WorkItems;
+ SmallSet<std::pair<size_t, int64_t>, 32> UniqueItems;
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = Sequence.begin(),
+ E = Sequence.end(); I != E; ++I) {
+ const SCEV *Reg = *I;
+ const ImmMapTy &Imms = Map.find(Reg)->second;
+
+ // It's not worthwhile looking for reuse if there's only one offset.
+ if (Imms.size() == 1)
continue;
- DEBUG(dbgs() << " Change loop exiting icmp to use postinc iv: "
- << *Cond << '\n');
+ DEBUG(dbgs() << "Generating cross-use offsets for " << *Reg << ':';
+ for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
+ J != JE; ++J)
+ dbgs() << ' ' << J->first;
+ dbgs() << '\n');
- // It's possible for the setcc instruction to be anywhere in the loop, and
- // possible for it to have multiple users. If it is not immediately before
- // the exiting block branch, move it.
- if (&*++BasicBlock::iterator(Cond) != (Instruction*)TermBr) {
- if (Cond->hasOneUse()) { // Condition has a single use, just move it.
- Cond->moveBefore(TermBr);
- } else {
- // Otherwise, clone the terminating condition and insert into the
- // loopend.
- Cond = cast<ICmpInst>(Cond->clone());
- Cond->setName(L->getHeader()->getName() + ".termcond");
- ExitingBlock->getInstList().insert(TermBr, Cond);
+ // Examine each offset.
+ for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
+ J != JE; ++J) {
+ const SCEV *OrigReg = J->second;
- // Clone the IVUse, as the old use still exists!
- IU->IVUsesByStride[CondStride]->addUser(CondUse->getOffset(), Cond,
- CondUse->getOperandValToReplace());
- CondUse = &IU->IVUsesByStride[CondStride]->Users.back();
+ int64_t JImm = J->first;
+ const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(OrigReg);
+
+ if (!isa<SCEVConstant>(OrigReg) &&
+ UsedByIndicesMap[Reg].count() == 1) {
+ DEBUG(dbgs() << "Skipping cross-use reuse for " << *OrigReg << '\n');
+ continue;
+ }
+
+ // Conservatively examine offsets between this orig reg a few selected
+ // other orig regs.
+ ImmMapTy::const_iterator OtherImms[] = {
+ Imms.begin(), prior(Imms.end()),
+ Imms.upper_bound((Imms.begin()->first + prior(Imms.end())->first) / 2)
+ };
+ for (size_t i = 0, e = array_lengthof(OtherImms); i != e; ++i) {
+ ImmMapTy::const_iterator M = OtherImms[i];
+ if (M == J || M == JE) continue;
+
+ // Compute the difference between the two.
+ int64_t Imm = (uint64_t)JImm - M->first;
+ for (int LUIdx = UsedByIndices.find_first(); LUIdx != -1;
+ LUIdx = UsedByIndices.find_next(LUIdx))
+ // Make a memo of this use, offset, and register tuple.
+ if (UniqueItems.insert(std::make_pair(LUIdx, Imm)))
+ WorkItems.push_back(WorkItem(LUIdx, Imm, OrigReg));
}
}
+ }
- // If we get to here, we know that we can transform the setcc instruction to
- // use the post-incremented version of the IV, allowing us to coalesce the
- // live ranges for the IV correctly.
- CondUse->setOffset(SE->getMinusSCEV(CondUse->getOffset(), CondStride));
- CondUse->setIsUseOfPostIncrementedValue(true);
- Changed = true;
+ Map.clear();
+ Sequence.clear();
+ UsedByIndicesMap.clear();
+ UniqueItems.clear();
+
+ // Now iterate through the worklist and add new formulae.
+ for (SmallVectorImpl<WorkItem>::const_iterator I = WorkItems.begin(),
+ E = WorkItems.end(); I != E; ++I) {
+ const WorkItem &WI = *I;
+ size_t LUIdx = WI.LUIdx;
+ LSRUse &LU = Uses[LUIdx];
+ int64_t Imm = WI.Imm;
+ const SCEV *OrigReg = WI.OrigReg;
+
+ const Type *IntTy = SE.getEffectiveSCEVType(OrigReg->getType());
+ const SCEV *NegImmS = SE.getSCEV(ConstantInt::get(IntTy, -(uint64_t)Imm));
+ unsigned BitWidth = SE.getTypeSizeInBits(IntTy);
+
+ // TODO: Use a more targetted data structure.
+ for (size_t L = 0, LE = LU.Formulae.size(); L != LE; ++L) {
+ Formula F = LU.Formulae[L];
+ // Use the immediate in the scaled register.
+ if (F.ScaledReg == OrigReg) {
+ int64_t Offs = (uint64_t)F.AM.BaseOffs +
+ Imm * (uint64_t)F.AM.Scale;
+ // Don't create 50 + reg(-50).
+ if (F.referencesReg(SE.getSCEV(
+ ConstantInt::get(IntTy, -(uint64_t)Offs))))
+ continue;
+ Formula NewF = F;
+ NewF.AM.BaseOffs = Offs;
+ if (!isLegalUse(NewF.AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI))
+ continue;
+ NewF.ScaledReg = SE.getAddExpr(NegImmS, NewF.ScaledReg);
+
+ // If the new scale is a constant in a register, and adding the constant
+ // value to the immediate would produce a value closer to zero than the
+ // immediate itself, then the formula isn't worthwhile.
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(NewF.ScaledReg))
+ if (C->getValue()->getValue().isNegative() !=
+ (NewF.AM.BaseOffs < 0) &&
+ (C->getValue()->getValue().abs() * APInt(BitWidth, F.AM.Scale))
+ .ule(APInt(BitWidth, NewF.AM.BaseOffs).abs()))
+ continue;
- ++NumLoopCond;
+ // OK, looks good.
+ (void)InsertFormula(LU, LUIdx, NewF);
+ } else {
+ // Use the immediate in a base register.
+ for (size_t N = 0, NE = F.BaseRegs.size(); N != NE; ++N) {
+ const SCEV *BaseReg = F.BaseRegs[N];
+ if (BaseReg != OrigReg)
+ continue;
+ Formula NewF = F;
+ NewF.AM.BaseOffs = (uint64_t)NewF.AM.BaseOffs + Imm;
+ if (!isLegalUse(NewF.AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI))
+ continue;
+ NewF.BaseRegs[N] = SE.getAddExpr(NegImmS, BaseReg);
+
+ // If the new formula has a constant in a register, and adding the
+ // constant value to the immediate would produce a value closer to
+ // zero than the immediate itself, then the formula isn't worthwhile.
+ for (SmallVectorImpl<const SCEV *>::const_iterator
+ J = NewF.BaseRegs.begin(), JE = NewF.BaseRegs.end();
+ J != JE; ++J)
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(*J))
+ if (C->getValue()->getValue().isNegative() !=
+ (NewF.AM.BaseOffs < 0) &&
+ C->getValue()->getValue().abs()
+ .ule(APInt(BitWidth, NewF.AM.BaseOffs).abs()))
+ goto skip_formula;
+
+ // Ok, looks good.
+ (void)InsertFormula(LU, LUIdx, NewF);
+ break;
+ skip_formula:;
+ }
+ }
+ }
}
}
-bool LoopStrengthReduce::OptimizeLoopCountIVOfStride(const SCEV* &Stride,
- IVStrideUse* &CondUse,
- Loop *L) {
- // If the only use is an icmp of a loop exiting conditional branch, then
- // attempt the optimization.
- BasedUser User = BasedUser(*CondUse, SE);
- assert(isa<ICmpInst>(User.Inst) && "Expecting an ICMPInst!");
- ICmpInst *Cond = cast<ICmpInst>(User.Inst);
+/// GenerateAllReuseFormulae - Generate formulae for each use.
+void
+LSRInstance::GenerateAllReuseFormulae() {
+ // This is split into multiple loops so that hasRegsUsedByUsesOtherThan
+ // queries are more precise.
+ for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
+ LSRUse &LU = Uses[LUIdx];
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateReassociations(LU, LUIdx, LU.Formulae[i]);
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateCombinations(LU, LUIdx, LU.Formulae[i]);
+ }
+ for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
+ LSRUse &LU = Uses[LUIdx];
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateSymbolicOffsets(LU, LUIdx, LU.Formulae[i]);
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateConstantOffsets(LU, LUIdx, LU.Formulae[i]);
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateICmpZeroScales(LU, LUIdx, LU.Formulae[i]);
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateScales(LU, LUIdx, LU.Formulae[i]);
+ }
+ for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
+ LSRUse &LU = Uses[LUIdx];
+ for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
+ GenerateTruncates(LU, LUIdx, LU.Formulae[i]);
+ }
- // Less strict check now that compare stride optimization is done.
- if (!ShouldCountToZero(Cond, CondUse, SE, L))
- return false;
+ GenerateCrossUseConstantOffsets();
+}
- Value *CondOp0 = Cond->getOperand(0);
- PHINode *PHIExpr = dyn_cast<PHINode>(CondOp0);
- Instruction *Incr;
- if (!PHIExpr) {
- // Value tested is postinc. Find the phi node.
- Incr = dyn_cast<BinaryOperator>(CondOp0);
- // FIXME: Just use User.OperandValToReplace here?
- if (!Incr || Incr->getOpcode() != Instruction::Add)
- return false;
+/// If their are multiple formulae with the same set of registers used
+/// by other uses, pick the best one and delete the others.
+void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
+#ifndef NDEBUG
+ bool Changed = false;
+#endif
+
+ // Collect the best formula for each unique set of shared registers. This
+ // is reset for each use.
+ typedef DenseMap<SmallVector<const SCEV *, 2>, size_t, UniquifierDenseMapInfo>
+ BestFormulaeTy;
+ BestFormulaeTy BestFormulae;
+
+ for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
+ LSRUse &LU = Uses[LUIdx];
+ FormulaSorter Sorter(L, LU, SE, DT);
+
+ // Clear out the set of used regs; it will be recomputed.
+ LU.Regs.clear();
+
+ for (size_t FIdx = 0, NumForms = LU.Formulae.size();
+ FIdx != NumForms; ++FIdx) {
+ Formula &F = LU.Formulae[FIdx];
+
+ SmallVector<const SCEV *, 2> Key;
+ for (SmallVectorImpl<const SCEV *>::const_iterator J = F.BaseRegs.begin(),
+ JE = F.BaseRegs.end(); J != JE; ++J) {
+ const SCEV *Reg = *J;
+ if (RegUses.isRegUsedByUsesOtherThan(Reg, LUIdx))
+ Key.push_back(Reg);
+ }
+ if (F.ScaledReg &&
+ RegUses.isRegUsedByUsesOtherThan(F.ScaledReg, LUIdx))
+ Key.push_back(F.ScaledReg);
+ // Unstable sort by host order ok, because this is only used for
+ // uniquifying.
+ std::sort(Key.begin(), Key.end());
+
+ std::pair<BestFormulaeTy::const_iterator, bool> P =
+ BestFormulae.insert(std::make_pair(Key, FIdx));
+ if (!P.second) {
+ Formula &Best = LU.Formulae[P.first->second];
+ if (Sorter.operator()(F, Best))
+ std::swap(F, Best);
+ DEBUG(dbgs() << "Filtering out "; F.print(dbgs());
+ dbgs() << "\n"
+ " in favor of "; Best.print(dbgs());
+ dbgs() << '\n');
+#ifndef NDEBUG
+ Changed = true;
+#endif
+ std::swap(F, LU.Formulae.back());
+ LU.Formulae.pop_back();
+ --FIdx;
+ --NumForms;
+ continue;
+ }
+ if (F.ScaledReg) LU.Regs.insert(F.ScaledReg);
+ LU.Regs.insert(F.BaseRegs.begin(), F.BaseRegs.end());
+ }
+ BestFormulae.clear();
+ }
- PHIExpr = dyn_cast<PHINode>(Incr->getOperand(0));
- if (!PHIExpr)
- return false;
- // 1 use for preinc value, the increment.
- if (!PHIExpr->hasOneUse())
- return false;
- } else {
- assert(isa<PHINode>(CondOp0) &&
- "Unexpected loop exiting counting instruction sequence!");
- PHIExpr = cast<PHINode>(CondOp0);
- // Value tested is preinc. Find the increment.
- // A CmpInst is not a BinaryOperator; we depend on this.
- Instruction::use_iterator UI = PHIExpr->use_begin();
- Incr = dyn_cast<BinaryOperator>(UI);
- if (!Incr)
- Incr = dyn_cast<BinaryOperator>(++UI);
- // One use for postinc value, the phi. Unnecessarily conservative?
- if (!Incr || !Incr->hasOneUse() || Incr->getOpcode() != Instruction::Add)
- return false;
+ DEBUG(if (Changed) {
+ dbgs() << "\n"
+ "After filtering out undesirable candidates:\n";
+ print_uses(dbgs());
+ });
+}
+
+/// NarrowSearchSpaceUsingHeuristics - If there are an extrordinary number of
+/// formulae to choose from, use some rough heuristics to prune down the number
+/// of formulae. This keeps the main solver from taking an extrordinary amount
+/// of time in some worst-case scenarios.
+void LSRInstance::NarrowSearchSpaceUsingHeuristics() {
+ // This is a rough guess that seems to work fairly well.
+ const size_t Limit = UINT16_MAX;
+
+ SmallPtrSet<const SCEV *, 4> Taken;
+ for (;;) {
+ // Estimate the worst-case number of solutions we might consider. We almost
+ // never consider this many solutions because we prune the search space,
+ // but the pruning isn't always sufficient.
+ uint32_t Power = 1;
+ for (SmallVectorImpl<LSRUse>::const_iterator I = Uses.begin(),
+ E = Uses.end(); I != E; ++I) {
+ size_t FSize = I->Formulae.size();
+ if (FSize >= Limit) {
+ Power = Limit;
+ break;
+ }
+ Power *= FSize;
+ if (Power >= Limit)
+ break;
+ }
+ if (Power < Limit)
+ break;
+
+ // Ok, we have too many of formulae on our hands to conveniently handle.
+ // Use a rough heuristic to thin out the list.
+
+ // Pick the register which is used by the most LSRUses, which is likely
+ // to be a good reuse register candidate.
+ const SCEV *Best = 0;
+ unsigned BestNum = 0;
+ for (RegUseTracker::const_iterator I = RegUses.begin(), E = RegUses.end();
+ I != E; ++I) {
+ const SCEV *Reg = *I;
+ if (Taken.count(Reg))
+ continue;
+ if (!Best)
+ Best = Reg;
+ else {
+ unsigned Count = RegUses.getUsedByIndices(Reg).count();
+ if (Count > BestNum) {
+ Best = Reg;
+ BestNum = Count;
+ }
+ }
+ }
+
+ DEBUG(dbgs() << "Narrowing the search space by assuming " << *Best
+ << " will yeild profitable reuse.\n");
+ Taken.insert(Best);
+
+ // In any use with formulae which references this register, delete formulae
+ // which don't reference it.
+ for (SmallVectorImpl<LSRUse>::iterator I = Uses.begin(),
+ E = Uses.end(); I != E; ++I) {
+ LSRUse &LU = *I;
+ if (!LU.Regs.count(Best)) continue;
+
+ // Clear out the set of used regs; it will be recomputed.
+ LU.Regs.clear();
+
+ for (size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
+ Formula &F = LU.Formulae[i];
+ if (!F.referencesReg(Best)) {
+ DEBUG(dbgs() << " Deleting "; F.print(dbgs()); dbgs() << '\n');
+ std::swap(LU.Formulae.back(), F);
+ LU.Formulae.pop_back();
+ --e;
+ --i;
+ continue;
+ }
+
+ if (F.ScaledReg) LU.Regs.insert(F.ScaledReg);
+ LU.Regs.insert(F.BaseRegs.begin(), F.BaseRegs.end());
+ }
+ }
+
+ DEBUG(dbgs() << "After pre-selection:\n";
+ print_uses(dbgs()));
}
+}
- // Replace the increment with a decrement.
- DEBUG(dbgs() << "LSR: Examining use ");
- DEBUG(WriteAsOperand(dbgs(), CondOp0, /*PrintType=*/false));
- DEBUG(dbgs() << " in Inst: " << *Cond << '\n');
- BinaryOperator *Decr = BinaryOperator::Create(Instruction::Sub,
- Incr->getOperand(0), Incr->getOperand(1), "tmp", Incr);
- Incr->replaceAllUsesWith(Decr);
- Incr->eraseFromParent();
-
- // Substitute endval-startval for the original startval, and 0 for the
- // original endval. Since we're only testing for equality this is OK even
- // if the computation wraps around.
- BasicBlock *Preheader = L->getLoopPreheader();
- Instruction *PreInsertPt = Preheader->getTerminator();
- unsigned InBlock = L->contains(PHIExpr->getIncomingBlock(0)) ? 1 : 0;
- Value *StartVal = PHIExpr->getIncomingValue(InBlock);
- Value *EndVal = Cond->getOperand(1);
- DEBUG(dbgs() << " Optimize loop counting iv to count down ["
- << *EndVal << " .. " << *StartVal << "]\n");
-
- // FIXME: check for case where both are constant.
- Constant* Zero = ConstantInt::get(Cond->getOperand(1)->getType(), 0);
- BinaryOperator *NewStartVal = BinaryOperator::Create(Instruction::Sub,
- EndVal, StartVal, "tmp", PreInsertPt);
- PHIExpr->setIncomingValue(InBlock, NewStartVal);
- Cond->setOperand(1, Zero);
- DEBUG(dbgs() << " New icmp: " << *Cond << "\n");
-
- int64_t SInt = cast<SCEVConstant>(Stride)->getValue()->getSExtValue();
- const SCEV *NewStride = 0;
- bool Found = false;
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- const SCEV *OldStride = IU->StrideOrder[i];
- if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(OldStride))
- if (SC->getValue()->getSExtValue() == -SInt) {
- Found = true;
- NewStride = OldStride;
+/// SolveRecurse - This is the recursive solver.
+void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
+ Cost &SolutionCost,
+ SmallVectorImpl<const Formula *> &Workspace,
+ const Cost &CurCost,
+ const SmallPtrSet<const SCEV *, 16> &CurRegs,
+ DenseSet<const SCEV *> &VisitedRegs) const {
+ // Some ideas:
+ // - prune more:
+ // - use more aggressive filtering
+ // - sort the formula so that the most profitable solutions are found first
+ // - sort the uses too
+ // - search faster:
+ // - dont compute a cost, and then compare. compare while computing a cost
+ // and bail early.
+ // - track register sets with SmallBitVector
+
+ const LSRUse &LU = Uses[Workspace.size()];
+
+ // If this use references any register that's already a part of the
+ // in-progress solution, consider it a requirement that a formula must
+ // reference that register in order to be considered. This prunes out
+ // unprofitable searching.
+ SmallSetVector<const SCEV *, 4> ReqRegs;
+ for (SmallPtrSet<const SCEV *, 16>::const_iterator I = CurRegs.begin(),
+ E = CurRegs.end(); I != E; ++I)
+ if (LU.Regs.count(*I))
+ ReqRegs.insert(*I);
+
+ bool AnySatisfiedReqRegs = false;
+ SmallPtrSet<const SCEV *, 16> NewRegs;
+ Cost NewCost;
+retry:
+ for (SmallVectorImpl<Formula>::const_iterator I = LU.Formulae.begin(),
+ E = LU.Formulae.end(); I != E; ++I) {
+ const Formula &F = *I;
+
+ // Ignore formulae which do not use any of the required registers.
+ for (SmallSetVector<const SCEV *, 4>::const_iterator J = ReqRegs.begin(),
+ JE = ReqRegs.end(); J != JE; ++J) {
+ const SCEV *Reg = *J;
+ if ((!F.ScaledReg || F.ScaledReg != Reg) &&
+ std::find(F.BaseRegs.begin(), F.BaseRegs.end(), Reg) ==
+ F.BaseRegs.end())
+ goto skip;
+ }
+ AnySatisfiedReqRegs = true;
+
+ // Evaluate the cost of the current formula. If it's already worse than
+ // the current best, prune the search at that point.
+ NewCost = CurCost;
+ NewRegs = CurRegs;
+ NewCost.RateFormula(F, NewRegs, VisitedRegs, L, LU.Offsets, SE, DT);
+ if (NewCost < SolutionCost) {
+ Workspace.push_back(&F);
+ if (Workspace.size() != Uses.size()) {
+ SolveRecurse(Solution, SolutionCost, Workspace, NewCost,
+ NewRegs, VisitedRegs);
+ if (F.getNumRegs() == 1 && Workspace.size() == 1)
+ VisitedRegs.insert(F.ScaledReg ? F.ScaledReg : F.BaseRegs[0]);
+ } else {
+ DEBUG(dbgs() << "New best at "; NewCost.print(dbgs());
+ dbgs() << ". Regs:";
+ for (SmallPtrSet<const SCEV *, 16>::const_iterator
+ I = NewRegs.begin(), E = NewRegs.end(); I != E; ++I)
+ dbgs() << ' ' << **I;
+ dbgs() << '\n');
+
+ SolutionCost = NewCost;
+ Solution = Workspace;
+ }
+ Workspace.pop_back();
+ }
+ skip:;
+ }
+
+ // If none of the formulae had all of the required registers, relax the
+ // constraint so that we don't exclude all formulae.
+ if (!AnySatisfiedReqRegs) {
+ ReqRegs.clear();
+ goto retry;
+ }
+}
+
+void LSRInstance::Solve(SmallVectorImpl<const Formula *> &Solution) const {
+ SmallVector<const Formula *, 8> Workspace;
+ Cost SolutionCost;
+ SolutionCost.Loose();
+ Cost CurCost;
+ SmallPtrSet<const SCEV *, 16> CurRegs;
+ DenseSet<const SCEV *> VisitedRegs;
+ Workspace.reserve(Uses.size());
+
+ SolveRecurse(Solution, SolutionCost, Workspace, CurCost,
+ CurRegs, VisitedRegs);
+
+ // Ok, we've now made all our decisions.
+ DEBUG(dbgs() << "\n"
+ "The chosen solution requires "; SolutionCost.print(dbgs());
+ dbgs() << ":\n";
+ for (size_t i = 0, e = Uses.size(); i != e; ++i) {
+ dbgs() << " ";
+ Uses[i].print(dbgs());
+ dbgs() << "\n"
+ " ";
+ Solution[i]->print(dbgs());
+ dbgs() << '\n';
+ });
+}
+
+/// getImmediateDominator - A handy utility for the specific DominatorTree
+/// query that we need here.
+///
+static BasicBlock *getImmediateDominator(BasicBlock *BB, DominatorTree &DT) {
+ DomTreeNode *Node = DT.getNode(BB);
+ if (!Node) return 0;
+ Node = Node->getIDom();
+ if (!Node) return 0;
+ return Node->getBlock();
+}
+
+Value *LSRInstance::Expand(const LSRFixup &LF,
+ const Formula &F,
+ BasicBlock::iterator IP,
+ Loop *L, Instruction *IVIncInsertPos,
+ SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakVH> &DeadInsts,
+ ScalarEvolution &SE, DominatorTree &DT) const {
+ const LSRUse &LU = Uses[LF.LUIdx];
+
+ // Then, collect some instructions which we will remain dominated by when
+ // expanding the replacement. These must be dominated by any operands that
+ // will be required in the expansion.
+ SmallVector<Instruction *, 4> Inputs;
+ if (Instruction *I = dyn_cast<Instruction>(LF.OperandValToReplace))
+ Inputs.push_back(I);
+ if (LU.Kind == LSRUse::ICmpZero)
+ if (Instruction *I =
+ dyn_cast<Instruction>(cast<ICmpInst>(LF.UserInst)->getOperand(1)))
+ Inputs.push_back(I);
+ if (LF.PostIncLoop && !L->contains(LF.UserInst))
+ Inputs.push_back(L->getLoopLatch()->getTerminator());
+
+ // Then, climb up the immediate dominator tree as far as we can go while
+ // still being dominated by the input positions.
+ for (;;) {
+ bool AllDominate = true;
+ Instruction *BetterPos = 0;
+ BasicBlock *IDom = getImmediateDominator(IP->getParent(), DT);
+ if (!IDom) break;
+ Instruction *Tentative = IDom->getTerminator();
+ for (SmallVectorImpl<Instruction *>::const_iterator I = Inputs.begin(),
+ E = Inputs.end(); I != E; ++I) {
+ Instruction *Inst = *I;
+ if (Inst == Tentative || !DT.dominates(Inst, Tentative)) {
+ AllDominate = false;
break;
}
+ if (IDom == Inst->getParent() &&
+ (!BetterPos || DT.dominates(BetterPos, Inst)))
+ BetterPos = next(BasicBlock::iterator(Inst));
+ }
+ if (!AllDominate)
+ break;
+ if (BetterPos)
+ IP = BetterPos;
+ else
+ IP = Tentative;
}
+ while (isa<PHINode>(IP)) ++IP;
+
+ // Inform the Rewriter if we have a post-increment use, so that it can
+ // perform an advantageous expansion.
+ Rewriter.setPostInc(LF.PostIncLoop);
+
+ // This is the type that the user actually needs.
+ const Type *OpTy = LF.OperandValToReplace->getType();
+ // This will be the type that we'll initially expand to.
+ const Type *Ty = F.getType();
+ if (!Ty)
+ // No type known; just expand directly to the ultimate type.
+ Ty = OpTy;
+ else if (SE.getEffectiveSCEVType(Ty) == SE.getEffectiveSCEVType(OpTy))
+ // Expand directly to the ultimate type if it's the right size.
+ Ty = OpTy;
+ // This is the type to do integer arithmetic in.
+ const Type *IntTy = SE.getEffectiveSCEVType(Ty);
+
+ // Build up a list of operands to add together to form the full base.
+ SmallVector<const SCEV *, 8> Ops;
+
+ // Expand the BaseRegs portion.
+ for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(),
+ E = F.BaseRegs.end(); I != E; ++I) {
+ const SCEV *Reg = *I;
+ assert(!Reg->isZero() && "Zero allocated in a base register!");
+
+ // If we're expanding for a post-inc user for the add-rec's loop, make the
+ // post-inc adjustment.
+ const SCEV *Start = Reg;
+ while (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Start)) {
+ if (AR->getLoop() == LF.PostIncLoop) {
+ Reg = SE.getAddExpr(Reg, AR->getStepRecurrence(SE));
+ // If the user is inside the loop, insert the code after the increment
+ // so that it is dominated by its operand.
+ if (L->contains(LF.UserInst))
+ IP = IVIncInsertPos;
+ break;
+ }
+ Start = AR->getStart();
+ }
- if (!Found)
- NewStride = SE->getIntegerSCEV(-SInt, Stride->getType());
- IU->AddUser(NewStride, CondUse->getOffset(), Cond, Cond->getOperand(0));
- IU->IVUsesByStride[Stride]->removeUser(CondUse);
+ Ops.push_back(SE.getUnknown(Rewriter.expandCodeFor(Reg, 0, IP)));
+ }
- CondUse = &IU->IVUsesByStride[NewStride]->Users.back();
- Stride = NewStride;
+ // Expand the ScaledReg portion.
+ Value *ICmpScaledV = 0;
+ if (F.AM.Scale != 0) {
+ const SCEV *ScaledS = F.ScaledReg;
+
+ // If we're expanding for a post-inc user for the add-rec's loop, make the
+ // post-inc adjustment.
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(ScaledS))
+ if (AR->getLoop() == LF.PostIncLoop)
+ ScaledS = SE.getAddExpr(ScaledS, AR->getStepRecurrence(SE));
+
+ if (LU.Kind == LSRUse::ICmpZero) {
+ // An interesting way of "folding" with an icmp is to use a negated
+ // scale, which we'll implement by inserting it into the other operand
+ // of the icmp.
+ assert(F.AM.Scale == -1 &&
+ "The only scale supported by ICmpZero uses is -1!");
+ ICmpScaledV = Rewriter.expandCodeFor(ScaledS, 0, IP);
+ } else {
+ // Otherwise just expand the scaled register and an explicit scale,
+ // which is expected to be matched as part of the address.
+ ScaledS = SE.getUnknown(Rewriter.expandCodeFor(ScaledS, 0, IP));
+ ScaledS = SE.getMulExpr(ScaledS,
+ SE.getIntegerSCEV(F.AM.Scale,
+ ScaledS->getType()));
+ Ops.push_back(ScaledS);
+ }
+ }
- ++NumCountZero;
+ // Expand the immediate portions.
+ if (F.AM.BaseGV)
+ Ops.push_back(SE.getSCEV(F.AM.BaseGV));
+ int64_t Offset = (uint64_t)F.AM.BaseOffs + LF.Offset;
+ if (Offset != 0) {
+ if (LU.Kind == LSRUse::ICmpZero) {
+ // The other interesting way of "folding" with an ICmpZero is to use a
+ // negated immediate.
+ if (!ICmpScaledV)
+ ICmpScaledV = ConstantInt::get(IntTy, -Offset);
+ else {
+ Ops.push_back(SE.getUnknown(ICmpScaledV));
+ ICmpScaledV = ConstantInt::get(IntTy, Offset);
+ }
+ } else {
+ // Just add the immediate values. These again are expected to be matched
+ // as part of the address.
+ Ops.push_back(SE.getIntegerSCEV(Offset, IntTy));
+ }
+ }
- return true;
+ // Emit instructions summing all the operands.
+ const SCEV *FullS = Ops.empty() ?
+ SE.getIntegerSCEV(0, IntTy) :
+ SE.getAddExpr(Ops);
+ Value *FullV = Rewriter.expandCodeFor(FullS, Ty, IP);
+
+ // We're done expanding now, so reset the rewriter.
+ Rewriter.setPostInc(0);
+
+ // An ICmpZero Formula represents an ICmp which we're handling as a
+ // comparison against zero. Now that we've expanded an expression for that
+ // form, update the ICmp's other operand.
+ if (LU.Kind == LSRUse::ICmpZero) {
+ ICmpInst *CI = cast<ICmpInst>(LF.UserInst);
+ DeadInsts.push_back(CI->getOperand(1));
+ assert(!F.AM.BaseGV && "ICmp does not support folding a global value and "
+ "a scale at the same time!");
+ if (F.AM.Scale == -1) {
+ if (ICmpScaledV->getType() != OpTy) {
+ Instruction *Cast =
+ CastInst::Create(CastInst::getCastOpcode(ICmpScaledV, false,
+ OpTy, false),
+ ICmpScaledV, OpTy, "tmp", CI);
+ ICmpScaledV = Cast;
+ }
+ CI->setOperand(1, ICmpScaledV);
+ } else {
+ assert(F.AM.Scale == 0 &&
+ "ICmp does not support folding a global value and "
+ "a scale at the same time!");
+ Constant *C = ConstantInt::getSigned(SE.getEffectiveSCEVType(OpTy),
+ -(uint64_t)Offset);
+ if (C->getType() != OpTy)
+ C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
+ OpTy, false),
+ C, OpTy);
+
+ CI->setOperand(1, C);
+ }
+ }
+
+ return FullV;
}
-/// OptimizeLoopCountIV - If, after all sharing of IVs, the IV used for deciding
-/// when to exit the loop is used only for that purpose, try to rearrange things
-/// so it counts down to a test against zero.
-bool LoopStrengthReduce::OptimizeLoopCountIV(Loop *L) {
- bool ThisChanged = false;
- for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
- const SCEV *Stride = IU->StrideOrder[i];
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SI =
- IU->IVUsesByStride.find(Stride);
- assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
- // FIXME: Generalize to non-affine IV's.
- if (!SI->first->isLoopInvariant(L))
- continue;
- // If stride is a constant and it has an icmpinst use, check if we can
- // optimize the loop to count down.
- if (isa<SCEVConstant>(Stride) && SI->second->Users.size() == 1) {
- Instruction *User = SI->second->Users.begin()->getUser();
- if (!isa<ICmpInst>(User))
- continue;
- const SCEV *CondStride = Stride;
- IVStrideUse *Use = &*SI->second->Users.begin();
- if (!OptimizeLoopCountIVOfStride(CondStride, Use, L))
- continue;
- ThisChanged = true;
+/// Rewrite - Emit instructions for the leading candidate expression for this
+/// LSRUse (this is called "expanding"), and update the UserInst to reference
+/// the newly expanded value.
+void LSRInstance::Rewrite(const LSRFixup &LF,
+ const Formula &F,
+ Loop *L, Instruction *IVIncInsertPos,
+ SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakVH> &DeadInsts,
+ ScalarEvolution &SE, DominatorTree &DT,
+ Pass *P) const {
+ const Type *OpTy = LF.OperandValToReplace->getType();
+
+ // First, find an insertion point that dominates UserInst. For PHI nodes,
+ // find the nearest block which dominates all the relevant uses.
+ if (PHINode *PN = dyn_cast<PHINode>(LF.UserInst)) {
+ DenseMap<BasicBlock *, Value *> Inserted;
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (PN->getIncomingValue(i) == LF.OperandValToReplace) {
+ BasicBlock *BB = PN->getIncomingBlock(i);
- // Now check if it's possible to reuse this iv for other stride uses.
- for (unsigned j = 0, ee = IU->StrideOrder.size(); j != ee; ++j) {
- const SCEV *SStride = IU->StrideOrder[j];
- if (SStride == CondStride)
- continue;
- std::map<const SCEV *, IVUsersOfOneStride *>::iterator SII =
- IU->IVUsesByStride.find(SStride);
- assert(SII != IU->IVUsesByStride.end() && "Stride doesn't exist!");
- // FIXME: Generalize to non-affine IV's.
- if (!SII->first->isLoopInvariant(L))
- continue;
- // FIXME: Rewrite other stride using CondStride.
+ // If this is a critical edge, split the edge so that we do not insert
+ // the code on all predecessor/successor paths. We do this unless this
+ // is the canonical backedge for this loop, which complicates post-inc
+ // users.
+ if (e != 1 && BB->getTerminator()->getNumSuccessors() > 1 &&
+ !isa<IndirectBrInst>(BB->getTerminator()) &&
+ (PN->getParent() != L->getHeader() || !L->contains(BB))) {
+ // Split the critical edge.
+ BasicBlock *NewBB = SplitCriticalEdge(BB, PN->getParent(), P);
+
+ // If PN is outside of the loop and BB is in the loop, we want to
+ // move the block to be immediately before the PHI block, not
+ // immediately after BB.
+ if (L->contains(BB) && !L->contains(PN))
+ NewBB->moveBefore(PN->getParent());
+
+ // Splitting the edge can reduce the number of PHI entries we have.
+ e = PN->getNumIncomingValues();
+ BB = NewBB;
+ i = PN->getBasicBlockIndex(BB);
+ }
+
+ std::pair<DenseMap<BasicBlock *, Value *>::iterator, bool> Pair =
+ Inserted.insert(std::make_pair(BB, static_cast<Value *>(0)));
+ if (!Pair.second)
+ PN->setIncomingValue(i, Pair.first->second);
+ else {
+ Value *FullV = Expand(LF, F, BB->getTerminator(), L, IVIncInsertPos,
+ Rewriter, DeadInsts, SE, DT);
+
+ // If this is reuse-by-noop-cast, insert the noop cast.
+ if (FullV->getType() != OpTy)
+ FullV =
+ CastInst::Create(CastInst::getCastOpcode(FullV, false,
+ OpTy, false),
+ FullV, LF.OperandValToReplace->getType(),
+ "tmp", BB->getTerminator());
+
+ PN->setIncomingValue(i, FullV);
+ Pair.first->second = FullV;
+ }
}
+ } else {
+ Value *FullV = Expand(LF, F, LF.UserInst, L, IVIncInsertPos,
+ Rewriter, DeadInsts, SE, DT);
+
+ // If this is reuse-by-noop-cast, insert the noop cast.
+ if (FullV->getType() != OpTy) {
+ Instruction *Cast =
+ CastInst::Create(CastInst::getCastOpcode(FullV, false, OpTy, false),
+ FullV, OpTy, "tmp", LF.UserInst);
+ FullV = Cast;
}
+
+ // Update the user. ICmpZero is handled specially here (for now) because
+ // Expand may have updated one of the operands of the icmp already, and
+ // its new value may happen to be equal to LF.OperandValToReplace, in
+ // which case doing replaceUsesOfWith leads to replacing both operands
+ // with the same value. TODO: Reorganize this.
+ if (Uses[LF.LUIdx].Kind == LSRUse::ICmpZero)
+ LF.UserInst->setOperand(0, FullV);
+ else
+ LF.UserInst->replaceUsesOfWith(LF.OperandValToReplace, FullV);
}
- Changed |= ThisChanged;
- return ThisChanged;
+ DeadInsts.push_back(LF.OperandValToReplace);
}
-bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) {
- IU = &getAnalysis<IVUsers>();
- SE = &getAnalysis<ScalarEvolution>();
- Changed = false;
+void
+LSRInstance::ImplementSolution(const SmallVectorImpl<const Formula *> &Solution,
+ Pass *P) {
+ // Keep track of instructions we may have made dead, so that
+ // we can remove them after we are done working.
+ SmallVector<WeakVH, 16> DeadInsts;
+
+ SCEVExpander Rewriter(SE);
+ Rewriter.disableCanonicalMode();
+ Rewriter.setIVIncInsertPos(L, IVIncInsertPos);
- // If LoopSimplify form is not available, stay out of trouble.
- if (!L->getLoopPreheader() || !L->getLoopLatch())
- return false;
+ // Expand the new value definitions and update the users.
+ for (size_t i = 0, e = Fixups.size(); i != e; ++i) {
+ size_t LUIdx = Fixups[i].LUIdx;
+
+ Rewrite(Fixups[i], *Solution[LUIdx], L, IVIncInsertPos, Rewriter,
+ DeadInsts, SE, DT, P);
+
+ Changed = true;
+ }
- if (!IU->IVUsesByStride.empty()) {
- DEBUG(dbgs() << "\nLSR on \"" << L->getHeader()->getParent()->getName()
- << "\" ";
- L->print(dbgs()));
+ // Clean up after ourselves. This must be done before deleting any
+ // instructions.
+ Rewriter.clear();
- // Sort the StrideOrder so we process larger strides first.
- std::stable_sort(IU->StrideOrder.begin(), IU->StrideOrder.end(),
- StrideCompare(SE));
+ Changed |= DeleteTriviallyDeadInstructions(DeadInsts);
+}
- // Optimize induction variables. Some indvar uses can be transformed to use
- // strides that will be needed for other purposes. A common example of this
- // is the exit test for the loop, which can often be rewritten to use the
- // computation of some other indvar to decide when to terminate the loop.
- OptimizeIndvars(L);
+LSRInstance::LSRInstance(const TargetLowering *tli, Loop *l, Pass *P)
+ : IU(P->getAnalysis<IVUsers>()),
+ SE(P->getAnalysis<ScalarEvolution>()),
+ DT(P->getAnalysis<DominatorTree>()),
+ TLI(tli), L(l), Changed(false), IVIncInsertPos(0) {
- // Change loop terminating condition to use the postinc iv when possible
- // and optimize loop terminating compare. FIXME: Move this after
- // StrengthReduceIVUsersOfStride?
- OptimizeLoopTermCond(L);
+ // If LoopSimplify form is not available, stay out of trouble.
+ if (!L->isLoopSimplifyForm()) return;
+
+ // If there's no interesting work to be done, bail early.
+ if (IU.empty()) return;
+
+ DEBUG(dbgs() << "\nLSR on loop ";
+ WriteAsOperand(dbgs(), L->getHeader(), /*PrintType=*/false);
+ dbgs() << ":\n");
+
+ /// OptimizeShadowIV - If IV is used in a int-to-float cast
+ /// inside the loop then try to eliminate the cast opeation.
+ OptimizeShadowIV();
+
+ // Change loop terminating condition to use the postinc iv when possible.
+ Changed |= OptimizeLoopTermCond();
+
+ CollectInterestingTypesAndFactors();
+ CollectFixupsAndInitialFormulae();
+ CollectLoopInvariantFixupsAndFormulae();
+
+ DEBUG(dbgs() << "LSR found " << Uses.size() << " uses:\n";
+ print_uses(dbgs()));
+
+ // Now use the reuse data to generate a bunch of interesting ways
+ // to formulate the values needed for the uses.
+ GenerateAllReuseFormulae();
+
+ DEBUG(dbgs() << "\n"
+ "After generating reuse formulae:\n";
+ print_uses(dbgs()));
+
+ FilterOutUndesirableDedicatedRegisters();
+ NarrowSearchSpaceUsingHeuristics();
+
+ SmallVector<const Formula *, 8> Solution;
+ Solve(Solution);
+ assert(Solution.size() == Uses.size() && "Malformed solution!");
+
+ // Release memory that is no longer needed.
+ Factors.clear();
+ Types.clear();
+ RegUses.clear();
+
+#ifndef NDEBUG
+ // Formulae should be legal.
+ for (SmallVectorImpl<LSRUse>::const_iterator I = Uses.begin(),
+ E = Uses.end(); I != E; ++I) {
+ const LSRUse &LU = *I;
+ for (SmallVectorImpl<Formula>::const_iterator J = LU.Formulae.begin(),
+ JE = LU.Formulae.end(); J != JE; ++J)
+ assert(isLegalUse(J->AM, LU.MinOffset, LU.MaxOffset,
+ LU.Kind, LU.AccessTy, TLI) &&
+ "Illegal formula generated!");
+ };
+#endif
- // FIXME: We can shrink overlarge IV's here. e.g. if the code has
- // computation in i64 values and the target doesn't support i64, demote
- // the computation to 32-bit if safe.
+ // Now that we've decided what we want, make it so.
+ ImplementSolution(Solution, P);
+}
- // FIXME: Attempt to reuse values across multiple IV's. In particular, we
- // could have something like "for(i) { foo(i*8); bar(i*16) }", which should
- // be codegened as "for (j = 0;; j+=8) { foo(j); bar(j+j); }" on X86/PPC.
- // Need to be careful that IV's are all the same type. Only works for
- // intptr_t indvars.
+void LSRInstance::print_factors_and_types(raw_ostream &OS) const {
+ if (Factors.empty() && Types.empty()) return;
- // IVsByStride keeps IVs for one particular loop.
- assert(IVsByStride.empty() && "Stale entries in IVsByStride?");
+ OS << "LSR has identified the following interesting factors and types: ";
+ bool First = true;
- StrengthReduceIVUsers(L);
+ for (SmallSetVector<int64_t, 8>::const_iterator
+ I = Factors.begin(), E = Factors.end(); I != E; ++I) {
+ if (!First) OS << ", ";
+ First = false;
+ OS << '*' << *I;
+ }
- // After all sharing is done, see if we can adjust the loop to test against
- // zero instead of counting up to a maximum. This is usually faster.
- OptimizeLoopCountIV(L);
+ for (SmallSetVector<const Type *, 4>::const_iterator
+ I = Types.begin(), E = Types.end(); I != E; ++I) {
+ if (!First) OS << ", ";
+ First = false;
+ OS << '(' << **I << ')';
+ }
+ OS << '\n';
+}
- // We're done analyzing this loop; release all the state we built up for it.
- IVsByStride.clear();
+void LSRInstance::print_fixups(raw_ostream &OS) const {
+ OS << "LSR is examining the following fixup sites:\n";
+ for (SmallVectorImpl<LSRFixup>::const_iterator I = Fixups.begin(),
+ E = Fixups.end(); I != E; ++I) {
+ const LSRFixup &LF = *I;
+ dbgs() << " ";
+ LF.print(OS);
+ OS << '\n';
+ }
+}
- // Clean up after ourselves
- DeleteTriviallyDeadInstructions();
+void LSRInstance::print_uses(raw_ostream &OS) const {
+ OS << "LSR is examining the following uses:\n";
+ for (SmallVectorImpl<LSRUse>::const_iterator I = Uses.begin(),
+ E = Uses.end(); I != E; ++I) {
+ const LSRUse &LU = *I;
+ dbgs() << " ";
+ LU.print(OS);
+ OS << '\n';
+ for (SmallVectorImpl<Formula>::const_iterator J = LU.Formulae.begin(),
+ JE = LU.Formulae.end(); J != JE; ++J) {
+ OS << " ";
+ J->print(OS);
+ OS << '\n';
+ }
}
+}
+
+void LSRInstance::print(raw_ostream &OS) const {
+ print_factors_and_types(OS);
+ print_fixups(OS);
+ print_uses(OS);
+}
+
+void LSRInstance::dump() const {
+ print(errs()); errs() << '\n';
+}
+
+namespace {
+
+class LoopStrengthReduce : public LoopPass {
+ /// TLI - Keep a pointer of a TargetLowering to consult for determining
+ /// transformation profitability.
+ const TargetLowering *const TLI;
+
+public:
+ static char ID; // Pass ID, replacement for typeid
+ explicit LoopStrengthReduce(const TargetLowering *tli = 0);
+
+private:
+ bool runOnLoop(Loop *L, LPPassManager &LPM);
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+
+}
+
+char LoopStrengthReduce::ID = 0;
+static RegisterPass<LoopStrengthReduce>
+X("loop-reduce", "Loop Strength Reduction");
+
+Pass *llvm::createLoopStrengthReducePass(const TargetLowering *TLI) {
+ return new LoopStrengthReduce(TLI);
+}
+
+LoopStrengthReduce::LoopStrengthReduce(const TargetLowering *tli)
+ : LoopPass(&ID), TLI(tli) {}
+
+void LoopStrengthReduce::getAnalysisUsage(AnalysisUsage &AU) const {
+ // We split critical edges, so we change the CFG. However, we do update
+ // many analyses if they are around.
+ AU.addPreservedID(LoopSimplifyID);
+ AU.addPreserved<LoopInfo>();
+ AU.addPreserved("domfrontier");
+
+ AU.addRequiredID(LoopSimplifyID);
+ AU.addRequired<DominatorTree>();
+ AU.addPreserved<DominatorTree>();
+ AU.addRequired<ScalarEvolution>();
+ AU.addPreserved<ScalarEvolution>();
+ AU.addRequired<IVUsers>();
+ AU.addPreserved<IVUsers>();
+}
+
+bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager & /*LPM*/) {
+ bool Changed = false;
+
+ // Run the main LSR transformation.
+ Changed |= LSRInstance(TLI, L, this).getChanged();
// At this point, it is worth checking to see if any recurrence PHIs are also
// dead, so that we can remove them as well.
diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp
index ee8cb4f..a355ec3 100644
--- a/lib/Transforms/Scalar/LoopUnrollPass.cpp
+++ b/lib/Transforms/Scalar/LoopUnrollPass.cpp
@@ -76,11 +76,12 @@ static RegisterPass<LoopUnroll> X("loop-unroll", "Unroll loops");
Pass *llvm::createLoopUnrollPass() { return new LoopUnroll(); }
/// ApproximateLoopSize - Approximate the size of the loop.
-static unsigned ApproximateLoopSize(const Loop *L) {
+static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls) {
CodeMetrics Metrics;
for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
I != E; ++I)
Metrics.analyzeBasicBlock(*I);
+ NumCalls = Metrics.NumCalls;
return Metrics.NumInsts;
}
@@ -110,8 +111,13 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
// Enforce the threshold.
if (UnrollThreshold != NoThreshold) {
- unsigned LoopSize = ApproximateLoopSize(L);
+ unsigned NumCalls;
+ unsigned LoopSize = ApproximateLoopSize(L, NumCalls);
DEBUG(dbgs() << " Loop Size = " << LoopSize << "\n");
+ if (NumCalls != 0) {
+ DEBUG(dbgs() << " Not unrolling loop with function calls.\n");
+ return false;
+ }
uint64_t Size = (uint64_t)LoopSize*Count;
if (TripCount != 1 && Size > UnrollThreshold) {
DEBUG(dbgs() << " Too large to fully unroll with count: " << Count
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp
index 527a7b5..990e0c4 100644
--- a/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -169,6 +169,10 @@ Pass *llvm::createLoopUnswitchPass(bool Os) {
/// invariant in the loop, or has an invariant piece, return the invariant.
/// Otherwise, return null.
static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) {
+ // We can never unswitch on vector conditions.
+ if (isa<VectorType>(Cond->getType()))
+ return 0;
+
// Constants should be folded, not unswitched on!
if (isa<Constant>(Cond)) return 0;
@@ -401,7 +405,7 @@ bool LoopUnswitch::IsTrivialUnswitchCondition(Value *Cond, Constant **Val,
/// UnswitchIfProfitable - We have found that we can unswitch currentLoop when
/// LoopCond == Val to simplify the loop. If we decide that this is profitable,
/// unswitch the loop, reprocess the pieces, then return true.
-bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val){
+bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val) {
initLoopData();
@@ -867,7 +871,7 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
// If we know that LIC == Val, or that LIC == NotVal, just replace uses of LIC
// in the loop with the appropriate one directly.
if (IsEqual || (isa<ConstantInt>(Val) &&
- Val->getType()->isInteger(1))) {
+ Val->getType()->isIntegerTy(1))) {
Value *Replacement;
if (IsEqual)
Replacement = Val;
@@ -993,10 +997,10 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
case Instruction::And:
if (isa<ConstantInt>(I->getOperand(0)) &&
// constant -> RHS
- I->getOperand(0)->getType()->isInteger(1))
+ I->getOperand(0)->getType()->isIntegerTy(1))
cast<BinaryOperator>(I)->swapOperands();
if (ConstantInt *CB = dyn_cast<ConstantInt>(I->getOperand(1)))
- if (CB->getType()->isInteger(1)) {
+ if (CB->getType()->isIntegerTy(1)) {
if (CB->isOne()) // X & 1 -> X
ReplaceUsesOfWith(I, I->getOperand(0), Worklist, L, LPM);
else // X & 0 -> 0
@@ -1007,10 +1011,10 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
case Instruction::Or:
if (isa<ConstantInt>(I->getOperand(0)) &&
// constant -> RHS
- I->getOperand(0)->getType()->isInteger(1))
+ I->getOperand(0)->getType()->isIntegerTy(1))
cast<BinaryOperator>(I)->swapOperands();
if (ConstantInt *CB = dyn_cast<ConstantInt>(I->getOperand(1)))
- if (CB->getType()->isInteger(1)) {
+ if (CB->getType()->isIntegerTy(1)) {
if (CB->isOne()) // X | 1 -> 1
ReplaceUsesOfWith(I, I->getOperand(1), Worklist, L, LPM);
else // X | 0 -> X
diff --git a/lib/Transforms/Scalar/Makefile b/lib/Transforms/Scalar/Makefile
index e18f30f..cc42fd0 100644
--- a/lib/Transforms/Scalar/Makefile
+++ b/lib/Transforms/Scalar/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMScalarOpts
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index e0aa491..62e2977 100644
--- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -42,7 +42,7 @@ static Value *isBytewiseValue(Value *V) {
LLVMContext &Context = V->getContext();
// All byte-wide stores are splatable, even of arbitrary variables.
- if (V->getType()->isInteger(8)) return V;
+ if (V->getType()->isIntegerTy(8)) return V;
// Constant float and double values can be handled as integer values if the
// corresponding integer value is "byteable". An important case is 0.0.
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp
index 4a99f4a..187216a 100644
--- a/lib/Transforms/Scalar/Reassociate.cpp
+++ b/lib/Transforms/Scalar/Reassociate.cpp
@@ -182,7 +182,7 @@ unsigned Reassociate::getRank(Value *V) {
// If this is a not or neg instruction, do not count it for rank. This
// assures us that X and ~X will have the same rank.
- if (!I->getType()->isInteger() ||
+ if (!I->getType()->isIntegerTy() ||
(!BinaryOperator::isNot(I) && !BinaryOperator::isNeg(I)))
++Rank;
@@ -249,7 +249,7 @@ void Reassociate::LinearizeExpr(BinaryOperator *I) {
/// LinearizeExprTree - Given an associative binary expression tree, traverse
/// all of the uses putting it into canonical form. This forces a left-linear
-/// form of the the expression (((a+b)+c)+d), and collects information about the
+/// form of the expression (((a+b)+c)+d), and collects information about the
/// rank of the non-tree operands.
///
/// NOTE: These intentionally destroys the expression tree operands (turning
@@ -299,7 +299,7 @@ void Reassociate::LinearizeExprTree(BinaryOperator *I,
Success = false;
MadeChange = true;
} else if (RHSBO) {
- // Turn (A+B)+(C+D) -> (((A+B)+C)+D). This guarantees the the RHS is not
+ // Turn (A+B)+(C+D) -> (((A+B)+C)+D). This guarantees the RHS is not
// part of the expression tree.
LinearizeExpr(I);
LHS = LHSBO = cast<BinaryOperator>(I->getOperand(0));
@@ -929,10 +929,19 @@ void Reassociate::ReassociateBB(BasicBlock *BB) {
}
// Reject cases where it is pointless to do this.
- if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPoint() ||
+ if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPointTy() ||
isa<VectorType>(BI->getType()))
continue; // Floating point ops are not associative.
+ // Do not reassociate boolean (i1) expressions. We want to preserve the
+ // original order of evaluation for short-circuited comparisons that
+ // SimplifyCFG has folded to AND/OR expressions. If the expression
+ // is not further optimized, it is likely to be transformed back to a
+ // short-circuited form for code gen, and the source order may have been
+ // optimized for the most likely conditions.
+ if (BI->getType()->isIntegerTy(1))
+ continue;
+
// If this is a subtract instruction which is not already in negate form,
// see if we can convert it to X+-Y.
if (BI->getOpcode() == Instruction::Sub) {
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index f473480..822712e 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -202,12 +202,18 @@ bool SROA::performPromotion(Function &F) {
return Changed;
}
-/// getNumSAElements - Return the number of elements in the specific struct or
-/// array.
-static uint64_t getNumSAElements(const Type *T) {
+/// ShouldAttemptScalarRepl - Decide if an alloca is a good candidate for
+/// SROA. It must be a struct or array type with a small number of elements.
+static bool ShouldAttemptScalarRepl(AllocaInst *AI) {
+ const Type *T = AI->getAllocatedType();
+ // Do not promote any struct into more than 32 separate vars.
if (const StructType *ST = dyn_cast<StructType>(T))
- return ST->getNumElements();
- return cast<ArrayType>(T)->getNumElements();
+ return ST->getNumElements() <= 32;
+ // Arrays are much less likely to be safe for SROA; only consider
+ // them if they are very small.
+ if (const ArrayType *AT = dyn_cast<ArrayType>(T))
+ return AT->getNumElements() <= 8;
+ return false;
}
// performScalarRepl - This algorithm is a simple worklist driven algorithm,
@@ -266,22 +272,18 @@ bool SROA::performScalarRepl(Function &F) {
// Do not promote [0 x %struct].
if (AllocaSize == 0) continue;
+ // If the alloca looks like a good candidate for scalar replacement, and if
+ // all its users can be transformed, then split up the aggregate into its
+ // separate elements.
+ if (ShouldAttemptScalarRepl(AI) && isSafeAllocaToScalarRepl(AI)) {
+ DoScalarReplacement(AI, WorkList);
+ Changed = true;
+ continue;
+ }
+
// Do not promote any struct whose size is too big.
if (AllocaSize > SRThreshold) continue;
- if ((isa<StructType>(AI->getAllocatedType()) ||
- isa<ArrayType>(AI->getAllocatedType())) &&
- // Do not promote any struct into more than "32" separate vars.
- getNumSAElements(AI->getAllocatedType()) <= SRThreshold/4) {
- // Check that all of the users of the allocation are capable of being
- // transformed.
- if (isSafeAllocaToScalarRepl(AI)) {
- DoScalarReplacement(AI, WorkList);
- Changed = true;
- continue;
- }
- }
-
// If we can turn this aggregate value (potentially with casts) into a
// simple scalar value that can be mem2reg'd into a register value.
// IsNotTrivial tracks whether this is something that mem2reg could have
@@ -681,7 +683,7 @@ void SROA::RewriteGEP(GetElementPtrInst *GEPI, AllocaInst *AI, uint64_t Offset,
Val->takeName(GEPI);
}
if (Val->getType() != GEPI->getType())
- Val = new BitCastInst(Val, GEPI->getType(), Val->getNameStr(), GEPI);
+ Val = new BitCastInst(Val, GEPI->getType(), Val->getName(), GEPI);
GEPI->replaceAllUsesWith(Val);
DeadInsts.push_back(GEPI);
}
@@ -769,7 +771,7 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
Value *Idx[2] = { Zero,
ConstantInt::get(Type::getInt32Ty(MI->getContext()), i) };
OtherElt = GetElementPtrInst::CreateInBounds(OtherPtr, Idx, Idx + 2,
- OtherPtr->getNameStr()+"."+Twine(i),
+ OtherPtr->getName()+"."+Twine(i),
MI);
uint64_t EltOffset;
const PointerType *OtherPtrTy = cast<PointerType>(OtherPtr->getType());
@@ -833,7 +835,7 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
StoreVal = ConstantInt::get(Context, TotalVal);
if (isa<PointerType>(ValTy))
StoreVal = ConstantExpr::getIntToPtr(StoreVal, ValTy);
- else if (ValTy->isFloatingPoint())
+ else if (ValTy->isFloatingPointTy())
StoreVal = ConstantExpr::getBitCast(StoreVal, ValTy);
assert(StoreVal->getType() == ValTy && "Type mismatch!");
@@ -853,12 +855,11 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
// Cast the element pointer to BytePtrTy.
if (EltPtr->getType() != BytePtrTy)
- EltPtr = new BitCastInst(EltPtr, BytePtrTy, EltPtr->getNameStr(), MI);
+ EltPtr = new BitCastInst(EltPtr, BytePtrTy, EltPtr->getName(), MI);
// Cast the other pointer (if we have one) to BytePtrTy.
if (OtherElt && OtherElt->getType() != BytePtrTy)
- OtherElt = new BitCastInst(OtherElt, BytePtrTy,OtherElt->getNameStr(),
- MI);
+ OtherElt = new BitCastInst(OtherElt, BytePtrTy, OtherElt->getName(), MI);
unsigned EltSize = TD->getTypeAllocSize(EltTy);
@@ -938,7 +939,7 @@ void SROA::RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocaInst *AI,
Value *DestField = NewElts[i];
if (EltVal->getType() == FieldTy) {
// Storing to an integer field of this size, just do it.
- } else if (FieldTy->isFloatingPoint() || isa<VectorType>(FieldTy)) {
+ } else if (FieldTy->isFloatingPointTy() || isa<VectorType>(FieldTy)) {
// Bitcast to the right element type (for fp/vector values).
EltVal = new BitCastInst(EltVal, FieldTy, "", SI);
} else {
@@ -982,7 +983,8 @@ void SROA::RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocaInst *AI,
Value *DestField = NewElts[i];
if (EltVal->getType() == ArrayEltTy) {
// Storing to an integer field of this size, just do it.
- } else if (ArrayEltTy->isFloatingPoint() || isa<VectorType>(ArrayEltTy)) {
+ } else if (ArrayEltTy->isFloatingPointTy() ||
+ isa<VectorType>(ArrayEltTy)) {
// Bitcast to the right element type (for fp/vector values).
EltVal = new BitCastInst(EltVal, ArrayEltTy, "", SI);
} else {
@@ -1042,7 +1044,7 @@ void SROA::RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocaInst *AI,
const IntegerType *FieldIntTy = IntegerType::get(LI->getContext(),
FieldSizeBits);
- if (!isa<IntegerType>(FieldTy) && !FieldTy->isFloatingPoint() &&
+ if (!isa<IntegerType>(FieldTy) && !FieldTy->isFloatingPointTy() &&
!isa<VectorType>(FieldTy))
SrcField = new BitCastInst(SrcField,
PointerType::getUnqual(FieldIntTy),
@@ -1384,9 +1386,9 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) {
// If the source and destination are both to the same alloca, then this is
// a noop copy-to-self, just delete it. Otherwise, emit a load and store
// as appropriate.
- AllocaInst *OrigAI = cast<AllocaInst>(Ptr->getUnderlyingObject());
+ AllocaInst *OrigAI = cast<AllocaInst>(Ptr->getUnderlyingObject(0));
- if (MTI->getSource()->getUnderlyingObject() != OrigAI) {
+ if (MTI->getSource()->getUnderlyingObject(0) != OrigAI) {
// Dest must be OrigAI, change this to be a load from the original
// pointer (bitcasted), then a store to our new alloca.
assert(MTI->getRawDest() == Ptr && "Neither use is of pointer?");
@@ -1396,7 +1398,7 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) {
LoadInst *SrcVal = Builder.CreateLoad(SrcPtr, "srcval");
SrcVal->setAlignment(MTI->getAlignment());
Builder.CreateStore(SrcVal, NewAI);
- } else if (MTI->getDest()->getUnderlyingObject() != OrigAI) {
+ } else if (MTI->getDest()->getUnderlyingObject(0) != OrigAI) {
// Src must be OrigAI, change this to be a load from NewAI then a store
// through the original dest pointer (bitcasted).
assert(MTI->getRawSource() == Ptr && "Neither use is of pointer?");
@@ -1521,7 +1523,7 @@ Value *SROA::ConvertScalar_ExtractValue(Value *FromVal, const Type *ToType,
// If the result is an integer, this is a trunc or bitcast.
if (isa<IntegerType>(ToType)) {
// Should be done.
- } else if (ToType->isFloatingPoint() || isa<VectorType>(ToType)) {
+ } else if (ToType->isFloatingPointTy() || isa<VectorType>(ToType)) {
// Just do a bitcast, we know the sizes match up.
FromVal = Builder.CreateBitCast(FromVal, ToType, "tmp");
} else {
@@ -1599,7 +1601,7 @@ Value *SROA::ConvertScalar_InsertValue(Value *SV, Value *Old,
unsigned DestWidth = TD->getTypeSizeInBits(AllocaType);
unsigned SrcStoreWidth = TD->getTypeStoreSizeInBits(SV->getType());
unsigned DestStoreWidth = TD->getTypeStoreSizeInBits(AllocaType);
- if (SV->getType()->isFloatingPoint() || isa<VectorType>(SV->getType()))
+ if (SV->getType()->isFloatingPointTy() || isa<VectorType>(SV->getType()))
SV = Builder.CreateBitCast(SV,
IntegerType::get(SV->getContext(),SrcWidth), "tmp");
else if (isa<PointerType>(SV->getType()))
diff --git a/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/lib/Transforms/Scalar/SimplifyCFGPass.cpp
index 43447de..62f34a2 100644
--- a/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -30,6 +30,7 @@
#include "llvm/Attributes.h"
#include "llvm/Support/CFG.h"
#include "llvm/Pass.h"
+#include "llvm/Target/TargetData.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
@@ -261,7 +262,7 @@ static bool MergeEmptyReturnBlocks(Function &F) {
/// IterativeSimplifyCFG - Call SimplifyCFG on all the blocks in the function,
/// iterating until no more changes are made.
-static bool IterativeSimplifyCFG(Function &F) {
+static bool IterativeSimplifyCFG(Function &F, const TargetData *TD) {
bool Changed = false;
bool LocalChange = true;
while (LocalChange) {
@@ -271,7 +272,7 @@ static bool IterativeSimplifyCFG(Function &F) {
// if they are unneeded...
//
for (Function::iterator BBIt = ++F.begin(); BBIt != F.end(); ) {
- if (SimplifyCFG(BBIt++)) {
+ if (SimplifyCFG(BBIt++, TD)) {
LocalChange = true;
++NumSimpl;
}
@@ -285,10 +286,11 @@ static bool IterativeSimplifyCFG(Function &F) {
// simplify the CFG.
//
bool CFGSimplifyPass::runOnFunction(Function &F) {
+ const TargetData *TD = getAnalysisIfAvailable<TargetData>();
bool EverChanged = RemoveUnreachableBlocksFromFn(F);
EverChanged |= MergeEmptyReturnBlocks(F);
- EverChanged |= IterativeSimplifyCFG(F);
-
+ EverChanged |= IterativeSimplifyCFG(F, TD);
+
// If neither pass changed anything, we're done.
if (!EverChanged) return false;
@@ -299,11 +301,11 @@ bool CFGSimplifyPass::runOnFunction(Function &F) {
// RemoveUnreachableBlocksFromFn doesn't do anything.
if (!RemoveUnreachableBlocksFromFn(F))
return true;
-
+
do {
- EverChanged = IterativeSimplifyCFG(F);
+ EverChanged = IterativeSimplifyCFG(F, TD);
EverChanged |= RemoveUnreachableBlocksFromFn(F);
} while (EverChanged);
-
+
return true;
}
diff --git a/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp b/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp
index 5acd6aa..4464961 100644
--- a/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp
+++ b/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp
@@ -68,7 +68,7 @@ InlineHalfPowrs(const std::vector<Instruction *> &HalfPowrs,
Function *Callee = Call->getCalledFunction();
// Minimally sanity-check the CFG of half_powr to ensure that it contains
- // the the kind of code we expect. If we're running this pass, we have
+ // the kind of code we expect. If we're running this pass, we have
// reason to believe it will be what we expect.
Function::iterator I = Callee->begin();
BasicBlock *Prologue = I++;
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
index a49da9c..54b4380 100644
--- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp
+++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
@@ -152,7 +152,7 @@ Value *LibCallOptimization::EmitStrLen(Value *Ptr, IRBuilder<> &B) {
Constant *StrLen =M->getOrInsertFunction("strlen", AttrListPtr::get(AWI, 2),
TD->getIntPtrType(*Context),
- Type::getInt8PtrTy(*Context),
+ Type::getInt8PtrTy(*Context),
NULL);
CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
@@ -232,10 +232,10 @@ Value *LibCallOptimization::EmitMemChr(Value *Ptr, Value *Val,
AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(&AWI, 1),
- Type::getInt8PtrTy(*Context),
- Type::getInt8PtrTy(*Context),
+ Type::getInt8PtrTy(*Context),
+ Type::getInt8PtrTy(*Context),
Type::getInt32Ty(*Context),
- TD->getIntPtrType(*Context),
+ TD->getIntPtrType(*Context),
NULL);
CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
@@ -321,9 +321,9 @@ Value *LibCallOptimization::EmitPutChar(Value *Char, IRBuilder<> &B) {
Type::getInt32Ty(*Context), NULL);
CallInst *CI = B.CreateCall(PutChar,
B.CreateIntCast(Char,
- Type::getInt32Ty(*Context),
- /*isSigned*/true,
- "chari"),
+ Type::getInt32Ty(*Context),
+ /*isSigned*/true,
+ "chari"),
"putchar");
if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
@@ -341,7 +341,7 @@ void LibCallOptimization::EmitPutS(Value *Str, IRBuilder<> &B) {
Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI, 2),
Type::getInt32Ty(*Context),
- Type::getInt8PtrTy(*Context),
+ Type::getInt8PtrTy(*Context),
NULL);
CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
@@ -359,13 +359,13 @@ void LibCallOptimization::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B) {
Constant *F;
if (isa<PointerType>(File->getType()))
F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2),
- Type::getInt32Ty(*Context),
+ Type::getInt32Ty(*Context),
Type::getInt32Ty(*Context), File->getType(),
- NULL);
+ NULL);
else
F = M->getOrInsertFunction("fputc",
- Type::getInt32Ty(*Context),
- Type::getInt32Ty(*Context),
+ Type::getInt32Ty(*Context),
+ Type::getInt32Ty(*Context),
File->getType(), NULL);
Char = B.CreateIntCast(Char, Type::getInt32Ty(*Context), /*isSigned*/true,
"chari");
@@ -386,7 +386,7 @@ void LibCallOptimization::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B) {
Constant *F;
if (isa<PointerType>(File->getType()))
F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 3),
- Type::getInt32Ty(*Context),
+ Type::getInt32Ty(*Context),
Type::getInt8PtrTy(*Context),
File->getType(), NULL);
else
@@ -414,13 +414,13 @@ void LibCallOptimization::EmitFWrite(Value *Ptr, Value *Size, Value *File,
TD->getIntPtrType(*Context),
Type::getInt8PtrTy(*Context),
TD->getIntPtrType(*Context),
- TD->getIntPtrType(*Context),
+ TD->getIntPtrType(*Context),
File->getType(), NULL);
else
F = M->getOrInsertFunction("fwrite", TD->getIntPtrType(*Context),
Type::getInt8PtrTy(*Context),
TD->getIntPtrType(*Context),
- TD->getIntPtrType(*Context),
+ TD->getIntPtrType(*Context),
File->getType(), NULL);
CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
ConstantInt::get(TD->getIntPtrType(*Context), 1), File);
@@ -525,7 +525,7 @@ static uint64_t GetStringLengthH(Value *V, SmallPtrSet<PHINode*, 32> &PHIs) {
// Must be a Constant Array
ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
- if (!Array || !Array->getType()->getElementType()->isInteger(8))
+ if (!Array || !Array->getType()->getElementType()->isIntegerTy(8))
return false;
// Get the number of elements in the array
@@ -697,7 +697,7 @@ struct StrChrOpt : public LibCallOptimization {
if (!TD) return 0;
uint64_t Len = GetStringLength(SrcStr);
- if (Len == 0 || !FT->getParamType(1)->isInteger(32)) // memchr needs i32.
+ if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32.
return 0;
return EmitMemChr(SrcStr, CI->getOperand(2), // include nul.
@@ -739,7 +739,7 @@ struct StrCmpOpt : public LibCallOptimization {
// Verify the "strcmp" function prototype.
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 2 ||
- !FT->getReturnType()->isInteger(32) ||
+ !FT->getReturnType()->isIntegerTy(32) ||
FT->getParamType(0) != FT->getParamType(1) ||
FT->getParamType(0) != Type::getInt8PtrTy(*Context))
return 0;
@@ -787,7 +787,7 @@ struct StrNCmpOpt : public LibCallOptimization {
// Verify the "strncmp" function prototype.
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 3 ||
- !FT->getReturnType()->isInteger(32) ||
+ !FT->getReturnType()->isIntegerTy(32) ||
FT->getParamType(0) != FT->getParamType(1) ||
FT->getParamType(0) != Type::getInt8PtrTy(*Context) ||
!isa<IntegerType>(FT->getParamType(2)))
@@ -1008,7 +1008,7 @@ struct MemCmpOpt : public LibCallOptimization {
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 3 || !isa<PointerType>(FT->getParamType(0)) ||
!isa<PointerType>(FT->getParamType(1)) ||
- !FT->getReturnType()->isInteger(32))
+ !FT->getReturnType()->isIntegerTy(32))
return 0;
Value *LHS = CI->getOperand(1), *RHS = CI->getOperand(2);
@@ -1203,22 +1203,23 @@ struct MemMoveChkOpt : public LibCallOptimization {
struct StrCpyChkOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
- // These optimizations require TargetData.
- if (!TD) return 0;
-
const FunctionType *FT = Callee->getFunctionType();
if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
!isa<PointerType>(FT->getParamType(0)) ||
- !isa<PointerType>(FT->getParamType(1)) ||
- !isa<IntegerType>(FT->getParamType(2)))
+ !isa<PointerType>(FT->getParamType(1)))
return 0;
ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3));
if (!SizeCI)
return 0;
- // We don't have any length information, just lower to a plain strcpy.
- if (SizeCI->isAllOnesValue())
+ // If a) we don't have any length information, or b) we know this will
+ // fit then just lower to a plain strcpy. Otherwise we'll keep our
+ // strcpy_chk call which may fail at runtime if the size is too long.
+ // TODO: It might be nice to get a maximum length out of the possible
+ // string lengths for varying.
+ if (SizeCI->isAllOnesValue() ||
+ SizeCI->getZExtValue() >= GetStringLength(CI->getOperand(2)))
return EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B);
return 0;
@@ -1240,7 +1241,7 @@ struct PowOpt : public LibCallOptimization {
// result type.
if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
FT->getParamType(0) != FT->getParamType(1) ||
- !FT->getParamType(0)->isFloatingPoint())
+ !FT->getParamType(0)->isFloatingPointTy())
return 0;
Value *Op1 = CI->getOperand(1), *Op2 = CI->getOperand(2);
@@ -1294,7 +1295,7 @@ struct Exp2Opt : public LibCallOptimization {
// Just make sure this has 1 argument of FP type, which matches the
// result type.
if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
- !FT->getParamType(0)->isFloatingPoint())
+ !FT->getParamType(0)->isFloatingPointTy())
return 0;
Value *Op = CI->getOperand(1);
@@ -1327,7 +1328,7 @@ struct Exp2Opt : public LibCallOptimization {
Module *M = Caller->getParent();
Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
Op->getType(),
- Type::getInt32Ty(*Context),NULL);
+ Type::getInt32Ty(*Context),NULL);
CallInst *CI = B.CreateCall2(Callee, One, LdExpArg);
if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
CI->setCallingConv(F->getCallingConv());
@@ -1374,7 +1375,7 @@ struct FFSOpt : public LibCallOptimization {
// Just make sure this has 2 arguments of the same FP type, which match the
// result type.
if (FT->getNumParams() != 1 ||
- !FT->getReturnType()->isInteger(32) ||
+ !FT->getReturnType()->isIntegerTy(32) ||
!isa<IntegerType>(FT->getParamType(0)))
return 0;
@@ -1410,7 +1411,7 @@ struct IsDigitOpt : public LibCallOptimization {
const FunctionType *FT = Callee->getFunctionType();
// We require integer(i32)
if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
- !FT->getParamType(0)->isInteger(32))
+ !FT->getParamType(0)->isIntegerTy(32))
return 0;
// isdigit(c) -> (c-'0') <u 10
@@ -1431,7 +1432,7 @@ struct IsAsciiOpt : public LibCallOptimization {
const FunctionType *FT = Callee->getFunctionType();
// We require integer(i32)
if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
- !FT->getParamType(0)->isInteger(32))
+ !FT->getParamType(0)->isIntegerTy(32))
return 0;
// isascii(c) -> c <u 128
@@ -1472,7 +1473,7 @@ struct ToAsciiOpt : public LibCallOptimization {
const FunctionType *FT = Callee->getFunctionType();
// We require i32(i32)
if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
- !FT->getParamType(0)->isInteger(32))
+ !FT->getParamType(0)->isIntegerTy(32))
return 0;
// isascii(c) -> c & 0x7f
diff --git a/lib/Transforms/Scalar/TailRecursionElimination.cpp b/lib/Transforms/Scalar/TailRecursionElimination.cpp
index 4119cb9..162d902 100644
--- a/lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -211,7 +211,8 @@ bool TailCallElim::CanMoveAboveCall(Instruction *I, CallInst *CI) {
// FIXME: Writes to memory only matter if they may alias the pointer
// being loaded from.
if (CI->mayWriteToMemory() ||
- !isSafeToLoadUnconditionally(L->getPointerOperand(), L))
+ !isSafeToLoadUnconditionally(L->getPointerOperand(), L,
+ L->getAlignment()))
return false;
}
}
diff --git a/lib/Transforms/Utils/BreakCriticalEdges.cpp b/lib/Transforms/Utils/BreakCriticalEdges.cpp
index 19c7206..3657390 100644
--- a/lib/Transforms/Utils/BreakCriticalEdges.cpp
+++ b/lib/Transforms/Utils/BreakCriticalEdges.cpp
@@ -179,7 +179,7 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
// Create a new basic block, linking it into the CFG.
BasicBlock *NewBB = BasicBlock::Create(TI->getContext(),
TIBB->getName() + "." + DestBB->getName() + "_crit_edge");
- // Create our unconditional branch...
+ // Create our unconditional branch.
BranchInst::Create(DestBB, NewBB);
// Branch to the new block, breaking the edge.
@@ -192,16 +192,47 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
// If there are any PHI nodes in DestBB, we need to update them so that they
// merge incoming values from NewBB instead of from TIBB.
- //
- for (BasicBlock::iterator I = DestBB->begin(); isa<PHINode>(I); ++I) {
- PHINode *PN = cast<PHINode>(I);
- // We no longer enter through TIBB, now we come in through NewBB. Revector
- // exactly one entry in the PHI node that used to come from TIBB to come
- // from NewBB.
- int BBIdx = PN->getBasicBlockIndex(TIBB);
- PN->setIncomingBlock(BBIdx, NewBB);
+ if (PHINode *APHI = dyn_cast<PHINode>(DestBB->begin())) {
+ // This conceptually does:
+ // foreach (PHINode *PN in DestBB)
+ // PN->setIncomingBlock(PN->getIncomingBlock(TIBB), NewBB);
+ // but is optimized for two cases.
+
+ if (APHI->getNumIncomingValues() <= 8) { // Small # preds case.
+ unsigned BBIdx = 0;
+ for (BasicBlock::iterator I = DestBB->begin(); isa<PHINode>(I); ++I) {
+ // We no longer enter through TIBB, now we come in through NewBB.
+ // Revector exactly one entry in the PHI node that used to come from
+ // TIBB to come from NewBB.
+ PHINode *PN = cast<PHINode>(I);
+
+ // Reuse the previous value of BBIdx if it lines up. In cases where we
+ // have multiple phi nodes with *lots* of predecessors, this is a speed
+ // win because we don't have to scan the PHI looking for TIBB. This
+ // happens because the BB list of PHI nodes are usually in the same
+ // order.
+ if (PN->getIncomingBlock(BBIdx) != TIBB)
+ BBIdx = PN->getBasicBlockIndex(TIBB);
+ PN->setIncomingBlock(BBIdx, NewBB);
+ }
+ } else {
+ // However, the foreach loop is slow for blocks with lots of predecessors
+ // because PHINode::getIncomingBlock is O(n) in # preds. Instead, walk
+ // the user list of TIBB to find the PHI nodes.
+ SmallPtrSet<PHINode*, 16> UpdatedPHIs;
+
+ for (Value::use_iterator UI = TIBB->use_begin(), E = TIBB->use_end();
+ UI != E; ) {
+ Value::use_iterator Use = UI++;
+ if (PHINode *PN = dyn_cast<PHINode>(Use)) {
+ // Remove one entry from each PHI.
+ if (PN->getParent() == DestBB && UpdatedPHIs.insert(PN))
+ PN->setOperand(Use.getOperandNo(), NewBB);
+ }
+ }
+ }
}
-
+
// If there are any other edges from TIBB to DestBB, update those to go
// through the split block, making those edges non-critical as well (and
// reducing the number of phi entries in the DestBB if relevant).
@@ -221,6 +252,15 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
// If we don't have a pass object, we can't update anything...
if (P == 0) return NewBB;
+
+ DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>();
+ DominanceFrontier *DF = P->getAnalysisIfAvailable<DominanceFrontier>();
+ LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>();
+ ProfileInfo *PI = P->getAnalysisIfAvailable<ProfileInfo>();
+
+ // If we have nothing to update, just return.
+ if (DT == 0 && DF == 0 && LI == 0 && PI == 0)
+ return NewBB;
// Now update analysis information. Since the only predecessor of NewBB is
// the TIBB, TIBB clearly dominates NewBB. TIBB usually doesn't dominate
@@ -229,14 +269,23 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
// loop header) then NewBB dominates DestBB.
SmallVector<BasicBlock*, 8> OtherPreds;
- for (pred_iterator I = pred_begin(DestBB), E = pred_end(DestBB); I != E; ++I)
- if (*I != NewBB)
- OtherPreds.push_back(*I);
+ // If there is a PHI in the block, loop over predecessors with it, which is
+ // faster than iterating pred_begin/end.
+ if (PHINode *PN = dyn_cast<PHINode>(DestBB->begin())) {
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (PN->getIncomingBlock(i) != NewBB)
+ OtherPreds.push_back(PN->getIncomingBlock(i));
+ } else {
+ for (pred_iterator I = pred_begin(DestBB), E = pred_end(DestBB);
+ I != E; ++I)
+ if (*I != NewBB)
+ OtherPreds.push_back(*I);
+ }
bool NewBBDominatesDestBB = true;
// Should we update DominatorTree information?
- if (DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>()) {
+ if (DT) {
DomTreeNode *TINode = DT->getNode(TIBB);
// The new block is not the immediate dominator for any other nodes, but
@@ -267,7 +316,7 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
}
// Should we update DominanceFrontier information?
- if (DominanceFrontier *DF = P->getAnalysisIfAvailable<DominanceFrontier>()) {
+ if (DF) {
// If NewBBDominatesDestBB hasn't been computed yet, do so with DF.
if (!OtherPreds.empty()) {
// FIXME: IMPLEMENT THIS!
@@ -301,7 +350,7 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
}
// Update LoopInfo if it is around.
- if (LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>()) {
+ if (LI) {
if (Loop *TIL = LI->getLoopFor(TIBB)) {
// If one or the other blocks were not in a loop, the new block is not
// either, and thus LI doesn't need to be updated.
@@ -382,9 +431,8 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
}
// Update ProfileInfo if it is around.
- if (ProfileInfo *PI = P->getAnalysisIfAvailable<ProfileInfo>()) {
- PI->splitEdge(TIBB,DestBB,NewBB,MergeIdenticalEdges);
- }
+ if (PI)
+ PI->splitEdge(TIBB, DestBB, NewBB, MergeIdenticalEdges);
return NewBB;
}
diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp
index bd750cc..c80827d 100644
--- a/lib/Transforms/Utils/CloneFunction.cpp
+++ b/lib/Transforms/Utils/CloneFunction.cpp
@@ -33,7 +33,7 @@ using namespace llvm;
// CloneBasicBlock - See comments in Cloning.h
BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB,
DenseMap<const Value*, Value*> &ValueMap,
- const char *NameSuffix, Function *F,
+ const Twine &NameSuffix, Function *F,
ClonedCodeInfo *CodeInfo) {
BasicBlock *NewBB = BasicBlock::Create(BB->getContext(), "", F);
if (BB->hasName()) NewBB->setName(BB->getName()+NameSuffix);
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index 92bdf2d..57ad459 100644
--- a/lib/Transforms/Utils/Local.cpp
+++ b/lib/Transforms/Utils/Local.cpp
@@ -38,20 +38,82 @@ using namespace llvm;
// Local analysis.
//
+/// getUnderlyingObjectWithOffset - Strip off up to MaxLookup GEPs and
+/// bitcasts to get back to the underlying object being addressed, keeping
+/// track of the offset in bytes from the GEPs relative to the result.
+/// This is closely related to Value::getUnderlyingObject but is located
+/// here to avoid making VMCore depend on TargetData.
+static Value *getUnderlyingObjectWithOffset(Value *V, const TargetData *TD,
+ uint64_t &ByteOffset,
+ unsigned MaxLookup = 6) {
+ if (!isa<PointerType>(V->getType()))
+ return V;
+ for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) {
+ if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
+ if (!GEP->hasAllConstantIndices())
+ return V;
+ SmallVector<Value*, 8> Indices(GEP->op_begin() + 1, GEP->op_end());
+ ByteOffset += TD->getIndexedOffset(GEP->getPointerOperandType(),
+ &Indices[0], Indices.size());
+ V = GEP->getPointerOperand();
+ } else if (Operator::getOpcode(V) == Instruction::BitCast) {
+ V = cast<Operator>(V)->getOperand(0);
+ } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
+ if (GA->mayBeOverridden())
+ return V;
+ V = GA->getAliasee();
+ } else {
+ return V;
+ }
+ assert(isa<PointerType>(V->getType()) && "Unexpected operand type!");
+ }
+ return V;
+}
+
/// isSafeToLoadUnconditionally - Return true if we know that executing a load
/// from this value cannot trap. If it is not obviously safe to load from the
/// specified pointer, we do a quick local scan of the basic block containing
/// ScanFrom, to determine if the address is already accessed.
-bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom) {
- // If it is an alloca it is always safe to load from.
- if (isa<AllocaInst>(V)) return true;
+bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
+ unsigned Align, const TargetData *TD) {
+ uint64_t ByteOffset = 0;
+ Value *Base = V;
+ if (TD)
+ Base = getUnderlyingObjectWithOffset(V, TD, ByteOffset);
+
+ const Type *BaseType = 0;
+ unsigned BaseAlign = 0;
+ if (const AllocaInst *AI = dyn_cast<AllocaInst>(Base)) {
+ // An alloca is safe to load from as load as it is suitably aligned.
+ BaseType = AI->getAllocatedType();
+ BaseAlign = AI->getAlignment();
+ } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(Base)) {
+ // Global variables are safe to load from but their size cannot be
+ // guaranteed if they are overridden.
+ if (!isa<GlobalAlias>(GV) && !GV->mayBeOverridden()) {
+ BaseType = GV->getType()->getElementType();
+ BaseAlign = GV->getAlignment();
+ }
+ }
- // If it is a global variable it is mostly safe to load from.
- if (const GlobalValue *GV = dyn_cast<GlobalVariable>(V))
- // Don't try to evaluate aliases. External weak GV can be null.
- return !isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage();
+ if (BaseType && BaseType->isSized()) {
+ if (TD && BaseAlign == 0)
+ BaseAlign = TD->getPrefTypeAlignment(BaseType);
- // Otherwise, be a little bit agressive by scanning the local block where we
+ if (Align <= BaseAlign) {
+ if (!TD)
+ return true; // Loading directly from an alloca or global is OK.
+
+ // Check if the load is within the bounds of the underlying object.
+ const PointerType *AddrTy = cast<PointerType>(V->getType());
+ uint64_t LoadSize = TD->getTypeStoreSize(AddrTy->getElementType());
+ if (ByteOffset + LoadSize <= TD->getTypeAllocSize(BaseType) &&
+ (Align == 0 || (ByteOffset % Align) == 0))
+ return true;
+ }
+ }
+
+ // Otherwise, be a little bit aggressive by scanning the local block where we
// want to check to see if the pointer is already being loaded or stored
// from/to. If so, the previous load or store would have already trapped,
// so there is no harm doing an extra load (also, CSE will later eliminate
@@ -428,6 +490,17 @@ void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, Pass *P) {
// Splice all the instructions from PredBB to DestBB.
PredBB->getTerminator()->eraseFromParent();
DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList());
+
+ // Zap anything that took the address of DestBB. Not doing this will give the
+ // address an invalid value.
+ if (DestBB->hasAddressTaken()) {
+ BlockAddress *BA = BlockAddress::get(DestBB);
+ Constant *Replacement =
+ ConstantInt::get(llvm::Type::getInt32Ty(BA->getContext()), 1);
+ BA->replaceAllUsesWith(ConstantExpr::getIntToPtr(Replacement,
+ BA->getType()));
+ BA->destroyConstant();
+ }
// Anything that branched to PredBB now branches to DestBB.
PredBB->replaceAllUsesWith(DestBB);
diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp
index e81b779..57bab60 100644
--- a/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/lib/Transforms/Utils/LoopSimplify.cpp
@@ -176,8 +176,9 @@ ReprocessLoop:
SmallVector<BasicBlock*, 8> ExitBlocks;
L->getExitBlocks(ExitBlocks);
- SetVector<BasicBlock*> ExitBlockSet(ExitBlocks.begin(), ExitBlocks.end());
- for (SetVector<BasicBlock*>::iterator I = ExitBlockSet.begin(),
+ SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(),
+ ExitBlocks.end());
+ for (SmallSetVector<BasicBlock *, 8>::iterator I = ExitBlockSet.begin(),
E = ExitBlockSet.end(); I != E; ++I) {
BasicBlock *ExitBlock = *I;
for (pred_iterator PI = pred_begin(ExitBlock), PE = pred_end(ExitBlock);
diff --git a/lib/Transforms/Utils/LoopUnroll.cpp b/lib/Transforms/Utils/LoopUnroll.cpp
index 53117a0..e47c86d 100644
--- a/lib/Transforms/Utils/LoopUnroll.cpp
+++ b/lib/Transforms/Utils/LoopUnroll.cpp
@@ -29,7 +29,6 @@
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
-#include <cstdio>
using namespace llvm;
@@ -204,15 +203,12 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, LoopInfo* LI, LPPassManager* LPM)
Latches.push_back(LatchBlock);
for (unsigned It = 1; It != Count; ++It) {
- char SuffixBuffer[100];
- sprintf(SuffixBuffer, ".%d", It);
-
std::vector<BasicBlock*> NewBlocks;
for (std::vector<BasicBlock*>::iterator BB = LoopBlocks.begin(),
E = LoopBlocks.end(); BB != E; ++BB) {
ValueMapTy ValueMap;
- BasicBlock *New = CloneBasicBlock(*BB, ValueMap, SuffixBuffer);
+ BasicBlock *New = CloneBasicBlock(*BB, ValueMap, "." + Twine(It));
Header->getParent()->getBasicBlockList().push_back(New);
// Loop over all of the PHI nodes in the block, changing them to use the
diff --git a/lib/Transforms/Utils/Makefile b/lib/Transforms/Utils/Makefile
index b9761df..d1e9336 100644
--- a/lib/Transforms/Utils/Makefile
+++ b/lib/Transforms/Utils/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../..
LIBRARYNAME = LLVMTransformUtils
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index d9261ac..544e20b 100644
--- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -23,6 +23,7 @@
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
+#include "llvm/Metadata.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/AliasSetTracker.h"
@@ -84,6 +85,18 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) {
return true;
}
+/// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic describing the
+/// alloca 'V', if any.
+static DbgDeclareInst *FindAllocaDbgDeclare(Value *V) {
+ if (MDNode *DebugNode = MDNode::getIfExists(V->getContext(), &V, 1))
+ for (Value::use_iterator UI = DebugNode->use_begin(),
+ E = DebugNode->use_end(); UI != E; ++UI)
+ if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(*UI))
+ return DDI;
+
+ return 0;
+}
+
namespace {
struct AllocaInfo;
@@ -188,6 +201,11 @@ namespace {
///
std::vector<Value*> PointerAllocaValues;
+ /// AllocaDbgDeclares - For each alloca, we keep track of the dbg.declare
+ /// intrinsic that describes it, if any, so that we can convert it to a
+ /// dbg.value intrinsic if the alloca gets promoted.
+ SmallVector<DbgDeclareInst*, 8> AllocaDbgDeclares;
+
/// Visited - The set of basic blocks the renamer has already visited.
///
SmallPtrSet<BasicBlock*, 16> Visited;
@@ -202,6 +220,9 @@ namespace {
PromoteMem2Reg(const std::vector<AllocaInst*> &A, DominatorTree &dt,
DominanceFrontier &df, AliasSetTracker *ast)
: Allocas(A), DT(dt), DF(df), DIF(0), AST(ast) {}
+ ~PromoteMem2Reg() {
+ delete DIF;
+ }
void run();
@@ -243,9 +264,9 @@ namespace {
LargeBlockInfo &LBI);
void PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
LargeBlockInfo &LBI);
- void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst* SI,
- uint64_t Offset);
-
+ void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst *SI);
+
+
void RenamePass(BasicBlock *BB, BasicBlock *Pred,
RenamePassData::ValVector &IncVals,
std::vector<RenamePassData> &Worklist);
@@ -262,6 +283,7 @@ namespace {
bool OnlyUsedInOneBlock;
Value *AllocaPointerVal;
+ DbgDeclareInst *DbgDeclare;
void clear() {
DefiningBlocks.clear();
@@ -270,6 +292,7 @@ namespace {
OnlyBlock = 0;
OnlyUsedInOneBlock = true;
AllocaPointerVal = 0;
+ DbgDeclare = 0;
}
/// AnalyzeAlloca - Scan the uses of the specified alloca, filling in our
@@ -304,28 +327,18 @@ namespace {
OnlyUsedInOneBlock = false;
}
}
+
+ DbgDeclare = FindAllocaDbgDeclare(AI);
}
};
} // end of anonymous namespace
-/// Finds the llvm.dbg.declare intrinsic corresponding to an alloca if any.
-static DbgDeclareInst *findDbgDeclare(AllocaInst *AI) {
- Function *F = AI->getParent()->getParent();
- for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
- for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end();
- BI != BE; ++BI)
- if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
- if (DDI->getAddress() == AI)
- return DDI;
-
- return 0;
-}
-
void PromoteMem2Reg::run() {
Function &F = *DF.getRoot()->getParent();
if (AST) PointerAllocaValues.resize(Allocas.size());
+ AllocaDbgDeclares.resize(Allocas.size());
AllocaInfo Info;
LargeBlockInfo LBI;
@@ -360,8 +373,11 @@ void PromoteMem2Reg::run() {
// Finally, after the scan, check to see if the store is all that is left.
if (Info.UsingBlocks.empty()) {
- // Record debuginfo for the store before removing it.
- ConvertDebugDeclareToDebugValue(findDbgDeclare(AI), Info.OnlyStore, 0);
+ // Record debuginfo for the store and remove the declaration's debuginfo.
+ if (DbgDeclareInst *DDI = Info.DbgDeclare) {
+ ConvertDebugDeclareToDebugValue(DDI, Info.OnlyStore);
+ DDI->eraseFromParent();
+ }
// Remove the (now dead) store and alloca.
Info.OnlyStore->eraseFromParent();
LBI.deleteValue(Info.OnlyStore);
@@ -388,11 +404,11 @@ void PromoteMem2Reg::run() {
if (Info.UsingBlocks.empty()) {
// Remove the (now dead) stores and alloca.
- DbgDeclareInst *DDI = findDbgDeclare(AI);
while (!AI->use_empty()) {
StoreInst *SI = cast<StoreInst>(AI->use_back());
// Record debuginfo for the store before removing it.
- ConvertDebugDeclareToDebugValue(DDI, SI, 0);
+ if (DbgDeclareInst *DDI = Info.DbgDeclare)
+ ConvertDebugDeclareToDebugValue(DDI, SI);
SI->eraseFromParent();
LBI.deleteValue(SI);
}
@@ -404,6 +420,10 @@ void PromoteMem2Reg::run() {
// The alloca has been processed, move on.
RemoveFromAllocasList(AllocaNum);
+ // The alloca's debuginfo can be removed as well.
+ if (DbgDeclareInst *DDI = Info.DbgDeclare)
+ DDI->eraseFromParent();
+
++NumLocalPromoted;
continue;
}
@@ -421,6 +441,9 @@ void PromoteMem2Reg::run() {
// stored into the alloca.
if (AST)
PointerAllocaValues[AllocaNum] = Info.AllocaPointerVal;
+
+ // Remember the dbg.declare intrinsic describing this alloca, if any.
+ if (Info.DbgDeclare) AllocaDbgDeclares[AllocaNum] = Info.DbgDeclare;
// Keep the reverse mapping of the 'Allocas' array for the rename pass.
AllocaLookup[Allocas[AllocaNum]] = AllocaNum;
@@ -476,7 +499,11 @@ void PromoteMem2Reg::run() {
A->eraseFromParent();
}
-
+ // Remove alloca's dbg.declare instrinsics from the function.
+ for (unsigned i = 0, e = AllocaDbgDeclares.size(); i != e; ++i)
+ if (DbgDeclareInst *DDI = AllocaDbgDeclares[i])
+ DDI->eraseFromParent();
+
// Loop over all of the PHI nodes and see if there are any that we can get
// rid of because they merge all of the same incoming values. This can
// happen due to undef values coming into the PHI nodes. This process is
@@ -857,14 +884,19 @@ void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value
// that has an associated llvm.dbg.decl intrinsic.
void PromoteMem2Reg::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
- StoreInst* SI,
- uint64_t Offset) {
- if (!DDI) return;
+ StoreInst *SI) {
+ DIVariable DIVar(DDI->getVariable());
+ if (!DIVar.getNode())
+ return;
if (!DIF)
DIF = new DIFactory(*SI->getParent()->getParent()->getParent());
- DIF->InsertDbgValueIntrinsic(SI->getOperand(0), Offset,
- DIVariable(DDI->getVariable()), SI);
+ Instruction *DbgVal = DIF->InsertDbgValueIntrinsic(SI->getOperand(0), 0,
+ DIVar, SI);
+
+ // Propagate any debug metadata from the store onto the dbg.value.
+ if (MDNode *SIMD = SI->getMetadata("dbg"))
+ DbgVal->setMetadata("dbg", SIMD);
}
// QueuePhiNode - queues a phi-node to be added to a basic-block for a specific
@@ -980,7 +1012,8 @@ NextIteration:
// what value were we writing?
IncomingVals[ai->second] = SI->getOperand(0);
// Record debuginfo for the store before removing it.
- ConvertDebugDeclareToDebugValue(findDbgDeclare(Dest), SI, 0);
+ if (DbgDeclareInst *DDI = AllocaDbgDeclares[ai->second])
+ ConvertDebugDeclareToDebugValue(DDI, SI);
BB->getInstList().erase(SI);
}
}
diff --git a/lib/Transforms/Utils/SSAUpdater.cpp b/lib/Transforms/Utils/SSAUpdater.cpp
index 161bf21..a31235a 100644
--- a/lib/Transforms/Utils/SSAUpdater.cpp
+++ b/lib/Transforms/Utils/SSAUpdater.cpp
@@ -71,6 +71,50 @@ void SSAUpdater::AddAvailableValue(BasicBlock *BB, Value *V) {
getAvailableVals(AV)[BB] = V;
}
+/// IsEquivalentPHI - Check if PHI has the same incoming value as specified
+/// in ValueMapping for each predecessor block.
+static bool IsEquivalentPHI(PHINode *PHI,
+ DenseMap<BasicBlock*, Value*> &ValueMapping) {
+ unsigned PHINumValues = PHI->getNumIncomingValues();
+ if (PHINumValues != ValueMapping.size())
+ return false;
+
+ // Scan the phi to see if it matches.
+ for (unsigned i = 0, e = PHINumValues; i != e; ++i)
+ if (ValueMapping[PHI->getIncomingBlock(i)] !=
+ PHI->getIncomingValue(i)) {
+ return false;
+ }
+
+ return true;
+}
+
+/// GetExistingPHI - Check if BB already contains a phi node that is equivalent
+/// to the specified mapping from predecessor blocks to incoming values.
+static Value *GetExistingPHI(BasicBlock *BB,
+ DenseMap<BasicBlock*, Value*> &ValueMapping) {
+ PHINode *SomePHI;
+ for (BasicBlock::iterator It = BB->begin();
+ (SomePHI = dyn_cast<PHINode>(It)); ++It) {
+ if (IsEquivalentPHI(SomePHI, ValueMapping))
+ return SomePHI;
+ }
+ return 0;
+}
+
+/// GetExistingPHI - Check if BB already contains an equivalent phi node.
+/// The InputIt type must be an iterator over std::pair<BasicBlock*, Value*>
+/// objects that specify the mapping from predecessor blocks to incoming values.
+template<typename InputIt>
+static Value *GetExistingPHI(BasicBlock *BB, const InputIt &I,
+ const InputIt &E) {
+ // Avoid create the mapping if BB has no phi nodes at all.
+ if (!isa<PHINode>(BB->begin()))
+ return 0;
+ DenseMap<BasicBlock*, Value*> ValueMapping(I, E);
+ return GetExistingPHI(BB, ValueMapping);
+}
+
/// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
/// live at the end of the specified block.
Value *SSAUpdater::GetValueAtEndOfBlock(BasicBlock *BB) {
@@ -149,28 +193,11 @@ Value *SSAUpdater::GetValueInMiddleOfBlock(BasicBlock *BB) {
if (SingularValue != 0)
return SingularValue;
- // Otherwise, we do need a PHI: check to see if we already have one available
- // in this block that produces the right value.
- if (isa<PHINode>(BB->begin())) {
- DenseMap<BasicBlock*, Value*> ValueMapping(PredValues.begin(),
- PredValues.end());
- PHINode *SomePHI;
- for (BasicBlock::iterator It = BB->begin();
- (SomePHI = dyn_cast<PHINode>(It)); ++It) {
- // Scan this phi to see if it is what we need.
- bool Equal = true;
- for (unsigned i = 0, e = SomePHI->getNumIncomingValues(); i != e; ++i)
- if (ValueMapping[SomePHI->getIncomingBlock(i)] !=
- SomePHI->getIncomingValue(i)) {
- Equal = false;
- break;
- }
-
- if (Equal)
- return SomePHI;
- }
- }
-
+ // Otherwise, we do need a PHI.
+ if (Value *ExistingPHI = GetExistingPHI(BB, PredValues.begin(),
+ PredValues.end()))
+ return ExistingPHI;
+
// Ok, we have no way out, insert a new one now.
PHINode *InsertedPHI = PHINode::Create(PrototypeValue->getType(),
PrototypeValue->getName(),
@@ -255,7 +282,7 @@ Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) {
// producing the same value. If so, this value will capture it, if not, it
// will get reset to null. We distinguish the no-predecessor case explicitly
// below.
- TrackingVH<Value> SingularValue;
+ TrackingVH<Value> ExistingValue;
// We can get our predecessor info by walking the pred_iterator list, but it
// is relatively slow. If we already have PHI nodes in this block, walk one
@@ -266,11 +293,11 @@ Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) {
Value *PredVal = GetValueAtEndOfBlockInternal(PredBB);
IncomingPredInfo.push_back(std::make_pair(PredBB, PredVal));
- // Compute SingularValue.
+ // Set ExistingValue to singular value from all predecessors so far.
if (i == 0)
- SingularValue = PredVal;
- else if (PredVal != SingularValue)
- SingularValue = 0;
+ ExistingValue = PredVal;
+ else if (PredVal != ExistingValue)
+ ExistingValue = 0;
}
} else {
bool isFirstPred = true;
@@ -279,12 +306,12 @@ Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) {
Value *PredVal = GetValueAtEndOfBlockInternal(PredBB);
IncomingPredInfo.push_back(std::make_pair(PredBB, PredVal));
- // Compute SingularValue.
+ // Set ExistingValue to singular value from all predecessors so far.
if (isFirstPred) {
- SingularValue = PredVal;
+ ExistingValue = PredVal;
isFirstPred = false;
- } else if (PredVal != SingularValue)
- SingularValue = 0;
+ } else if (PredVal != ExistingValue)
+ ExistingValue = 0;
}
}
@@ -300,31 +327,38 @@ Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) {
/// above.
TrackingVH<Value> &InsertedVal = AvailableVals[BB];
- // If all the predecessor values are the same then we don't need to insert a
+ // If the predecessor values are not all the same, then check to see if there
+ // is an existing PHI that can be used.
+ if (!ExistingValue)
+ ExistingValue = GetExistingPHI(BB,
+ IncomingPredInfo.begin()+FirstPredInfoEntry,
+ IncomingPredInfo.end());
+
+ // If there is an existing value we can use, then we don't need to insert a
// PHI. This is the simple and common case.
- if (SingularValue) {
- // If a PHI node got inserted, replace it with the singlar value and delete
+ if (ExistingValue) {
+ // If a PHI node got inserted, replace it with the existing value and delete
// it.
if (InsertedVal) {
PHINode *OldVal = cast<PHINode>(InsertedVal);
// Be careful about dead loops. These RAUW's also update InsertedVal.
- if (InsertedVal != SingularValue)
- OldVal->replaceAllUsesWith(SingularValue);
+ if (InsertedVal != ExistingValue)
+ OldVal->replaceAllUsesWith(ExistingValue);
else
OldVal->replaceAllUsesWith(UndefValue::get(InsertedVal->getType()));
OldVal->eraseFromParent();
} else {
- InsertedVal = SingularValue;
+ InsertedVal = ExistingValue;
}
- // Either path through the 'if' should have set insertedVal -> SingularVal.
- assert((InsertedVal == SingularValue || isa<UndefValue>(InsertedVal)) &&
- "RAUW didn't change InsertedVal to be SingularVal");
+ // Either path through the 'if' should have set InsertedVal -> ExistingVal.
+ assert((InsertedVal == ExistingValue || isa<UndefValue>(InsertedVal)) &&
+ "RAUW didn't change InsertedVal to be ExistingValue");
// Drop the entries we added in IncomingPredInfo to restore the stack.
IncomingPredInfo.erase(IncomingPredInfo.begin()+FirstPredInfoEntry,
IncomingPredInfo.end());
- return SingularValue;
+ return ExistingValue;
}
// Otherwise, we do need a PHI: insert one now if we don't already have one.
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index cb53296..2215059 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -23,6 +23,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
@@ -36,6 +37,28 @@ using namespace llvm;
STATISTIC(NumSpeculations, "Number of speculative executed instructions");
+namespace {
+class SimplifyCFGOpt {
+ const TargetData *const TD;
+
+ ConstantInt *GetConstantInt(Value *V);
+ Value *GatherConstantSetEQs(Value *V, std::vector<ConstantInt*> &Values);
+ Value *GatherConstantSetNEs(Value *V, std::vector<ConstantInt*> &Values);
+ bool GatherValueComparisons(Instruction *Cond, Value *&CompVal,
+ std::vector<ConstantInt*> &Values);
+ Value *isValueEqualityComparison(TerminatorInst *TI);
+ BasicBlock *GetValueEqualityComparisonCases(TerminatorInst *TI,
+ std::vector<std::pair<ConstantInt*, BasicBlock*> > &Cases);
+ bool SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
+ BasicBlock *Pred);
+ bool FoldValueComparisonIntoPredecessors(TerminatorInst *TI);
+
+public:
+ explicit SimplifyCFGOpt(const TargetData *td) : TD(td) {}
+ bool run(BasicBlock *BB);
+};
+}
+
/// SafeToMergeTerminators - Return true if it is safe to merge these two
/// terminator instructions together.
///
@@ -243,17 +266,48 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
return true;
}
+/// GetConstantInt - Extract ConstantInt from value, looking through IntToPtr
+/// and PointerNullValue. Return NULL if value is not a constant int.
+ConstantInt *SimplifyCFGOpt::GetConstantInt(Value *V) {
+ // Normal constant int.
+ ConstantInt *CI = dyn_cast<ConstantInt>(V);
+ if (CI || !TD || !isa<Constant>(V) || !isa<PointerType>(V->getType()))
+ return CI;
+
+ // This is some kind of pointer constant. Turn it into a pointer-sized
+ // ConstantInt if possible.
+ const IntegerType *PtrTy = TD->getIntPtrType(V->getContext());
+
+ // Null pointer means 0, see SelectionDAGBuilder::getValue(const Value*).
+ if (isa<ConstantPointerNull>(V))
+ return ConstantInt::get(PtrTy, 0);
+
+ // IntToPtr const int.
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ if (CE->getOpcode() == Instruction::IntToPtr)
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(0))) {
+ // The constant is very likely to have the right type already.
+ if (CI->getType() == PtrTy)
+ return CI;
+ else
+ return cast<ConstantInt>
+ (ConstantExpr::getIntegerCast(CI, PtrTy, /*isSigned=*/false));
+ }
+ return 0;
+}
+
/// GatherConstantSetEQs - Given a potentially 'or'd together collection of
/// icmp_eq instructions that compare a value against a constant, return the
/// value being compared, and stick the constant into the Values vector.
-static Value *GatherConstantSetEQs(Value *V, std::vector<ConstantInt*> &Values){
+Value *SimplifyCFGOpt::
+GatherConstantSetEQs(Value *V, std::vector<ConstantInt*> &Values) {
if (Instruction *Inst = dyn_cast<Instruction>(V)) {
if (Inst->getOpcode() == Instruction::ICmp &&
cast<ICmpInst>(Inst)->getPredicate() == ICmpInst::ICMP_EQ) {
- if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand(1))) {
+ if (ConstantInt *C = GetConstantInt(Inst->getOperand(1))) {
Values.push_back(C);
return Inst->getOperand(0);
- } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand(0))) {
+ } else if (ConstantInt *C = GetConstantInt(Inst->getOperand(0))) {
Values.push_back(C);
return Inst->getOperand(1);
}
@@ -270,14 +324,15 @@ static Value *GatherConstantSetEQs(Value *V, std::vector<ConstantInt*> &Values){
/// GatherConstantSetNEs - Given a potentially 'and'd together collection of
/// setne instructions that compare a value against a constant, return the value
/// being compared, and stick the constant into the Values vector.
-static Value *GatherConstantSetNEs(Value *V, std::vector<ConstantInt*> &Values){
+Value *SimplifyCFGOpt::
+GatherConstantSetNEs(Value *V, std::vector<ConstantInt*> &Values) {
if (Instruction *Inst = dyn_cast<Instruction>(V)) {
if (Inst->getOpcode() == Instruction::ICmp &&
cast<ICmpInst>(Inst)->getPredicate() == ICmpInst::ICMP_NE) {
- if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand(1))) {
+ if (ConstantInt *C = GetConstantInt(Inst->getOperand(1))) {
Values.push_back(C);
return Inst->getOperand(0);
- } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand(0))) {
+ } else if (ConstantInt *C = GetConstantInt(Inst->getOperand(0))) {
Values.push_back(C);
return Inst->getOperand(1);
}
@@ -294,8 +349,8 @@ static Value *GatherConstantSetNEs(Value *V, std::vector<ConstantInt*> &Values){
/// GatherValueComparisons - If the specified Cond is an 'and' or 'or' of a
/// bunch of comparisons of one value against constants, return the value and
/// the constants being compared.
-static bool GatherValueComparisons(Instruction *Cond, Value *&CompVal,
- std::vector<ConstantInt*> &Values) {
+bool SimplifyCFGOpt::GatherValueComparisons(Instruction *Cond, Value *&CompVal,
+ std::vector<ConstantInt*> &Values) {
if (Cond->getOpcode() == Instruction::Or) {
CompVal = GatherConstantSetEQs(Cond, Values);
@@ -327,29 +382,32 @@ static void EraseTerminatorInstAndDCECond(TerminatorInst *TI) {
/// isValueEqualityComparison - Return true if the specified terminator checks
/// to see if a value is equal to constant integer value.
-static Value *isValueEqualityComparison(TerminatorInst *TI) {
+Value *SimplifyCFGOpt::isValueEqualityComparison(TerminatorInst *TI) {
+ Value *CV = 0;
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
// Do not permit merging of large switch instructions into their
// predecessors unless there is only one predecessor.
- if (SI->getNumSuccessors() * std::distance(pred_begin(SI->getParent()),
- pred_end(SI->getParent())) > 128)
- return 0;
-
- return SI->getCondition();
- }
- if (BranchInst *BI = dyn_cast<BranchInst>(TI))
+ if (SI->getNumSuccessors()*std::distance(pred_begin(SI->getParent()),
+ pred_end(SI->getParent())) <= 128)
+ CV = SI->getCondition();
+ } else if (BranchInst *BI = dyn_cast<BranchInst>(TI))
if (BI->isConditional() && BI->getCondition()->hasOneUse())
if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition()))
if ((ICI->getPredicate() == ICmpInst::ICMP_EQ ||
ICI->getPredicate() == ICmpInst::ICMP_NE) &&
- isa<ConstantInt>(ICI->getOperand(1)))
- return ICI->getOperand(0);
- return 0;
+ GetConstantInt(ICI->getOperand(1)))
+ CV = ICI->getOperand(0);
+
+ // Unwrap any lossless ptrtoint cast.
+ if (TD && CV && CV->getType() == TD->getIntPtrType(CV->getContext()))
+ if (PtrToIntInst *PTII = dyn_cast<PtrToIntInst>(CV))
+ CV = PTII->getOperand(0);
+ return CV;
}
/// GetValueEqualityComparisonCases - Given a value comparison instruction,
/// decode all of the 'cases' that it represents and return the 'default' block.
-static BasicBlock *
+BasicBlock *SimplifyCFGOpt::
GetValueEqualityComparisonCases(TerminatorInst *TI,
std::vector<std::pair<ConstantInt*,
BasicBlock*> > &Cases) {
@@ -362,7 +420,7 @@ GetValueEqualityComparisonCases(TerminatorInst *TI,
BranchInst *BI = cast<BranchInst>(TI);
ICmpInst *ICI = cast<ICmpInst>(BI->getCondition());
- Cases.push_back(std::make_pair(cast<ConstantInt>(ICI->getOperand(1)),
+ Cases.push_back(std::make_pair(GetConstantInt(ICI->getOperand(1)),
BI->getSuccessor(ICI->getPredicate() ==
ICmpInst::ICMP_NE)));
return BI->getSuccessor(ICI->getPredicate() == ICmpInst::ICMP_EQ);
@@ -421,8 +479,9 @@ ValuesOverlap(std::vector<std::pair<ConstantInt*, BasicBlock*> > &C1,
/// comparison with the same value, and if that comparison determines the
/// outcome of this comparison. If so, simplify TI. This does a very limited
/// form of jump threading.
-static bool SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
- BasicBlock *Pred) {
+bool SimplifyCFGOpt::
+SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
+ BasicBlock *Pred) {
Value *PredVal = isValueEqualityComparison(Pred->getTerminator());
if (!PredVal) return false; // Not a value comparison in predecessor.
@@ -548,7 +607,7 @@ namespace {
/// equality comparison instruction (either a switch or a branch on "X == c").
/// See if any of the predecessors of the terminator block are value comparisons
/// on the same value. If so, and if safe to do so, fold them together.
-static bool FoldValueComparisonIntoPredecessors(TerminatorInst *TI) {
+bool SimplifyCFGOpt::FoldValueComparisonIntoPredecessors(TerminatorInst *TI) {
BasicBlock *BB = TI->getParent();
Value *CV = isValueEqualityComparison(TI); // CondVal
assert(CV && "Not a comparison?");
@@ -641,6 +700,13 @@ static bool FoldValueComparisonIntoPredecessors(TerminatorInst *TI) {
for (unsigned i = 0, e = NewSuccessors.size(); i != e; ++i)
AddPredecessorToBlock(NewSuccessors[i], Pred, BB);
+ // Convert pointer to int before we switch.
+ if (isa<PointerType>(CV->getType())) {
+ assert(TD && "Cannot switch on pointer without TargetData");
+ CV = new PtrToIntInst(CV, TD->getIntPtrType(CV->getContext()),
+ "magicptr", PTI);
+ }
+
// Now that the successors are updated, create the new Switch instruction.
SwitchInst *NewSI = SwitchInst::Create(CV, PredDefault,
PredCases.size(), PTI);
@@ -1011,7 +1077,7 @@ static bool FoldCondBranchOnPHI(BranchInst *BI) {
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
ConstantInt *CB;
if ((CB = dyn_cast<ConstantInt>(PN->getIncomingValue(i))) &&
- CB->getType()->isInteger(1)) {
+ CB->getType()->isIntegerTy(1)) {
// Okay, we now know that all edges from PredBB should be revectored to
// branch to RealDest.
BasicBlock *PredBB = PN->getIncomingBlock(i);
@@ -1589,14 +1655,7 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI) {
return true;
}
-/// SimplifyCFG - This function is used to do simplification of a CFG. For
-/// example, it adjusts branches to branches to eliminate the extra hop, it
-/// eliminates unreachable basic blocks, and does other "peephole" optimization
-/// of the CFG. It returns true if a modification was made.
-///
-/// WARNING: The entry node of a function may not be simplified.
-///
-bool llvm::SimplifyCFG(BasicBlock *BB) {
+bool SimplifyCFGOpt::run(BasicBlock *BB) {
bool Changed = false;
Function *M = BB->getParent();
@@ -1997,7 +2056,7 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
Value *CompVal = 0;
std::vector<ConstantInt*> Values;
bool TrueWhenEqual = GatherValueComparisons(Cond, CompVal, Values);
- if (CompVal && CompVal->getType()->isInteger()) {
+ if (CompVal) {
// There might be duplicate constants in the list, which the switch
// instruction can't handle, remove them now.
std::sort(Values.begin(), Values.end(), ConstantIntOrdering());
@@ -2008,6 +2067,14 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
BasicBlock *EdgeBB = BI->getSuccessor(0);
if (!TrueWhenEqual) std::swap(DefaultBB, EdgeBB);
+ // Convert pointer to int before we switch.
+ if (isa<PointerType>(CompVal->getType())) {
+ assert(TD && "Cannot switch on pointer without TargetData");
+ CompVal = new PtrToIntInst(CompVal,
+ TD->getIntPtrType(CompVal->getContext()),
+ "magicptr", BI);
+ }
+
// Create the new switch instruction now.
SwitchInst *New = SwitchInst::Create(CompVal, DefaultBB,
Values.size(), BI);
@@ -2035,3 +2102,14 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
return Changed;
}
+
+/// SimplifyCFG - This function is used to do simplification of a CFG. For
+/// example, it adjusts branches to branches to eliminate the extra hop, it
+/// eliminates unreachable basic blocks, and does other "peephole" optimization
+/// of the CFG. It returns true if a modification was made.
+///
+/// WARNING: The entry node of a function may not be simplified.
+///
+bool llvm::SimplifyCFG(BasicBlock *BB, const TargetData *TD) {
+ return SimplifyCFGOpt(TD).run(BB);
+}
diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp
index a6e6701..6045048 100644
--- a/lib/Transforms/Utils/ValueMapper.cpp
+++ b/lib/Transforms/Utils/ValueMapper.cpp
@@ -35,7 +35,7 @@ Value *llvm::MapValue(const Value *V, ValueMapTy &VM) {
if (const MDNode *MD = dyn_cast<MDNode>(V)) {
SmallVector<Value*, 4> Elts;
- for (unsigned i = 0; i != MD->getNumOperands(); i++)
+ for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i)
Elts.push_back(MD->getOperand(i) ? MapValue(MD->getOperand(i), VM) : 0);
return VM[V] = MDNode::get(V->getContext(), Elts.data(), Elts.size());
}
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index c9f3849..f5ba7e7 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -27,6 +27,7 @@
#include "llvm/ValueSymbolTable.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CFG.h"
@@ -238,6 +239,19 @@ void TypePrinting::CalcTypeName(const Type *Ty,
OS << '>';
break;
}
+ case Type::UnionTyID: {
+ const UnionType *UTy = cast<UnionType>(Ty);
+ OS << "union { ";
+ for (StructType::element_iterator I = UTy->element_begin(),
+ E = UTy->element_end(); I != E; ++I) {
+ CalcTypeName(*I, TypeStack, OS);
+ if (next(I) != UTy->element_end())
+ OS << ',';
+ OS << ' ';
+ }
+ OS << '}';
+ break;
+ }
case Type::PointerTyID: {
const PointerType *PTy = cast<PointerType>(Ty);
CalcTypeName(PTy->getElementType(), TypeStack, OS);
@@ -417,13 +431,13 @@ static void AddModuleTypesToPrinter(TypePrinting &TP,
// they are used too often to have a single useful name.
if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
const Type *PETy = PTy->getElementType();
- if ((PETy->isPrimitiveType() || PETy->isInteger()) &&
+ if ((PETy->isPrimitiveType() || PETy->isIntegerTy()) &&
!isa<OpaqueType>(PETy))
continue;
}
// Likewise don't insert primitives either.
- if (Ty->isInteger() || Ty->isPrimitiveType())
+ if (Ty->isIntegerTy() || Ty->isPrimitiveType())
continue;
// Get the name as a string and insert it into TypeNames.
@@ -835,7 +849,7 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
TypePrinting &TypePrinter, SlotTracker *Machine) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- if (CI->getType()->isInteger(1)) {
+ if (CI->getType()->isIntegerTy(1)) {
Out << (CI->getZExtValue() ? "true" : "false");
return;
}
@@ -855,7 +869,8 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble;
double Val = isDouble ? CFP->getValueAPF().convertToDouble() :
CFP->getValueAPF().convertToFloat();
- std::string StrVal = ftostr(CFP->getValueAPF());
+ SmallString<128> StrVal;
+ raw_svector_ostream(StrVal) << Val;
// Check to make sure that the stringized number is not some string like
// "Inf" or NaN, that atof will accept, but the lexer will not. Check
@@ -866,7 +881,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
(StrVal[1] >= '0' && StrVal[1] <= '9'))) {
// Reparse stringized version!
if (atof(StrVal.c_str()) == Val) {
- Out << StrVal;
+ Out << StrVal.str();
return;
}
}
@@ -1250,15 +1265,14 @@ public:
void printArgument(const Argument *FA, Attributes Attrs);
void printBasicBlock(const BasicBlock *BB);
void printInstruction(const Instruction &I);
-private:
+private:
// printInfoComment - Print a little comment after the instruction indicating
// which slot it occupies.
void printInfoComment(const Value &V);
};
} // end of anonymous namespace
-
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
if (Operand == 0) {
Out << "<null operand!>";
@@ -1402,8 +1416,6 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT,
case GlobalValue::AvailableExternallyLinkage:
Out << "available_externally ";
break;
- // This is invalid syntax and just a debugging aid.
- case GlobalValue::GhostLinkage: Out << "ghost "; break;
}
}
@@ -1418,6 +1430,9 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
}
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
+ if (GV->isMaterializable())
+ Out << "; Materializable\n";
+
WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine);
Out << " = ";
@@ -1448,6 +1463,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
}
void AssemblyWriter::printAlias(const GlobalAlias *GA) {
+ if (GA->isMaterializable())
+ Out << "; Materializable\n";
+
// Don't crash when dumping partially built GA
if (!GA->hasName())
Out << "<<nameless>> = ";
@@ -1521,6 +1539,9 @@ void AssemblyWriter::printFunction(const Function *F) {
if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
+ if (F->isMaterializable())
+ Out << "; Materializable\n";
+
if (F->isDeclaration())
Out << "declare ";
else
@@ -1680,11 +1701,15 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
}
-
/// printInfoComment - Print a little comment after the instruction indicating
/// which slot it occupies.
///
void AssemblyWriter::printInfoComment(const Value &V) {
+ if (AnnotationWriter) {
+ AnnotationWriter->printInfoComment(V, Out);
+ return;
+ }
+
if (V.getType()->isVoidTy()) return;
Out.PadToColumn(50);
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index 65155f1..ff0cc9b 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -56,6 +56,8 @@ std::string Attribute::getAsString(Attributes Attrs) {
Result += "optsize ";
if (Attrs & Attribute::NoInline)
Result += "noinline ";
+ if (Attrs & Attribute::InlineHint)
+ Result += "inlinehint ";
if (Attrs & Attribute::AlwaysInline)
Result += "alwaysinline ";
if (Attrs & Attribute::StackProtect)
@@ -68,6 +70,11 @@ std::string Attribute::getAsString(Attributes Attrs) {
Result += "noimplicitfloat ";
if (Attrs & Attribute::Naked)
Result += "naked ";
+ if (Attrs & Attribute::StackAlignment) {
+ Result += "alignstack(";
+ Result += utostr(Attribute::getStackAlignmentFromAttrs(Attrs));
+ Result += ") ";
+ }
if (Attrs & Attribute::Alignment) {
Result += "align ";
Result += utostr(Attribute::getAlignmentFromAttrs(Attrs));
@@ -82,7 +89,7 @@ std::string Attribute::getAsString(Attributes Attrs) {
Attributes Attribute::typeIncompatible(const Type *Ty) {
Attributes Incompatible = None;
- if (!Ty->isInteger())
+ if (!Ty->isIntegerTy())
// Attributes that only apply to integers.
Incompatible |= SExt | ZExt;
diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt
index 5ecedf1..4b80e36 100644
--- a/lib/VMCore/CMakeLists.txt
+++ b/lib/VMCore/CMakeLists.txt
@@ -8,17 +8,17 @@ add_llvm_library(LLVMCore
Core.cpp
Dominators.cpp
Function.cpp
+ GVMaterializer.cpp
Globals.cpp
+ IRBuilder.cpp
InlineAsm.cpp
Instruction.cpp
Instructions.cpp
IntrinsicInst.cpp
- IRBuilder.cpp
LLVMContext.cpp
LeakDetector.cpp
Metadata.cpp
Module.cpp
- ModuleProvider.cpp
Pass.cpp
PassManager.cpp
PrintModulePass.cpp
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index ddd5587..78a45e8 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -24,7 +24,6 @@
#include "llvm/Function.h"
#include "llvm/GlobalAlias.h"
#include "llvm/GlobalVariable.h"
-#include "llvm/LLVMContext.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -41,7 +40,7 @@ using namespace llvm;
/// BitCastConstantVector - Convert the specified ConstantVector node to the
/// specified vector type. At this point, we know that the elements of the
/// input vector constant are all simple integer or FP values.
-static Constant *BitCastConstantVector(LLVMContext &Context, ConstantVector *CV,
+static Constant *BitCastConstantVector(ConstantVector *CV,
const VectorType *DstTy) {
// If this cast changes element count then we can't handle it here:
// doing so requires endianness information. This should be handled by
@@ -91,8 +90,7 @@ foldConstantCastPair(
Type::getInt64Ty(DstTy->getContext()));
}
-static Constant *FoldBitCast(LLVMContext &Context,
- Constant *V, const Type *DestTy) {
+static Constant *FoldBitCast(Constant *V, const Type *DestTy) {
const Type *SrcTy = V->getType();
if (SrcTy == DestTy)
return V; // no-op cast
@@ -103,7 +101,8 @@ static Constant *FoldBitCast(LLVMContext &Context,
if (const PointerType *DPTy = dyn_cast<PointerType>(DestTy))
if (PTy->getAddressSpace() == DPTy->getAddressSpace()) {
SmallVector<Value*, 8> IdxList;
- Value *Zero = Constant::getNullValue(Type::getInt32Ty(Context));
+ Value *Zero =
+ Constant::getNullValue(Type::getInt32Ty(DPTy->getContext()));
IdxList.push_back(Zero);
const Type *ElTy = PTy->getElementType();
while (ElTy != DPTy->getElementType()) {
@@ -139,15 +138,14 @@ static Constant *FoldBitCast(LLVMContext &Context,
return Constant::getNullValue(DestTy);
if (ConstantVector *CV = dyn_cast<ConstantVector>(V))
- return BitCastConstantVector(Context, CV, DestPTy);
+ return BitCastConstantVector(CV, DestPTy);
}
// Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts
// This allows for other simplifications (although some of them
// can only be handled by Analysis/ConstantFolding.cpp).
if (isa<ConstantInt>(V) || isa<ConstantFP>(V))
- return ConstantExpr::getBitCast(
- ConstantVector::get(&V, 1), DestPTy);
+ return ConstantExpr::getBitCast(ConstantVector::get(&V, 1), DestPTy);
}
// Finally, implement bitcast folding now. The code below doesn't handle
@@ -157,23 +155,24 @@ static Constant *FoldBitCast(LLVMContext &Context,
// Handle integral constant input.
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
- if (DestTy->isInteger())
+ if (DestTy->isIntegerTy())
// Integral -> Integral. This is a no-op because the bit widths must
// be the same. Consequently, we just fold to V.
return V;
- if (DestTy->isFloatingPoint())
- return ConstantFP::get(Context, APFloat(CI->getValue(),
- DestTy != Type::getPPC_FP128Ty(Context)));
+ if (DestTy->isFloatingPointTy())
+ return ConstantFP::get(DestTy->getContext(),
+ APFloat(CI->getValue(),
+ !DestTy->isPPC_FP128Ty()));
// Otherwise, can't fold this (vector?)
return 0;
}
- // Handle ConstantFP input.
+ // Handle ConstantFP input: FP -> Integral.
if (ConstantFP *FP = dyn_cast<ConstantFP>(V))
- // FP -> Integral.
- return ConstantInt::get(Context, FP->getValueAPF().bitcastToAPInt());
+ return ConstantInt::get(FP->getContext(),
+ FP->getValueAPF().bitcastToAPInt());
return 0;
}
@@ -323,9 +322,195 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart,
}
}
+/// getFoldedSizeOf - Return a ConstantExpr with type DestTy for sizeof
+/// on Ty, with any known factors factored out. If Folded is false,
+/// return null if no factoring was possible, to avoid endlessly
+/// bouncing an unfoldable expression back into the top-level folder.
+///
+static Constant *getFoldedSizeOf(const Type *Ty, const Type *DestTy,
+ bool Folded) {
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+ Constant *N = ConstantInt::get(DestTy, ATy->getNumElements());
+ Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
+ return ConstantExpr::getNUWMul(E, N);
+ }
+ if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
+ Constant *N = ConstantInt::get(DestTy, VTy->getNumElements());
+ Constant *E = getFoldedSizeOf(VTy->getElementType(), DestTy, true);
+ return ConstantExpr::getNUWMul(E, N);
+ }
+ if (const StructType *STy = dyn_cast<StructType>(Ty))
+ if (!STy->isPacked()) {
+ unsigned NumElems = STy->getNumElements();
+ // An empty struct has size zero.
+ if (NumElems == 0)
+ return ConstantExpr::getNullValue(DestTy);
+ // Check for a struct with all members having the same size.
+ Constant *MemberSize =
+ getFoldedSizeOf(STy->getElementType(0), DestTy, true);
+ bool AllSame = true;
+ for (unsigned i = 1; i != NumElems; ++i)
+ if (MemberSize !=
+ getFoldedSizeOf(STy->getElementType(i), DestTy, true)) {
+ AllSame = false;
+ break;
+ }
+ if (AllSame) {
+ Constant *N = ConstantInt::get(DestTy, NumElems);
+ return ConstantExpr::getNUWMul(MemberSize, N);
+ }
+ }
+
+ // Pointer size doesn't depend on the pointee type, so canonicalize them
+ // to an arbitrary pointee.
+ if (const PointerType *PTy = dyn_cast<PointerType>(Ty))
+ if (!PTy->getElementType()->isIntegerTy(1))
+ return
+ getFoldedSizeOf(PointerType::get(IntegerType::get(PTy->getContext(), 1),
+ PTy->getAddressSpace()),
+ DestTy, true);
+
+ // If there's no interesting folding happening, bail so that we don't create
+ // a constant that looks like it needs folding but really doesn't.
+ if (!Folded)
+ return 0;
+
+ // Base case: Get a regular sizeof expression.
+ Constant *C = ConstantExpr::getSizeOf(Ty);
+ C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
+ DestTy, false),
+ C, DestTy);
+ return C;
+}
+
+/// getFoldedAlignOf - Return a ConstantExpr with type DestTy for alignof
+/// on Ty, with any known factors factored out. If Folded is false,
+/// return null if no factoring was possible, to avoid endlessly
+/// bouncing an unfoldable expression back into the top-level folder.
+///
+static Constant *getFoldedAlignOf(const Type *Ty, const Type *DestTy,
+ bool Folded) {
+ // The alignment of an array is equal to the alignment of the
+ // array element. Note that this is not always true for vectors.
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+ Constant *C = ConstantExpr::getAlignOf(ATy->getElementType());
+ C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
+ DestTy,
+ false),
+ C, DestTy);
+ return C;
+ }
+
+ if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+ // Packed structs always have an alignment of 1.
+ if (STy->isPacked())
+ return ConstantInt::get(DestTy, 1);
+
+ // Otherwise, struct alignment is the maximum alignment of any member.
+ // Without target data, we can't compare much, but we can check to see
+ // if all the members have the same alignment.
+ unsigned NumElems = STy->getNumElements();
+ // An empty struct has minimal alignment.
+ if (NumElems == 0)
+ return ConstantInt::get(DestTy, 1);
+ // Check for a struct with all members having the same alignment.
+ Constant *MemberAlign =
+ getFoldedAlignOf(STy->getElementType(0), DestTy, true);
+ bool AllSame = true;
+ for (unsigned i = 1; i != NumElems; ++i)
+ if (MemberAlign != getFoldedAlignOf(STy->getElementType(i), DestTy, true)) {
+ AllSame = false;
+ break;
+ }
+ if (AllSame)
+ return MemberAlign;
+ }
+
+ // Pointer alignment doesn't depend on the pointee type, so canonicalize them
+ // to an arbitrary pointee.
+ if (const PointerType *PTy = dyn_cast<PointerType>(Ty))
+ if (!PTy->getElementType()->isIntegerTy(1))
+ return
+ getFoldedAlignOf(PointerType::get(IntegerType::get(PTy->getContext(),
+ 1),
+ PTy->getAddressSpace()),
+ DestTy, true);
+
+ // If there's no interesting folding happening, bail so that we don't create
+ // a constant that looks like it needs folding but really doesn't.
+ if (!Folded)
+ return 0;
+
+ // Base case: Get a regular alignof expression.
+ Constant *C = ConstantExpr::getAlignOf(Ty);
+ C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
+ DestTy, false),
+ C, DestTy);
+ return C;
+}
+
+/// getFoldedOffsetOf - Return a ConstantExpr with type DestTy for offsetof
+/// on Ty and FieldNo, with any known factors factored out. If Folded is false,
+/// return null if no factoring was possible, to avoid endlessly
+/// bouncing an unfoldable expression back into the top-level folder.
+///
+static Constant *getFoldedOffsetOf(const Type *Ty, Constant *FieldNo,
+ const Type *DestTy,
+ bool Folded) {
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+ Constant *N = ConstantExpr::getCast(CastInst::getCastOpcode(FieldNo, false,
+ DestTy, false),
+ FieldNo, DestTy);
+ Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
+ return ConstantExpr::getNUWMul(E, N);
+ }
+ if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
+ Constant *N = ConstantExpr::getCast(CastInst::getCastOpcode(FieldNo, false,
+ DestTy, false),
+ FieldNo, DestTy);
+ Constant *E = getFoldedSizeOf(VTy->getElementType(), DestTy, true);
+ return ConstantExpr::getNUWMul(E, N);
+ }
+ if (const StructType *STy = dyn_cast<StructType>(Ty))
+ if (!STy->isPacked()) {
+ unsigned NumElems = STy->getNumElements();
+ // An empty struct has no members.
+ if (NumElems == 0)
+ return 0;
+ // Check for a struct with all members having the same size.
+ Constant *MemberSize =
+ getFoldedSizeOf(STy->getElementType(0), DestTy, true);
+ bool AllSame = true;
+ for (unsigned i = 1; i != NumElems; ++i)
+ if (MemberSize !=
+ getFoldedSizeOf(STy->getElementType(i), DestTy, true)) {
+ AllSame = false;
+ break;
+ }
+ if (AllSame) {
+ Constant *N = ConstantExpr::getCast(CastInst::getCastOpcode(FieldNo,
+ false,
+ DestTy,
+ false),
+ FieldNo, DestTy);
+ return ConstantExpr::getNUWMul(MemberSize, N);
+ }
+ }
+
+ // If there's no interesting folding happening, bail so that we don't create
+ // a constant that looks like it needs folding but really doesn't.
+ if (!Folded)
+ return 0;
+
+ // Base case: Get a regular offsetof expression.
+ Constant *C = ConstantExpr::getOffsetOf(Ty, FieldNo);
+ C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
+ DestTy, false),
+ C, DestTy);
+ return C;
+}
-Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
- unsigned opc, Constant *V,
+Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
const Type *DestTy) {
if (isa<UndefValue>(V)) {
// zext(undef) = 0, because the top bits will be zero.
@@ -394,7 +579,7 @@ Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
DestTy->isFP128Ty() ? APFloat::IEEEquad :
APFloat::Bogus,
APFloat::rmNearestTiesToEven, &ignored);
- return ConstantFP::get(Context, Val);
+ return ConstantFP::get(V->getContext(), Val);
}
return 0; // Can't fold.
case Instruction::FPToUI:
@@ -407,7 +592,7 @@ Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
(void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI,
APFloat::rmTowardZero, &ignored);
APInt Val(DestBitWidth, 2, x);
- return ConstantInt::get(Context, Val);
+ return ConstantInt::get(FPC->getContext(), Val);
}
return 0; // Can't fold.
case Instruction::IntToPtr: //always treated as unsigned
@@ -415,9 +600,49 @@ Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
return ConstantPointerNull::get(cast<PointerType>(DestTy));
return 0; // Other pointer types cannot be casted
case Instruction::PtrToInt: // always treated as unsigned
- if (V->isNullValue()) // is it a null pointer value?
+ // Is it a null pointer value?
+ if (V->isNullValue())
return ConstantInt::get(DestTy, 0);
- return 0; // Other pointer types cannot be casted
+ // If this is a sizeof-like expression, pull out multiplications by
+ // known factors to expose them to subsequent folding. If it's an
+ // alignof-like expression, factor out known factors.
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ if (CE->getOpcode() == Instruction::GetElementPtr &&
+ CE->getOperand(0)->isNullValue()) {
+ const Type *Ty =
+ cast<PointerType>(CE->getOperand(0)->getType())->getElementType();
+ if (CE->getNumOperands() == 2) {
+ // Handle a sizeof-like expression.
+ Constant *Idx = CE->getOperand(1);
+ bool isOne = isa<ConstantInt>(Idx) && cast<ConstantInt>(Idx)->isOne();
+ if (Constant *C = getFoldedSizeOf(Ty, DestTy, !isOne)) {
+ Idx = ConstantExpr::getCast(CastInst::getCastOpcode(Idx, true,
+ DestTy, false),
+ Idx, DestTy);
+ return ConstantExpr::getMul(C, Idx);
+ }
+ } else if (CE->getNumOperands() == 3 &&
+ CE->getOperand(1)->isNullValue()) {
+ // Handle an alignof-like expression.
+ if (const StructType *STy = dyn_cast<StructType>(Ty))
+ if (!STy->isPacked()) {
+ ConstantInt *CI = cast<ConstantInt>(CE->getOperand(2));
+ if (CI->isOne() &&
+ STy->getNumElements() == 2 &&
+ STy->getElementType(0)->isIntegerTy(1)) {
+ return getFoldedAlignOf(STy->getElementType(1), DestTy, false);
+ }
+ }
+ // Handle an offsetof-like expression.
+ if (isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)){
+ if (Constant *C = getFoldedOffsetOf(Ty, CE->getOperand(2),
+ DestTy, false))
+ return C;
+ }
+ }
+ }
+ // Other pointer types cannot be casted
+ return 0;
case Instruction::UIToFP:
case Instruction::SIToFP:
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
@@ -428,7 +653,7 @@ Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
(void)apf.convertFromAPInt(api,
opc==Instruction::SIToFP,
APFloat::rmNearestTiesToEven);
- return ConstantFP::get(Context, apf);
+ return ConstantFP::get(V->getContext(), apf);
}
return 0;
case Instruction::ZExt:
@@ -436,7 +661,7 @@ Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth();
APInt Result(CI->getValue());
Result.zext(BitWidth);
- return ConstantInt::get(Context, Result);
+ return ConstantInt::get(V->getContext(), Result);
}
return 0;
case Instruction::SExt:
@@ -444,7 +669,7 @@ Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth();
APInt Result(CI->getValue());
Result.sext(BitWidth);
- return ConstantInt::get(Context, Result);
+ return ConstantInt::get(V->getContext(), Result);
}
return 0;
case Instruction::Trunc: {
@@ -452,7 +677,7 @@ Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
APInt Result(CI->getValue());
Result.trunc(DestBitWidth);
- return ConstantInt::get(Context, Result);
+ return ConstantInt::get(V->getContext(), Result);
}
// The input must be a constantexpr. See if we can simplify this based on
@@ -466,12 +691,11 @@ Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
return 0;
}
case Instruction::BitCast:
- return FoldBitCast(Context, V, DestTy);
+ return FoldBitCast(V, DestTy);
}
}
-Constant *llvm::ConstantFoldSelectInstruction(LLVMContext&,
- Constant *Cond,
+Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
Constant *V1, Constant *V2) {
if (ConstantInt *CB = dyn_cast<ConstantInt>(Cond))
return CB->getZExtValue() ? V1 : V2;
@@ -483,8 +707,7 @@ Constant *llvm::ConstantFoldSelectInstruction(LLVMContext&,
return 0;
}
-Constant *llvm::ConstantFoldExtractElementInstruction(LLVMContext &Context,
- Constant *Val,
+Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val,
Constant *Idx) {
if (isa<UndefValue>(Val)) // ee(undef, x) -> undef
return UndefValue::get(cast<VectorType>(Val->getType())->getElementType());
@@ -503,8 +726,7 @@ Constant *llvm::ConstantFoldExtractElementInstruction(LLVMContext &Context,
return 0;
}
-Constant *llvm::ConstantFoldInsertElementInstruction(LLVMContext &Context,
- Constant *Val,
+Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val,
Constant *Elt,
Constant *Idx) {
ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx);
@@ -563,8 +785,7 @@ Constant *llvm::ConstantFoldInsertElementInstruction(LLVMContext &Context,
/// GetVectorElement - If C is a ConstantVector, ConstantAggregateZero or Undef
/// return the specified element value. Otherwise return null.
-static Constant *GetVectorElement(LLVMContext &Context, Constant *C,
- unsigned EltNo) {
+static Constant *GetVectorElement(Constant *C, unsigned EltNo) {
if (ConstantVector *CV = dyn_cast<ConstantVector>(C))
return CV->getOperand(EltNo);
@@ -576,8 +797,7 @@ static Constant *GetVectorElement(LLVMContext &Context, Constant *C,
return 0;
}
-Constant *llvm::ConstantFoldShuffleVectorInstruction(LLVMContext &Context,
- Constant *V1,
+Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1,
Constant *V2,
Constant *Mask) {
// Undefined shuffle mask -> undefined value.
@@ -590,7 +810,7 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(LLVMContext &Context,
// Loop over the shuffle mask, evaluating each element.
SmallVector<Constant*, 32> Result;
for (unsigned i = 0; i != MaskNumElts; ++i) {
- Constant *InElt = GetVectorElement(Context, Mask, i);
+ Constant *InElt = GetVectorElement(Mask, i);
if (InElt == 0) return 0;
if (isa<UndefValue>(InElt))
@@ -600,9 +820,9 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(LLVMContext &Context,
if (Elt >= SrcNumElts*2)
InElt = UndefValue::get(EltTy);
else if (Elt >= SrcNumElts)
- InElt = GetVectorElement(Context, V2, Elt - SrcNumElts);
+ InElt = GetVectorElement(V2, Elt - SrcNumElts);
else
- InElt = GetVectorElement(Context, V1, Elt);
+ InElt = GetVectorElement(V1, Elt);
if (InElt == 0) return 0;
} else {
// Unknown value.
@@ -614,8 +834,7 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(LLVMContext &Context,
return ConstantVector::get(&Result[0], Result.size());
}
-Constant *llvm::ConstantFoldExtractValueInstruction(LLVMContext &Context,
- Constant *Agg,
+Constant *llvm::ConstantFoldExtractValueInstruction(Constant *Agg,
const unsigned *Idxs,
unsigned NumIdx) {
// Base case: no indices, so return the entire value.
@@ -635,19 +854,18 @@ Constant *llvm::ConstantFoldExtractValueInstruction(LLVMContext &Context,
// Otherwise recurse.
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(Agg))
- return ConstantFoldExtractValueInstruction(Context, CS->getOperand(*Idxs),
+ return ConstantFoldExtractValueInstruction(CS->getOperand(*Idxs),
Idxs+1, NumIdx-1);
if (ConstantArray *CA = dyn_cast<ConstantArray>(Agg))
- return ConstantFoldExtractValueInstruction(Context, CA->getOperand(*Idxs),
+ return ConstantFoldExtractValueInstruction(CA->getOperand(*Idxs),
Idxs+1, NumIdx-1);
ConstantVector *CV = cast<ConstantVector>(Agg);
- return ConstantFoldExtractValueInstruction(Context, CV->getOperand(*Idxs),
+ return ConstantFoldExtractValueInstruction(CV->getOperand(*Idxs),
Idxs+1, NumIdx-1);
}
-Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context,
- Constant *Agg,
+Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
Constant *Val,
const unsigned *Idxs,
unsigned NumIdx) {
@@ -667,6 +885,8 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context,
unsigned numOps;
if (const ArrayType *AR = dyn_cast<ArrayType>(AggTy))
numOps = AR->getNumElements();
+ else if (isa<UnionType>(AggTy))
+ numOps = 1;
else
numOps = cast<StructType>(AggTy)->getNumElements();
@@ -675,14 +895,18 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context,
const Type *MemberTy = AggTy->getTypeAtIndex(i);
Constant *Op =
(*Idxs == i) ?
- ConstantFoldInsertValueInstruction(Context, UndefValue::get(MemberTy),
+ ConstantFoldInsertValueInstruction(UndefValue::get(MemberTy),
Val, Idxs+1, NumIdx-1) :
UndefValue::get(MemberTy);
Ops[i] = Op;
}
if (const StructType* ST = dyn_cast<StructType>(AggTy))
- return ConstantStruct::get(Context, Ops, ST->isPacked());
+ return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked());
+ if (const UnionType* UT = dyn_cast<UnionType>(AggTy)) {
+ assert(Ops.size() == 1 && "Union can only contain a single value!");
+ return ConstantUnion::get(UT, Ops[0]);
+ }
return ConstantArray::get(cast<ArrayType>(AggTy), Ops);
}
@@ -706,15 +930,14 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context,
const Type *MemberTy = AggTy->getTypeAtIndex(i);
Constant *Op =
(*Idxs == i) ?
- ConstantFoldInsertValueInstruction(Context,
- Constant::getNullValue(MemberTy),
+ ConstantFoldInsertValueInstruction(Constant::getNullValue(MemberTy),
Val, Idxs+1, NumIdx-1) :
Constant::getNullValue(MemberTy);
Ops[i] = Op;
}
- if (const StructType* ST = dyn_cast<StructType>(AggTy))
- return ConstantStruct::get(Context, Ops, ST->isPacked());
+ if (const StructType *ST = dyn_cast<StructType>(AggTy))
+ return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked());
return ConstantArray::get(cast<ArrayType>(AggTy), Ops);
}
@@ -724,13 +947,12 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context,
for (unsigned i = 0; i < Agg->getNumOperands(); ++i) {
Constant *Op = cast<Constant>(Agg->getOperand(i));
if (*Idxs == i)
- Op = ConstantFoldInsertValueInstruction(Context, Op,
- Val, Idxs+1, NumIdx-1);
+ Op = ConstantFoldInsertValueInstruction(Op, Val, Idxs+1, NumIdx-1);
Ops[i] = Op;
}
if (const StructType* ST = dyn_cast<StructType>(Agg->getType()))
- return ConstantStruct::get(Context, Ops, ST->isPacked());
+ return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked());
return ConstantArray::get(cast<ArrayType>(Agg->getType()), Ops);
}
@@ -738,8 +960,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context,
}
-Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context,
- unsigned Opcode,
+Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
Constant *C1, Constant *C2) {
// No compile-time operations on this type yet.
if (C1->getType()->isPPC_FP128Ty())
@@ -896,51 +1117,51 @@ Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context,
default:
break;
case Instruction::Add:
- return ConstantInt::get(Context, C1V + C2V);
+ return ConstantInt::get(CI1->getContext(), C1V + C2V);
case Instruction::Sub:
- return ConstantInt::get(Context, C1V - C2V);
+ return ConstantInt::get(CI1->getContext(), C1V - C2V);
case Instruction::Mul:
- return ConstantInt::get(Context, C1V * C2V);
+ return ConstantInt::get(CI1->getContext(), C1V * C2V);
case Instruction::UDiv:
assert(!CI2->isNullValue() && "Div by zero handled above");
- return ConstantInt::get(Context, C1V.udiv(C2V));
+ return ConstantInt::get(CI1->getContext(), C1V.udiv(C2V));
case Instruction::SDiv:
assert(!CI2->isNullValue() && "Div by zero handled above");
if (C2V.isAllOnesValue() && C1V.isMinSignedValue())
return UndefValue::get(CI1->getType()); // MIN_INT / -1 -> undef
- return ConstantInt::get(Context, C1V.sdiv(C2V));
+ return ConstantInt::get(CI1->getContext(), C1V.sdiv(C2V));
case Instruction::URem:
assert(!CI2->isNullValue() && "Div by zero handled above");
- return ConstantInt::get(Context, C1V.urem(C2V));
+ return ConstantInt::get(CI1->getContext(), C1V.urem(C2V));
case Instruction::SRem:
assert(!CI2->isNullValue() && "Div by zero handled above");
if (C2V.isAllOnesValue() && C1V.isMinSignedValue())
return UndefValue::get(CI1->getType()); // MIN_INT % -1 -> undef
- return ConstantInt::get(Context, C1V.srem(C2V));
+ return ConstantInt::get(CI1->getContext(), C1V.srem(C2V));
case Instruction::And:
- return ConstantInt::get(Context, C1V & C2V);
+ return ConstantInt::get(CI1->getContext(), C1V & C2V);
case Instruction::Or:
- return ConstantInt::get(Context, C1V | C2V);
+ return ConstantInt::get(CI1->getContext(), C1V | C2V);
case Instruction::Xor:
- return ConstantInt::get(Context, C1V ^ C2V);
+ return ConstantInt::get(CI1->getContext(), C1V ^ C2V);
case Instruction::Shl: {
uint32_t shiftAmt = C2V.getZExtValue();
if (shiftAmt < C1V.getBitWidth())
- return ConstantInt::get(Context, C1V.shl(shiftAmt));
+ return ConstantInt::get(CI1->getContext(), C1V.shl(shiftAmt));
else
return UndefValue::get(C1->getType()); // too big shift is undef
}
case Instruction::LShr: {
uint32_t shiftAmt = C2V.getZExtValue();
if (shiftAmt < C1V.getBitWidth())
- return ConstantInt::get(Context, C1V.lshr(shiftAmt));
+ return ConstantInt::get(CI1->getContext(), C1V.lshr(shiftAmt));
else
return UndefValue::get(C1->getType()); // too big shift is undef
}
case Instruction::AShr: {
uint32_t shiftAmt = C2V.getZExtValue();
if (shiftAmt < C1V.getBitWidth())
- return ConstantInt::get(Context, C1V.ashr(shiftAmt));
+ return ConstantInt::get(CI1->getContext(), C1V.ashr(shiftAmt));
else
return UndefValue::get(C1->getType()); // too big shift is undef
}
@@ -970,19 +1191,19 @@ Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context,
break;
case Instruction::FAdd:
(void)C3V.add(C2V, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(Context, C3V);
+ return ConstantFP::get(C1->getContext(), C3V);
case Instruction::FSub:
(void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(Context, C3V);
+ return ConstantFP::get(C1->getContext(), C3V);
case Instruction::FMul:
(void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(Context, C3V);
+ return ConstantFP::get(C1->getContext(), C3V);
case Instruction::FDiv:
(void)C3V.divide(C2V, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(Context, C3V);
+ return ConstantFP::get(C1->getContext(), C3V);
case Instruction::FRem:
(void)C3V.mod(C2V, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(Context, C3V);
+ return ConstantFP::get(C1->getContext(), C3V);
}
}
} else if (const VectorType *VTy = dyn_cast<VectorType>(C1->getType())) {
@@ -1127,10 +1348,19 @@ Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context,
}
}
- if (isa<ConstantExpr>(C1)) {
+ if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
// There are many possible foldings we could do here. We should probably
// at least fold add of a pointer with an integer into the appropriate
// getelementptr. This will improve alias analysis a bit.
+
+ // Given ((a + b) + c), if (b + c) folds to something interesting, return
+ // (a + (b + c)).
+ if (Instruction::isAssociative(Opcode, C1->getType()) &&
+ CE1->getOpcode() == Opcode) {
+ Constant *T = ConstantExpr::get(Opcode, CE1->getOperand(1), C2);
+ if (!isa<ConstantExpr>(T) || cast<ConstantExpr>(T)->getOpcode() != Opcode)
+ return ConstantExpr::get(Opcode, CE1->getOperand(0), T);
+ }
} else if (isa<ConstantExpr>(C2)) {
// If C2 is a constant expr and C1 isn't, flop them around and fold the
// other way if possible.
@@ -1143,7 +1373,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context,
case Instruction::Or:
case Instruction::Xor:
// No change of opcode required.
- return ConstantFoldBinaryInstruction(Context, Opcode, C2, C1);
+ return ConstantFoldBinaryInstruction(Opcode, C2, C1);
case Instruction::Shl:
case Instruction::LShr:
@@ -1162,7 +1392,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context,
}
// i1 can be simplified in many cases.
- if (C1->getType()->isInteger(1)) {
+ if (C1->getType()->isIntegerTy(1)) {
switch (Opcode) {
case Instruction::Add:
case Instruction::Sub:
@@ -1184,7 +1414,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context,
case Instruction::SRem:
// We can assume that C2 == 1. If it were zero the result would be
// undefined through division by zero.
- return ConstantInt::getFalse(Context);
+ return ConstantInt::getFalse(C1->getContext());
default:
break;
}
@@ -1218,8 +1448,7 @@ static bool isMaybeZeroSizedType(const Type *Ty) {
/// first is less than the second, return -1, if the second is less than the
/// first, return 1. If the constants are not integral, return -2.
///
-static int IdxCompare(LLVMContext &Context, Constant *C1, Constant *C2,
- const Type *ElTy) {
+static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) {
if (C1 == C2) return 0;
// Ok, we found a different index. If they are not ConstantInt, we can't do
@@ -1229,11 +1458,11 @@ static int IdxCompare(LLVMContext &Context, Constant *C1, Constant *C2,
// Ok, we have two differing integer indices. Sign extend them to be the same
// type. Long is always big enough, so we use it.
- if (!C1->getType()->isInteger(64))
- C1 = ConstantExpr::getSExt(C1, Type::getInt64Ty(Context));
+ if (!C1->getType()->isIntegerTy(64))
+ C1 = ConstantExpr::getSExt(C1, Type::getInt64Ty(C1->getContext()));
- if (!C2->getType()->isInteger(64))
- C2 = ConstantExpr::getSExt(C2, Type::getInt64Ty(Context));
+ if (!C2->getType()->isIntegerTy(64))
+ C2 = ConstantExpr::getSExt(C2, Type::getInt64Ty(C1->getContext()));
if (C1 == C2) return 0; // They are equal
@@ -1262,8 +1491,7 @@ static int IdxCompare(LLVMContext &Context, Constant *C1, Constant *C2,
/// To simplify this code we canonicalize the relation so that the first
/// operand is always the most "complex" of the two. We consider ConstantFP
/// to be the simplest, and ConstantExprs to be the most complex.
-static FCmpInst::Predicate evaluateFCmpRelation(LLVMContext &Context,
- Constant *V1, Constant *V2) {
+static FCmpInst::Predicate evaluateFCmpRelation(Constant *V1, Constant *V2) {
assert(V1->getType() == V2->getType() &&
"Cannot compare values of different types!");
@@ -1296,7 +1524,7 @@ static FCmpInst::Predicate evaluateFCmpRelation(LLVMContext &Context,
}
// If the first operand is simple and second is ConstantExpr, swap operands.
- FCmpInst::Predicate SwappedRelation = evaluateFCmpRelation(Context, V2, V1);
+ FCmpInst::Predicate SwappedRelation = evaluateFCmpRelation(V2, V1);
if (SwappedRelation != FCmpInst::BAD_FCMP_PREDICATE)
return FCmpInst::getSwappedPredicate(SwappedRelation);
} else {
@@ -1331,16 +1559,16 @@ static FCmpInst::Predicate evaluateFCmpRelation(LLVMContext &Context,
/// constants (like ConstantInt) to be the simplest, followed by
/// GlobalValues, followed by ConstantExpr's (the most complex).
///
-static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context,
- Constant *V1,
- Constant *V2,
+static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
bool isSigned) {
assert(V1->getType() == V2->getType() &&
"Cannot compare different types of values!");
if (V1 == V2) return ICmpInst::ICMP_EQ;
- if (!isa<ConstantExpr>(V1) && !isa<GlobalValue>(V1)) {
- if (!isa<GlobalValue>(V2) && !isa<ConstantExpr>(V2)) {
+ if (!isa<ConstantExpr>(V1) && !isa<GlobalValue>(V1) &&
+ !isa<BlockAddress>(V1)) {
+ if (!isa<GlobalValue>(V2) && !isa<ConstantExpr>(V2) &&
+ !isa<BlockAddress>(V2)) {
// We distilled this down to a simple case, use the standard constant
// folder.
ConstantInt *R = 0;
@@ -1363,36 +1591,63 @@ static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context,
// If the first operand is simple, swap operands.
ICmpInst::Predicate SwappedRelation =
- evaluateICmpRelation(Context, V2, V1, isSigned);
+ evaluateICmpRelation(V2, V1, isSigned);
if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE)
return ICmpInst::getSwappedPredicate(SwappedRelation);
- } else if (const GlobalValue *CPR1 = dyn_cast<GlobalValue>(V1)) {
+ } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(V1)) {
if (isa<ConstantExpr>(V2)) { // Swap as necessary.
ICmpInst::Predicate SwappedRelation =
- evaluateICmpRelation(Context, V2, V1, isSigned);
+ evaluateICmpRelation(V2, V1, isSigned);
if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE)
return ICmpInst::getSwappedPredicate(SwappedRelation);
- else
- return ICmpInst::BAD_ICMP_PREDICATE;
+ return ICmpInst::BAD_ICMP_PREDICATE;
}
- // Now we know that the RHS is a GlobalValue or simple constant,
- // which (since the types must match) means that it's a ConstantPointerNull.
- if (const GlobalValue *CPR2 = dyn_cast<GlobalValue>(V2)) {
+ // Now we know that the RHS is a GlobalValue, BlockAddress or simple
+ // constant (which, since the types must match, means that it's a
+ // ConstantPointerNull).
+ if (const GlobalValue *GV2 = dyn_cast<GlobalValue>(V2)) {
// Don't try to decide equality of aliases.
- if (!isa<GlobalAlias>(CPR1) && !isa<GlobalAlias>(CPR2))
- if (!CPR1->hasExternalWeakLinkage() || !CPR2->hasExternalWeakLinkage())
+ if (!isa<GlobalAlias>(GV) && !isa<GlobalAlias>(GV2))
+ if (!GV->hasExternalWeakLinkage() || !GV2->hasExternalWeakLinkage())
return ICmpInst::ICMP_NE;
+ } else if (isa<BlockAddress>(V2)) {
+ return ICmpInst::ICMP_NE; // Globals never equal labels.
} else {
assert(isa<ConstantPointerNull>(V2) && "Canonicalization guarantee!");
- // GlobalVals can never be null. Don't try to evaluate aliases.
- if (!CPR1->hasExternalWeakLinkage() && !isa<GlobalAlias>(CPR1))
+ // GlobalVals can never be null unless they have external weak linkage.
+ // We don't try to evaluate aliases here.
+ if (!GV->hasExternalWeakLinkage() && !isa<GlobalAlias>(GV))
return ICmpInst::ICMP_NE;
}
+ } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(V1)) {
+ if (isa<ConstantExpr>(V2)) { // Swap as necessary.
+ ICmpInst::Predicate SwappedRelation =
+ evaluateICmpRelation(V2, V1, isSigned);
+ if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE)
+ return ICmpInst::getSwappedPredicate(SwappedRelation);
+ return ICmpInst::BAD_ICMP_PREDICATE;
+ }
+
+ // Now we know that the RHS is a GlobalValue, BlockAddress or simple
+ // constant (which, since the types must match, means that it is a
+ // ConstantPointerNull).
+ if (const BlockAddress *BA2 = dyn_cast<BlockAddress>(V2)) {
+ // Block address in another function can't equal this one, but block
+ // addresses in the current function might be the same if blocks are
+ // empty.
+ if (BA2->getFunction() != BA->getFunction())
+ return ICmpInst::ICMP_NE;
+ } else {
+ // Block addresses aren't null, don't equal the address of globals.
+ assert((isa<ConstantPointerNull>(V2) || isa<GlobalValue>(V2)) &&
+ "Canonicalization guarantee!");
+ return ICmpInst::ICMP_NE;
+ }
} else {
// Ok, the LHS is known to be a constantexpr. The RHS can be any of a
- // constantexpr, a CPR, or a simple constant.
+ // constantexpr, a global, block address, or a simple constant.
ConstantExpr *CE1 = cast<ConstantExpr>(V1);
Constant *CE1Op0 = CE1->getOperand(0);
@@ -1412,10 +1667,10 @@ static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context,
// If the cast is not actually changing bits, and the second operand is a
// null pointer, do the comparison with the pre-casted value.
if (V2->isNullValue() &&
- (isa<PointerType>(CE1->getType()) || CE1->getType()->isInteger())) {
+ (isa<PointerType>(CE1->getType()) || CE1->getType()->isIntegerTy())) {
if (CE1->getOpcode() == Instruction::ZExt) isSigned = false;
if (CE1->getOpcode() == Instruction::SExt) isSigned = true;
- return evaluateICmpRelation(Context, CE1Op0,
+ return evaluateICmpRelation(CE1Op0,
Constant::getNullValue(CE1Op0->getType()),
isSigned);
}
@@ -1447,9 +1702,9 @@ static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context,
return ICmpInst::ICMP_EQ;
}
// Otherwise, we can't really say if the first operand is null or not.
- } else if (const GlobalValue *CPR2 = dyn_cast<GlobalValue>(V2)) {
+ } else if (const GlobalValue *GV2 = dyn_cast<GlobalValue>(V2)) {
if (isa<ConstantPointerNull>(CE1Op0)) {
- if (CPR2->hasExternalWeakLinkage())
+ if (GV2->hasExternalWeakLinkage())
// Weak linkage GVals could be zero or not. We're comparing it to
// a null pointer, so its less-or-equal
return isSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
@@ -1457,8 +1712,8 @@ static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context,
// If its not weak linkage, the GVal must have a non-zero address
// so the result is less-than
return isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
- } else if (const GlobalValue *CPR1 = dyn_cast<GlobalValue>(CE1Op0)) {
- if (CPR1 == CPR2) {
+ } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CE1Op0)) {
+ if (GV == GV2) {
// If this is a getelementptr of the same global, then it must be
// different. Because the types must match, the getelementptr could
// only have at most one index, and because we fold getelementptr's
@@ -1504,7 +1759,7 @@ static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context,
gep_type_iterator GTI = gep_type_begin(CE1);
for (;i != CE1->getNumOperands() && i != CE2->getNumOperands();
++i, ++GTI)
- switch (IdxCompare(Context, CE1->getOperand(i),
+ switch (IdxCompare(CE1->getOperand(i),
CE2->getOperand(i), GTI.getIndexedType())) {
case -1: return isSigned ? ICmpInst::ICMP_SLT:ICmpInst::ICMP_ULT;
case 1: return isSigned ? ICmpInst::ICMP_SGT:ICmpInst::ICMP_UGT;
@@ -1540,14 +1795,14 @@ static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context,
return ICmpInst::BAD_ICMP_PREDICATE;
}
-Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context,
- unsigned short pred,
+Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
Constant *C1, Constant *C2) {
const Type *ResultTy;
if (const VectorType *VT = dyn_cast<VectorType>(C1->getType()))
- ResultTy = VectorType::get(Type::getInt1Ty(Context), VT->getNumElements());
+ ResultTy = VectorType::get(Type::getInt1Ty(C1->getContext()),
+ VT->getNumElements());
else
- ResultTy = Type::getInt1Ty(Context);
+ ResultTy = Type::getInt1Ty(C1->getContext());
// Fold FCMP_FALSE/FCMP_TRUE unconditionally.
if (pred == FCmpInst::FCMP_FALSE)
@@ -1570,9 +1825,9 @@ Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context,
// Don't try to evaluate aliases. External weak GV can be null.
if (!isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage()) {
if (pred == ICmpInst::ICMP_EQ)
- return ConstantInt::getFalse(Context);
+ return ConstantInt::getFalse(C1->getContext());
else if (pred == ICmpInst::ICMP_NE)
- return ConstantInt::getTrue(Context);
+ return ConstantInt::getTrue(C1->getContext());
}
// icmp eq/ne(GV,null) -> false/true
} else if (C2->isNullValue()) {
@@ -1580,14 +1835,14 @@ Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context,
// Don't try to evaluate aliases. External weak GV can be null.
if (!isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage()) {
if (pred == ICmpInst::ICMP_EQ)
- return ConstantInt::getFalse(Context);
+ return ConstantInt::getFalse(C1->getContext());
else if (pred == ICmpInst::ICMP_NE)
- return ConstantInt::getTrue(Context);
+ return ConstantInt::getTrue(C1->getContext());
}
}
// If the comparison is a comparison between two i1's, simplify it.
- if (C1->getType()->isInteger(1)) {
+ if (C1->getType()->isIntegerTy(1)) {
switch(pred) {
case ICmpInst::ICMP_EQ:
if (isa<ConstantInt>(C2))
@@ -1605,26 +1860,16 @@ Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context,
APInt V2 = cast<ConstantInt>(C2)->getValue();
switch (pred) {
default: llvm_unreachable("Invalid ICmp Predicate"); return 0;
- case ICmpInst::ICMP_EQ:
- return ConstantInt::get(Type::getInt1Ty(Context), V1 == V2);
- case ICmpInst::ICMP_NE:
- return ConstantInt::get(Type::getInt1Ty(Context), V1 != V2);
- case ICmpInst::ICMP_SLT:
- return ConstantInt::get(Type::getInt1Ty(Context), V1.slt(V2));
- case ICmpInst::ICMP_SGT:
- return ConstantInt::get(Type::getInt1Ty(Context), V1.sgt(V2));
- case ICmpInst::ICMP_SLE:
- return ConstantInt::get(Type::getInt1Ty(Context), V1.sle(V2));
- case ICmpInst::ICMP_SGE:
- return ConstantInt::get(Type::getInt1Ty(Context), V1.sge(V2));
- case ICmpInst::ICMP_ULT:
- return ConstantInt::get(Type::getInt1Ty(Context), V1.ult(V2));
- case ICmpInst::ICMP_UGT:
- return ConstantInt::get(Type::getInt1Ty(Context), V1.ugt(V2));
- case ICmpInst::ICMP_ULE:
- return ConstantInt::get(Type::getInt1Ty(Context), V1.ule(V2));
- case ICmpInst::ICMP_UGE:
- return ConstantInt::get(Type::getInt1Ty(Context), V1.uge(V2));
+ case ICmpInst::ICMP_EQ: return ConstantInt::get(ResultTy, V1 == V2);
+ case ICmpInst::ICMP_NE: return ConstantInt::get(ResultTy, V1 != V2);
+ case ICmpInst::ICMP_SLT: return ConstantInt::get(ResultTy, V1.slt(V2));
+ case ICmpInst::ICMP_SGT: return ConstantInt::get(ResultTy, V1.sgt(V2));
+ case ICmpInst::ICMP_SLE: return ConstantInt::get(ResultTy, V1.sle(V2));
+ case ICmpInst::ICMP_SGE: return ConstantInt::get(ResultTy, V1.sge(V2));
+ case ICmpInst::ICMP_ULT: return ConstantInt::get(ResultTy, V1.ult(V2));
+ case ICmpInst::ICMP_UGT: return ConstantInt::get(ResultTy, V1.ugt(V2));
+ case ICmpInst::ICMP_ULE: return ConstantInt::get(ResultTy, V1.ule(V2));
+ case ICmpInst::ICMP_UGE: return ConstantInt::get(ResultTy, V1.uge(V2));
}
} else if (isa<ConstantFP>(C1) && isa<ConstantFP>(C2)) {
APFloat C1V = cast<ConstantFP>(C1)->getValueAPF();
@@ -1632,47 +1877,47 @@ Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context,
APFloat::cmpResult R = C1V.compare(C2V);
switch (pred) {
default: llvm_unreachable("Invalid FCmp Predicate"); return 0;
- case FCmpInst::FCMP_FALSE: return ConstantInt::getFalse(Context);
- case FCmpInst::FCMP_TRUE: return ConstantInt::getTrue(Context);
+ case FCmpInst::FCMP_FALSE: return Constant::getNullValue(ResultTy);
+ case FCmpInst::FCMP_TRUE: return Constant::getAllOnesValue(ResultTy);
case FCmpInst::FCMP_UNO:
- return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpUnordered);
+ return ConstantInt::get(ResultTy, R==APFloat::cmpUnordered);
case FCmpInst::FCMP_ORD:
- return ConstantInt::get(Type::getInt1Ty(Context), R!=APFloat::cmpUnordered);
+ return ConstantInt::get(ResultTy, R!=APFloat::cmpUnordered);
case FCmpInst::FCMP_UEQ:
- return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpUnordered ||
- R==APFloat::cmpEqual);
+ return ConstantInt::get(ResultTy, R==APFloat::cmpUnordered ||
+ R==APFloat::cmpEqual);
case FCmpInst::FCMP_OEQ:
- return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpEqual);
+ return ConstantInt::get(ResultTy, R==APFloat::cmpEqual);
case FCmpInst::FCMP_UNE:
- return ConstantInt::get(Type::getInt1Ty(Context), R!=APFloat::cmpEqual);
+ return ConstantInt::get(ResultTy, R!=APFloat::cmpEqual);
case FCmpInst::FCMP_ONE:
- return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpLessThan ||
- R==APFloat::cmpGreaterThan);
+ return ConstantInt::get(ResultTy, R==APFloat::cmpLessThan ||
+ R==APFloat::cmpGreaterThan);
case FCmpInst::FCMP_ULT:
- return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpUnordered ||
- R==APFloat::cmpLessThan);
+ return ConstantInt::get(ResultTy, R==APFloat::cmpUnordered ||
+ R==APFloat::cmpLessThan);
case FCmpInst::FCMP_OLT:
- return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpLessThan);
+ return ConstantInt::get(ResultTy, R==APFloat::cmpLessThan);
case FCmpInst::FCMP_UGT:
- return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpUnordered ||
- R==APFloat::cmpGreaterThan);
+ return ConstantInt::get(ResultTy, R==APFloat::cmpUnordered ||
+ R==APFloat::cmpGreaterThan);
case FCmpInst::FCMP_OGT:
- return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpGreaterThan);
+ return ConstantInt::get(ResultTy, R==APFloat::cmpGreaterThan);
case FCmpInst::FCMP_ULE:
- return ConstantInt::get(Type::getInt1Ty(Context), R!=APFloat::cmpGreaterThan);
+ return ConstantInt::get(ResultTy, R!=APFloat::cmpGreaterThan);
case FCmpInst::FCMP_OLE:
- return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpLessThan ||
- R==APFloat::cmpEqual);
+ return ConstantInt::get(ResultTy, R==APFloat::cmpLessThan ||
+ R==APFloat::cmpEqual);
case FCmpInst::FCMP_UGE:
- return ConstantInt::get(Type::getInt1Ty(Context), R!=APFloat::cmpLessThan);
+ return ConstantInt::get(ResultTy, R!=APFloat::cmpLessThan);
case FCmpInst::FCMP_OGE:
- return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpGreaterThan ||
- R==APFloat::cmpEqual);
+ return ConstantInt::get(ResultTy, R==APFloat::cmpGreaterThan ||
+ R==APFloat::cmpEqual);
}
} else if (isa<VectorType>(C1->getType())) {
SmallVector<Constant*, 16> C1Elts, C2Elts;
- C1->getVectorElements(Context, C1Elts);
- C2->getVectorElements(Context, C2Elts);
+ C1->getVectorElements(C1Elts);
+ C2->getVectorElements(C2Elts);
if (C1Elts.empty() || C2Elts.empty())
return 0;
@@ -1686,9 +1931,9 @@ Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context,
return ConstantVector::get(&ResElts[0], ResElts.size());
}
- if (C1->getType()->isFloatingPoint()) {
+ if (C1->getType()->isFloatingPointTy()) {
int Result = -1; // -1 = unknown, 0 = known false, 1 = known true.
- switch (evaluateFCmpRelation(Context, C1, C2)) {
+ switch (evaluateFCmpRelation(C1, C2)) {
default: llvm_unreachable("Unknown relation!");
case FCmpInst::FCMP_UNO:
case FCmpInst::FCMP_ORD:
@@ -1742,12 +1987,12 @@ Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context,
// If we evaluated the result, return it now.
if (Result != -1)
- return ConstantInt::get(Type::getInt1Ty(Context), Result);
+ return ConstantInt::get(ResultTy, Result);
} else {
// Evaluate the relation between the two constants, per the predicate.
int Result = -1; // -1 = unknown, 0 = known false, 1 = known true.
- switch (evaluateICmpRelation(Context, C1, C2, CmpInst::isSigned(pred))) {
+ switch (evaluateICmpRelation(C1, C2, CmpInst::isSigned(pred))) {
default: llvm_unreachable("Unknown relational!");
case ICmpInst::BAD_ICMP_PREDICATE:
break; // Couldn't determine anything about these constants.
@@ -1812,13 +2057,15 @@ Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context,
// If we evaluated the result, return it now.
if (Result != -1)
- return ConstantInt::get(Type::getInt1Ty(Context), Result);
+ return ConstantInt::get(ResultTy, Result);
// If the right hand side is a bitcast, try using its inverse to simplify
- // it by moving it to the left hand side.
+ // it by moving it to the left hand side. We can't do this if it would turn
+ // a vector compare into a scalar compare or visa versa.
if (ConstantExpr *CE2 = dyn_cast<ConstantExpr>(C2)) {
- if (CE2->getOpcode() == Instruction::BitCast) {
- Constant *CE2Op0 = CE2->getOperand(0);
+ Constant *CE2Op0 = CE2->getOperand(0);
+ if (CE2->getOpcode() == Instruction::BitCast &&
+ isa<VectorType>(CE2->getType())==isa<VectorType>(CE2Op0->getType())) {
Constant *Inverse = ConstantExpr::getBitCast(C1, CE2Op0->getType());
return ConstantExpr::getICmp(pred, Inverse, CE2Op0);
}
@@ -1890,8 +2137,7 @@ static bool isInBoundsIndices(Constant *const *Idxs, size_t NumIdx) {
return true;
}
-Constant *llvm::ConstantFoldGetElementPtr(LLVMContext &Context,
- Constant *C,
+Constant *llvm::ConstantFoldGetElementPtr(Constant *C,
bool inBounds,
Constant* const *Idxs,
unsigned NumIdx) {
@@ -1951,10 +2197,9 @@ Constant *llvm::ConstantFoldGetElementPtr(LLVMContext &Context,
if (!Idx0->isNullValue()) {
const Type *IdxTy = Combined->getType();
if (IdxTy != Idx0->getType()) {
- Constant *C1 =
- ConstantExpr::getSExtOrBitCast(Idx0, Type::getInt64Ty(Context));
- Constant *C2 = ConstantExpr::getSExtOrBitCast(Combined,
- Type::getInt64Ty(Context));
+ const Type *Int64Ty = Type::getInt64Ty(IdxTy->getContext());
+ Constant *C1 = ConstantExpr::getSExtOrBitCast(Idx0, Int64Ty);
+ Constant *C2 = ConstantExpr::getSExtOrBitCast(Combined, Int64Ty);
Combined = ConstantExpr::get(Instruction::Add, C1, C2);
} else {
Combined =
@@ -1975,7 +2220,7 @@ Constant *llvm::ConstantFoldGetElementPtr(LLVMContext &Context,
}
// Implement folding of:
- // int* getelementptr ([2 x int]* cast ([3 x int]* %X to [2 x int]*),
+ // int* getelementptr ([2 x int]* bitcast ([3 x int]* %X to [2 x int]*),
// long 0, long 0)
// To: int* getelementptr ([3 x int]* %X, long 0, long 0)
//
@@ -1992,28 +2237,6 @@ Constant *llvm::ConstantFoldGetElementPtr(LLVMContext &Context,
ConstantExpr::getGetElementPtr(
(Constant*)CE->getOperand(0), Idxs, NumIdx);
}
-
- // Fold: getelementptr (i8* inttoptr (i64 1 to i8*), i32 -1)
- // Into: inttoptr (i64 0 to i8*)
- // This happens with pointers to member functions in C++.
- if (CE->getOpcode() == Instruction::IntToPtr && NumIdx == 1 &&
- isa<ConstantInt>(CE->getOperand(0)) && isa<ConstantInt>(Idxs[0]) &&
- cast<PointerType>(CE->getType())->getElementType() ==
- Type::getInt8Ty(Context)) {
- Constant *Base = CE->getOperand(0);
- Constant *Offset = Idxs[0];
-
- // Convert the smaller integer to the larger type.
- if (Offset->getType()->getPrimitiveSizeInBits() <
- Base->getType()->getPrimitiveSizeInBits())
- Offset = ConstantExpr::getSExt(Offset, Base->getType());
- else if (Base->getType()->getPrimitiveSizeInBits() <
- Offset->getType()->getPrimitiveSizeInBits())
- Base = ConstantExpr::getZExt(Base, Offset->getType());
-
- Base = ConstantExpr::getAdd(Base, Offset);
- return ConstantExpr::getIntToPtr(Base, CE->getType());
- }
}
// Check to see if any array indices are not within the corresponding
@@ -2043,12 +2266,12 @@ Constant *llvm::ConstantFoldGetElementPtr(LLVMContext &Context,
// Before adding, extend both operands to i64 to avoid
// overflow trouble.
- if (!PrevIdx->getType()->isInteger(64))
+ if (!PrevIdx->getType()->isIntegerTy(64))
PrevIdx = ConstantExpr::getSExt(PrevIdx,
- Type::getInt64Ty(Context));
- if (!Div->getType()->isInteger(64))
+ Type::getInt64Ty(Div->getContext()));
+ if (!Div->getType()->isIntegerTy(64))
Div = ConstantExpr::getSExt(Div,
- Type::getInt64Ty(Context));
+ Type::getInt64Ty(Div->getContext()));
NewIdxs[i-1] = ConstantExpr::getAdd(PrevIdx, Div);
} else {
diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h
index cc97001..d2dbbdd 100644
--- a/lib/VMCore/ConstantFold.h
+++ b/lib/VMCore/ConstantFold.h
@@ -23,46 +23,31 @@ namespace llvm {
class Value;
class Constant;
class Type;
- class LLVMContext;
// Constant fold various types of instruction...
Constant *ConstantFoldCastInstruction(
- LLVMContext &Context,
unsigned opcode, ///< The opcode of the cast
Constant *V, ///< The source constant
const Type *DestTy ///< The destination type
);
- Constant *ConstantFoldSelectInstruction(LLVMContext &Context,
- Constant *Cond,
+ Constant *ConstantFoldSelectInstruction(Constant *Cond,
Constant *V1, Constant *V2);
- Constant *ConstantFoldExtractElementInstruction(LLVMContext &Context,
- Constant *Val,
- Constant *Idx);
- Constant *ConstantFoldInsertElementInstruction(LLVMContext &Context,
- Constant *Val,
- Constant *Elt,
+ Constant *ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx);
+ Constant *ConstantFoldInsertElementInstruction(Constant *Val, Constant *Elt,
Constant *Idx);
- Constant *ConstantFoldShuffleVectorInstruction(LLVMContext &Context,
- Constant *V1,
- Constant *V2,
+ Constant *ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2,
Constant *Mask);
- Constant *ConstantFoldExtractValueInstruction(LLVMContext &Context,
- Constant *Agg,
+ Constant *ConstantFoldExtractValueInstruction(Constant *Agg,
const unsigned *Idxs,
unsigned NumIdx);
- Constant *ConstantFoldInsertValueInstruction(LLVMContext &Context,
- Constant *Agg,
- Constant *Val,
+ Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
const unsigned *Idxs,
unsigned NumIdx);
- Constant *ConstantFoldBinaryInstruction(LLVMContext &Context,
- unsigned Opcode, Constant *V1,
+ Constant *ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1,
Constant *V2);
- Constant *ConstantFoldCompareInstruction(LLVMContext &Context,
- unsigned short predicate,
+ Constant *ConstantFoldCompareInstruction(unsigned short predicate,
Constant *C1, Constant *C2);
- Constant *ConstantFoldGetElementPtr(LLVMContext &Context, Constant *C,
- bool inBounds,
+ Constant *ConstantFoldGetElementPtr(Constant *C, bool inBounds,
Constant* const *Idxs, unsigned NumIdx);
} // End llvm namespace
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 916aac6..98040ea 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -228,8 +228,7 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
/// type, returns the elements of the vector in the specified smallvector.
/// This handles breaking down a vector undef into undef elements, etc. For
/// constant exprs and other cases we can't handle, we return an empty vector.
-void Constant::getVectorElements(LLVMContext &Context,
- SmallVectorImpl<Constant*> &Elts) const {
+void Constant::getVectorElements(SmallVectorImpl<Constant*> &Elts) const {
assert(isa<VectorType>(getType()) && "Not a vector constant!");
if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) {
@@ -405,13 +404,13 @@ ConstantFP* ConstantFP::getNegativeZero(const Type* Ty) {
Constant* ConstantFP::getZeroValueForNegation(const Type* Ty) {
if (const VectorType *PTy = dyn_cast<VectorType>(Ty))
- if (PTy->getElementType()->isFloatingPoint()) {
+ if (PTy->getElementType()->isFloatingPointTy()) {
std::vector<Constant*> zeros(PTy->getNumElements(),
getNegativeZero(PTy->getElementType()));
return ConstantVector::get(PTy, zeros);
}
- if (Ty->isFloatingPoint())
+ if (Ty->isFloatingPointTy())
return getNegativeZero(Ty);
return Constant::getNullValue(Ty);
@@ -586,6 +585,27 @@ Constant* ConstantStruct::get(LLVMContext &Context,
return get(Context, std::vector<Constant*>(Vals, Vals+NumVals), Packed);
}
+ConstantUnion::ConstantUnion(const UnionType *T, Constant* V)
+ : Constant(T, ConstantUnionVal,
+ OperandTraits<ConstantUnion>::op_end(this) - 1, 1) {
+ Use *OL = OperandList;
+ assert(T->getElementTypeIndex(V->getType()) >= 0 &&
+ "Initializer for union element isn't a member of union type!");
+ *OL = V;
+}
+
+// ConstantUnion accessors.
+Constant* ConstantUnion::get(const UnionType* T, Constant* V) {
+ LLVMContextImpl* pImpl = T->getContext().pImpl;
+
+ // Create a ConstantAggregateZero value if all elements are zeros...
+ if (!V->isNullValue())
+ return pImpl->UnionConstants.getOrCreate(T, V);
+
+ return ConstantAggregateZero::get(T);
+}
+
+
ConstantVector::ConstantVector(const VectorType *T,
const std::vector<Constant*> &V)
: Constant(T, ConstantVectorVal,
@@ -641,26 +661,47 @@ Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) {
}
Constant* ConstantExpr::getNSWNeg(Constant* C) {
- assert(C->getType()->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NEG a nonintegral value!");
return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
}
+Constant* ConstantExpr::getNUWNeg(Constant* C) {
+ assert(C->getType()->isIntOrIntVectorTy() &&
+ "Cannot NEG a nonintegral value!");
+ return getNUWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
+}
+
Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
return getTy(C1->getType(), Instruction::Add, C1, C2,
OverflowingBinaryOperator::NoSignedWrap);
}
+Constant* ConstantExpr::getNUWAdd(Constant* C1, Constant* C2) {
+ return getTy(C1->getType(), Instruction::Add, C1, C2,
+ OverflowingBinaryOperator::NoUnsignedWrap);
+}
+
Constant* ConstantExpr::getNSWSub(Constant* C1, Constant* C2) {
return getTy(C1->getType(), Instruction::Sub, C1, C2,
OverflowingBinaryOperator::NoSignedWrap);
}
+Constant* ConstantExpr::getNUWSub(Constant* C1, Constant* C2) {
+ return getTy(C1->getType(), Instruction::Sub, C1, C2,
+ OverflowingBinaryOperator::NoUnsignedWrap);
+}
+
Constant* ConstantExpr::getNSWMul(Constant* C1, Constant* C2) {
return getTy(C1->getType(), Instruction::Mul, C1, C2,
OverflowingBinaryOperator::NoSignedWrap);
}
+Constant* ConstantExpr::getNUWMul(Constant* C1, Constant* C2) {
+ return getTy(C1->getType(), Instruction::Mul, C1, C2,
+ OverflowingBinaryOperator::NoUnsignedWrap);
+}
+
Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
return getTy(C1->getType(), Instruction::SDiv, C1, C2,
SDivOperator::IsExact);
@@ -928,7 +969,7 @@ void ConstantArray::destroyConstant() {
/// if the elements of the array are all ConstantInt's.
bool ConstantArray::isString() const {
// Check the element type for i8...
- if (!getType()->getElementType()->isInteger(8))
+ if (!getType()->getElementType()->isIntegerTy(8))
return false;
// Check the elements to make sure they are all integers, not constant
// expressions.
@@ -943,7 +984,7 @@ bool ConstantArray::isString() const {
/// null bytes except its terminator.
bool ConstantArray::isCString() const {
// Check the element type for i8...
- if (!getType()->getElementType()->isInteger(8))
+ if (!getType()->getElementType()->isIntegerTy(8))
return false;
// Last element must be a null.
@@ -990,6 +1031,13 @@ void ConstantStruct::destroyConstant() {
// destroyConstant - Remove the constant from the constant table...
//
+void ConstantUnion::destroyConstant() {
+ getType()->getContext().pImpl->UnionConstants.remove(this);
+ destroyConstantImpl();
+}
+
+// destroyConstant - Remove the constant from the constant table...
+//
void ConstantVector::destroyConstant() {
getType()->getContext().pImpl->VectorConstants.remove(this);
destroyConstantImpl();
@@ -1134,7 +1182,7 @@ static inline Constant *getFoldedCast(
Instruction::CastOps opc, Constant *C, const Type *Ty) {
assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!");
// Fold a few common cases
- if (Constant *FC = ConstantFoldCastInstruction(Ty->getContext(), opc, C, Ty))
+ if (Constant *FC = ConstantFoldCastInstruction(opc, C, Ty))
return FC;
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
@@ -1150,24 +1198,24 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) {
Instruction::CastOps opc = Instruction::CastOps(oc);
assert(Instruction::isCast(opc) && "opcode out of range");
assert(C && Ty && "Null arguments to getCast");
- assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!");
+ assert(CastInst::castIsValid(opc, C, Ty) && "Invalid constantexpr cast!");
switch (opc) {
- default:
- llvm_unreachable("Invalid cast opcode");
- break;
- case Instruction::Trunc: return getTrunc(C, Ty);
- case Instruction::ZExt: return getZExt(C, Ty);
- case Instruction::SExt: return getSExt(C, Ty);
- case Instruction::FPTrunc: return getFPTrunc(C, Ty);
- case Instruction::FPExt: return getFPExtend(C, Ty);
- case Instruction::UIToFP: return getUIToFP(C, Ty);
- case Instruction::SIToFP: return getSIToFP(C, Ty);
- case Instruction::FPToUI: return getFPToUI(C, Ty);
- case Instruction::FPToSI: return getFPToSI(C, Ty);
- case Instruction::PtrToInt: return getPtrToInt(C, Ty);
- case Instruction::IntToPtr: return getIntToPtr(C, Ty);
- case Instruction::BitCast: return getBitCast(C, Ty);
+ default:
+ llvm_unreachable("Invalid cast opcode");
+ break;
+ case Instruction::Trunc: return getTrunc(C, Ty);
+ case Instruction::ZExt: return getZExt(C, Ty);
+ case Instruction::SExt: return getSExt(C, Ty);
+ case Instruction::FPTrunc: return getFPTrunc(C, Ty);
+ case Instruction::FPExt: return getFPExtend(C, Ty);
+ case Instruction::UIToFP: return getUIToFP(C, Ty);
+ case Instruction::SIToFP: return getSIToFP(C, Ty);
+ case Instruction::FPToUI: return getFPToUI(C, Ty);
+ case Instruction::FPToSI: return getFPToSI(C, Ty);
+ case Instruction::PtrToInt: return getPtrToInt(C, Ty);
+ case Instruction::IntToPtr: return getIntToPtr(C, Ty);
+ case Instruction::BitCast: return getBitCast(C, Ty);
}
return 0;
}
@@ -1192,17 +1240,17 @@ Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
assert(isa<PointerType>(S->getType()) && "Invalid cast");
- assert((Ty->isInteger() || isa<PointerType>(Ty)) && "Invalid cast");
+ assert((Ty->isIntegerTy() || isa<PointerType>(Ty)) && "Invalid cast");
- if (Ty->isInteger())
+ if (Ty->isIntegerTy())
return getCast(Instruction::PtrToInt, S, Ty);
return getCast(Instruction::BitCast, S, Ty);
}
Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
bool isSigned) {
- assert(C->getType()->isIntOrIntVector() &&
- Ty->isIntOrIntVector() && "Invalid cast");
+ assert(C->getType()->isIntOrIntVectorTy() &&
+ Ty->isIntOrIntVectorTy() && "Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
@@ -1213,7 +1261,7 @@ Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
}
Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) {
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
"Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
@@ -1230,8 +1278,8 @@ Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && "Trunc operand must be integer");
- assert(Ty->isIntOrIntVector() && "Trunc produces only integral");
+ assert(C->getType()->isIntOrIntVectorTy() && "Trunc operand must be integer");
+ assert(Ty->isIntOrIntVectorTy() && "Trunc produces only integral");
assert(C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
"SrcTy must be larger than DestTy for Trunc!");
@@ -1244,8 +1292,8 @@ Constant *ConstantExpr::getSExt(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && "SExt operand must be integral");
- assert(Ty->isIntOrIntVector() && "SExt produces only integer");
+ assert(C->getType()->isIntOrIntVectorTy() && "SExt operand must be integral");
+ assert(Ty->isIntOrIntVectorTy() && "SExt produces only integer");
assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"SrcTy must be smaller than DestTy for SExt!");
@@ -1258,8 +1306,8 @@ Constant *ConstantExpr::getZExt(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && "ZEXt operand must be integral");
- assert(Ty->isIntOrIntVector() && "ZExt produces only integer");
+ assert(C->getType()->isIntOrIntVectorTy() && "ZEXt operand must be integral");
+ assert(Ty->isIntOrIntVectorTy() && "ZExt produces only integer");
assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"SrcTy must be smaller than DestTy for ZExt!");
@@ -1272,7 +1320,7 @@ Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
"This is an illegal floating point truncation!");
return getFoldedCast(Instruction::FPTrunc, C, Ty);
@@ -1284,7 +1332,7 @@ Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"This is an illegal floating point extension!");
return getFoldedCast(Instruction::FPExt, C, Ty);
@@ -1296,7 +1344,7 @@ Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() &&
"This is an illegal uint to floating point cast!");
return getFoldedCast(Instruction::UIToFP, C, Ty);
}
@@ -1307,7 +1355,7 @@ Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() &&
"This is an illegal sint to floating point cast!");
return getFoldedCast(Instruction::SIToFP, C, Ty);
}
@@ -1318,7 +1366,7 @@ Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() &&
"This is an illegal floating point to uint cast!");
return getFoldedCast(Instruction::FPToUI, C, Ty);
}
@@ -1329,38 +1377,26 @@ Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty) {
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() &&
"This is an illegal floating point to sint cast!");
return getFoldedCast(Instruction::FPToSI, C, Ty);
}
Constant *ConstantExpr::getPtrToInt(Constant *C, const Type *DstTy) {
assert(isa<PointerType>(C->getType()) && "PtrToInt source must be pointer");
- assert(DstTy->isInteger() && "PtrToInt destination must be integral");
+ assert(DstTy->isIntegerTy() && "PtrToInt destination must be integral");
return getFoldedCast(Instruction::PtrToInt, C, DstTy);
}
Constant *ConstantExpr::getIntToPtr(Constant *C, const Type *DstTy) {
- assert(C->getType()->isInteger() && "IntToPtr source must be integral");
+ assert(C->getType()->isIntegerTy() && "IntToPtr source must be integral");
assert(isa<PointerType>(DstTy) && "IntToPtr destination must be a pointer");
return getFoldedCast(Instruction::IntToPtr, C, DstTy);
}
Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
- // BitCast implies a no-op cast of type only. No bits change. However, you
- // can't cast pointers to anything but pointers.
-#ifndef NDEBUG
- const Type *SrcTy = C->getType();
- assert((isa<PointerType>(SrcTy) == isa<PointerType>(DstTy)) &&
- "BitCast cannot cast pointer to non-pointer and vice versa");
-
- // Now we know we're not dealing with mismatched pointer casts (ptr->nonptr
- // or nonptr->ptr). For all the other types, the cast is okay if source and
- // destination bit widths are identical.
- unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
- unsigned DstBitSize = DstTy->getPrimitiveSizeInBits();
-#endif
- assert(SrcBitSize == DstBitSize && "BitCast requires types of same width");
+ assert(CastInst::castIsValid(Instruction::BitCast, C, DstTy) &&
+ "Invalid constantexpr bitcast!");
// It is common to ask for a bitcast of a value to its own type, handle this
// speedily.
@@ -1380,8 +1416,7 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
"Operand types in binary constant expression should match");
if (ReqTy == C1->getType() || ReqTy == Type::getInt1Ty(ReqTy->getContext()))
- if (Constant *FC = ConstantFoldBinaryInstruction(ReqTy->getContext(),
- Opcode, C1, C2))
+ if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2))
return FC; // Fold a few common cases...
std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
@@ -1414,7 +1449,7 @@ Constant *ConstantExpr::getCompareTy(unsigned short predicate,
Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
unsigned Flags) {
// API compatibility: Adjust integer opcodes to floating-point opcodes.
- if (C1->getType()->isFPOrFPVector()) {
+ if (C1->getType()->isFPOrFPVectorTy()) {
if (Opcode == Instruction::Add) Opcode = Instruction::FAdd;
else if (Opcode == Instruction::Sub) Opcode = Instruction::FSub;
else if (Opcode == Instruction::Mul) Opcode = Instruction::FMul;
@@ -1425,51 +1460,51 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
case Instruction::Sub:
case Instruction::Mul:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create an integer operation on a non-integer type!");
break;
case Instruction::FAdd:
case Instruction::FSub:
case Instruction::FMul:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isFPOrFPVector() &&
+ assert(C1->getType()->isFPOrFPVectorTy() &&
"Tried to create a floating-point operation on a "
"non-floating-point type!");
break;
case Instruction::UDiv:
case Instruction::SDiv:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::FDiv:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isFPOrFPVector() &&
+ assert(C1->getType()->isFPOrFPVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::URem:
case Instruction::SRem:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::FRem:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isFPOrFPVector() &&
+ assert(C1->getType()->isFPOrFPVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create a logical operation on a non-integral type!");
break;
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create a shift operation on a non-integer type!");
break;
default:
@@ -1491,30 +1526,35 @@ Constant* ConstantExpr::getSizeOf(const Type* Ty) {
}
Constant* ConstantExpr::getAlignOf(const Type* Ty) {
- // alignof is implemented as: (i64) gep ({i8,Ty}*)null, 0, 1
+ // alignof is implemented as: (i64) gep ({i1,Ty}*)null, 0, 1
// Note that a non-inbounds gep is used, as null isn't within any object.
const Type *AligningTy = StructType::get(Ty->getContext(),
- Type::getInt8Ty(Ty->getContext()), Ty, NULL);
+ Type::getInt1Ty(Ty->getContext()), Ty, NULL);
Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo());
- Constant *Zero = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 0);
+ Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0);
Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *Indices[2] = { Zero, One };
Constant *GEP = getGetElementPtr(NullPtr, Indices, 2);
return getCast(Instruction::PtrToInt, GEP,
- Type::getInt32Ty(Ty->getContext()));
+ Type::getInt64Ty(Ty->getContext()));
}
Constant* ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) {
+ return getOffsetOf(STy, ConstantInt::get(Type::getInt32Ty(STy->getContext()),
+ FieldNo));
+}
+
+Constant* ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) {
// offsetof is implemented as: (i64) gep (Ty*)null, 0, FieldNo
// Note that a non-inbounds gep is used, as null isn't within any object.
Constant *GEPIdx[] = {
- ConstantInt::get(Type::getInt64Ty(STy->getContext()), 0),
- ConstantInt::get(Type::getInt32Ty(STy->getContext()), FieldNo)
+ ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0),
+ FieldNo
};
Constant *GEP = getGetElementPtr(
- Constant::getNullValue(PointerType::getUnqual(STy)), GEPIdx, 2);
+ Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx, 2);
return getCast(Instruction::PtrToInt, GEP,
- Type::getInt64Ty(STy->getContext()));
+ Type::getInt64Ty(Ty->getContext()));
}
Constant *ConstantExpr::getCompare(unsigned short pred,
@@ -1528,8 +1568,7 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
assert(!SelectInst::areInvalidOperands(C, V1, V2)&&"Invalid select operands");
if (ReqTy == V1->getType())
- if (Constant *SC = ConstantFoldSelectInstruction(
- ReqTy->getContext(), C, V1, V2))
+ if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2))
return SC; // Fold common cases
std::vector<Constant*> argVec(3, C);
@@ -1549,9 +1588,8 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
cast<PointerType>(ReqTy)->getElementType() &&
"GEP indices invalid!");
- if (Constant *FC = ConstantFoldGetElementPtr(
- ReqTy->getContext(), C, /*inBounds=*/false,
- (Constant**)Idxs, NumIdx))
+ if (Constant *FC = ConstantFoldGetElementPtr(C, /*inBounds=*/false,
+ (Constant**)Idxs, NumIdx))
return FC; // Fold a few common cases...
assert(isa<PointerType>(C->getType()) &&
@@ -1577,9 +1615,8 @@ Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy,
cast<PointerType>(ReqTy)->getElementType() &&
"GEP indices invalid!");
- if (Constant *FC = ConstantFoldGetElementPtr(
- ReqTy->getContext(), C, /*inBounds=*/true,
- (Constant**)Idxs, NumIdx))
+ if (Constant *FC = ConstantFoldGetElementPtr(C, /*inBounds=*/true,
+ (Constant**)Idxs, NumIdx))
return FC; // Fold a few common cases...
assert(isa<PointerType>(C->getType()) &&
@@ -1635,8 +1672,7 @@ ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) {
assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE &&
pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate");
- if (Constant *FC = ConstantFoldCompareInstruction(
- LHS->getContext(), pred, LHS, RHS))
+ if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS))
return FC; // Fold a few common cases...
// Look up the constant in the table first to ensure uniqueness
@@ -1659,8 +1695,7 @@ ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) {
assert(LHS->getType() == RHS->getType());
assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate");
- if (Constant *FC = ConstantFoldCompareInstruction(
- LHS->getContext(), pred, LHS, RHS))
+ if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS))
return FC; // Fold a few common cases...
// Look up the constant in the table first to ensure uniqueness
@@ -1680,8 +1715,7 @@ ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) {
Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
Constant *Idx) {
- if (Constant *FC = ConstantFoldExtractElementInstruction(
- ReqTy->getContext(), Val, Idx))
+ if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
return FC; // Fold a few common cases.
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec(1, Val);
@@ -1695,7 +1729,7 @@ Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) {
assert(isa<VectorType>(Val->getType()) &&
"Tried to create extractelement operation on non-vector type!");
- assert(Idx->getType()->isInteger(32) &&
+ assert(Idx->getType()->isIntegerTy(32) &&
"Extractelement index must be i32 type!");
return getExtractElementTy(cast<VectorType>(Val->getType())->getElementType(),
Val, Idx);
@@ -1703,8 +1737,7 @@ Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) {
Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val,
Constant *Elt, Constant *Idx) {
- if (Constant *FC = ConstantFoldInsertElementInstruction(
- ReqTy->getContext(), Val, Elt, Idx))
+ if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx))
return FC; // Fold a few common cases.
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec(1, Val);
@@ -1722,15 +1755,14 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
"Tried to create insertelement operation on non-vector type!");
assert(Elt->getType() == cast<VectorType>(Val->getType())->getElementType()
&& "Insertelement types must match!");
- assert(Idx->getType()->isInteger(32) &&
+ assert(Idx->getType()->isIntegerTy(32) &&
"Insertelement index must be i32 type!");
return getInsertElementTy(Val->getType(), Val, Elt, Idx);
}
Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1,
Constant *V2, Constant *Mask) {
- if (Constant *FC = ConstantFoldShuffleVectorInstruction(
- ReqTy->getContext(), V1, V2, Mask))
+ if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask))
return FC; // Fold a few common cases...
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec(1, V1);
@@ -1763,8 +1795,7 @@ Constant *ConstantExpr::getInsertValueTy(const Type *ReqTy, Constant *Agg,
"insertvalue type invalid!");
assert(Agg->getType()->isFirstClassType() &&
"Non-first-class type for constant InsertValue expression");
- Constant *FC = ConstantFoldInsertValueInstruction(
- ReqTy->getContext(), Agg, Val, Idxs, NumIdx);
+ Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx);
assert(FC && "InsertValue constant expr couldn't be folded!");
return FC;
}
@@ -1790,8 +1821,7 @@ Constant *ConstantExpr::getExtractValueTy(const Type *ReqTy, Constant *Agg,
"extractvalue indices invalid!");
assert(Agg->getType()->isFirstClassType() &&
"Non-first-class type for constant extractvalue expression");
- Constant *FC = ConstantFoldExtractValueInstruction(
- ReqTy->getContext(), Agg, Idxs, NumIdx);
+ Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx);
assert(FC && "ExtractValue constant expr couldn't be folded!");
return FC;
}
@@ -1809,9 +1839,9 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg,
Constant* ConstantExpr::getNeg(Constant* C) {
// API compatibility: Adjust integer opcodes to floating-point opcodes.
- if (C->getType()->isFPOrFPVector())
+ if (C->getType()->isFPOrFPVectorTy())
return getFNeg(C);
- assert(C->getType()->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NEG a nonintegral value!");
return get(Instruction::Sub,
ConstantFP::getZeroValueForNegation(C->getType()),
@@ -1819,7 +1849,7 @@ Constant* ConstantExpr::getNeg(Constant* C) {
}
Constant* ConstantExpr::getFNeg(Constant* C) {
- assert(C->getType()->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() &&
"Cannot FNEG a non-floating-point value!");
return get(Instruction::FSub,
ConstantFP::getZeroValueForNegation(C->getType()),
@@ -1827,7 +1857,7 @@ Constant* ConstantExpr::getFNeg(Constant* C) {
}
Constant* ConstantExpr::getNot(Constant* C) {
- assert(C->getType()->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NOT a nonintegral value!");
return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType()));
}
@@ -2081,6 +2111,11 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
destroyConstant();
}
+void ConstantUnion::replaceUsesOfWithOnConstant(Value *From, Value *To,
+ Use *U) {
+ assert(false && "Implement replaceUsesOfWithOnConstant for unions");
+}
+
void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h
index 08224e4..c798ba2 100644
--- a/lib/VMCore/ConstantsContext.h
+++ b/lib/VMCore/ConstantsContext.h
@@ -341,6 +341,13 @@ struct ConstantTraits< std::vector<T, Alloc> > {
}
};
+template<>
+struct ConstantTraits<Constant *> {
+ static unsigned uses(Constant * const & v) {
+ return 1;
+ }
+};
+
template<class ConstantClass, class TypeClass, class ValType>
struct ConstantCreator {
static ConstantClass *create(const TypeClass *Ty, const ValType &V) {
@@ -470,6 +477,14 @@ struct ConstantKeyData<ConstantStruct> {
}
};
+template<>
+struct ConstantKeyData<ConstantUnion> {
+ typedef Constant* ValType;
+ static ValType getValType(ConstantUnion *CU) {
+ return cast<Constant>(CU->getOperand(0));
+ }
+};
+
// ConstantPointerNull does not take extra "value" argument...
template<class ValType>
struct ConstantCreator<ConstantPointerNull, PointerType, ValType> {
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index 984d245..a044fc5 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -20,12 +20,13 @@
#include "llvm/GlobalAlias.h"
#include "llvm/LLVMContext.h"
#include "llvm/TypeSymbolTable.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/InlineAsm.h"
#include "llvm/IntrinsicInst.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdlib>
#include <cstring>
@@ -140,6 +141,8 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) {
return LLVMFunctionTypeKind;
case Type::StructTyID:
return LLVMStructTypeKind;
+ case Type::UnionTyID:
+ return LLVMUnionTypeKind;
case Type::ArrayTyID:
return LLVMArrayTypeKind;
case Type::PointerTyID:
@@ -298,6 +301,35 @@ LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy) {
return unwrap<StructType>(StructTy)->isPacked();
}
+/*--.. Operations on union types ..........................................--*/
+
+LLVMTypeRef LLVMUnionTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
+ unsigned ElementCount) {
+ SmallVector<const Type*, 8> Tys;
+ for (LLVMTypeRef *I = ElementTypes,
+ *E = ElementTypes + ElementCount; I != E; ++I)
+ Tys.push_back(unwrap(*I));
+
+ return wrap(UnionType::get(&Tys[0], Tys.size()));
+}
+
+LLVMTypeRef LLVMUnionType(LLVMTypeRef *ElementTypes,
+ unsigned ElementCount, int Packed) {
+ return LLVMUnionTypeInContext(LLVMGetGlobalContext(), ElementTypes,
+ ElementCount);
+}
+
+unsigned LLVMCountUnionElementTypes(LLVMTypeRef UnionTy) {
+ return unwrap<UnionType>(UnionTy)->getNumElements();
+}
+
+void LLVMGetUnionElementTypes(LLVMTypeRef UnionTy, LLVMTypeRef *Dest) {
+ UnionType *Ty = unwrap<UnionType>(UnionTy);
+ for (FunctionType::param_iterator I = Ty->element_begin(),
+ E = Ty->element_end(); I != E; ++I)
+ *Dest++ = wrap(*I);
+}
+
/*--.. Operations on array, pointer, and vector types (sequence types) .....--*/
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount) {
@@ -932,8 +964,6 @@ LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) {
return LLVMDLLExportLinkage;
case GlobalValue::ExternalWeakLinkage:
return LLVMExternalWeakLinkage;
- case GlobalValue::GhostLinkage:
- return LLVMGhostLinkage;
case GlobalValue::CommonLinkage:
return LLVMCommonLinkage;
}
@@ -988,7 +1018,8 @@ void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) {
GV->setLinkage(GlobalValue::ExternalWeakLinkage);
break;
case LLVMGhostLinkage:
- GV->setLinkage(GlobalValue::GhostLinkage);
+ DEBUG(errs()
+ << "LLVMSetLinkage(): LLVMGhostLinkage is no longer supported.");
break;
case LLVMCommonLinkage:
GV->setLinkage(GlobalValue::CommonLinkage);
@@ -1965,7 +1996,7 @@ LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef B, LLVMValueRef LHS,
LLVMModuleProviderRef
LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M) {
- return wrap(new ExistingModuleProvider(unwrap(M)));
+ return reinterpret_cast<LLVMModuleProviderRef>(M);
}
void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP) {
diff --git a/lib/VMCore/GVMaterializer.cpp b/lib/VMCore/GVMaterializer.cpp
new file mode 100644
index 0000000..f77a9c9
--- /dev/null
+++ b/lib/VMCore/GVMaterializer.cpp
@@ -0,0 +1,18 @@
+//===-- GVMaterializer.cpp - Base implementation for GV materializers -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Minimal implementation of the abstract interface for materializing
+// GlobalValues.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/GVMaterializer.h"
+using namespace llvm;
+
+GVMaterializer::~GVMaterializer() {}
diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp
index 94bf3de..489ec65 100644
--- a/lib/VMCore/Globals.cpp
+++ b/lib/VMCore/Globals.cpp
@@ -43,6 +43,19 @@ static bool removeDeadUsersOfConstant(const Constant *C) {
return true;
}
+bool GlobalValue::isMaterializable() const {
+ return getParent() && getParent()->isMaterializable(this);
+}
+bool GlobalValue::isDematerializable() const {
+ return getParent() && getParent()->isDematerializable(this);
+}
+bool GlobalValue::Materialize(std::string *ErrInfo) {
+ return getParent()->Materialize(this, ErrInfo);
+}
+void GlobalValue::Dematerialize() {
+ getParent()->Dematerialize(this);
+}
+
/// removeDeadConstantUsers - If there are any dead constant users dangling
/// off of this global value, remove them. This method is useful for clients
/// that want to check to see if a global is unused, but don't want to deal
diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp
index 699bf0f..9f2786e 100644
--- a/lib/VMCore/IRBuilder.cpp
+++ b/lib/VMCore/IRBuilder.cpp
@@ -19,7 +19,7 @@
using namespace llvm;
/// CreateGlobalString - Make a new global variable with an initializer that
-/// has array of i8 type filled in the the nul terminated string value
+/// has array of i8 type filled in with the nul terminated string value
/// specified. If Name is specified, it is the name of the global variable
/// created.
Value *IRBuilderBase::CreateGlobalString(const char *Str, const Twine &Name) {
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index e2b920e..9d5f7a5 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -787,7 +787,7 @@ BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const {
void BranchInst::AssertOK() {
if (isConditional())
- assert(getCondition()->getType()->isInteger(1) &&
+ assert(getCondition()->getType()->isIntegerTy(1) &&
"May only branch on boolean predicates!");
}
@@ -892,7 +892,7 @@ static Value *getAISize(LLVMContext &Context, Value *Amt) {
else {
assert(!isa<BasicBlock>(Amt) &&
"Passed basic block into allocation size parameter! Use other ctor");
- assert(Amt->getType()->isInteger(32) &&
+ assert(Amt->getType()->isIntegerTy(32) &&
"Allocation array size is not a 32-bit integer!");
}
return Amt;
@@ -1391,7 +1391,7 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) {
- if (!isa<VectorType>(Val->getType()) || !Index->getType()->isInteger(32))
+ if (!isa<VectorType>(Val->getType()) || !Index->getType()->isIntegerTy(32))
return false;
return true;
}
@@ -1438,7 +1438,7 @@ bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt,
if (Elt->getType() != cast<VectorType>(Vec->getType())->getElementType())
return false;// Second operand of insertelement must be vector element type.
- if (!Index->getType()->isInteger(32))
+ if (!Index->getType()->isIntegerTy(32))
return false; // Third operand of insertelement must be i32.
return true;
}
@@ -1490,7 +1490,7 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
const VectorType *MaskTy = dyn_cast<VectorType>(Mask->getType());
if (!isa<Constant>(Mask) || MaskTy == 0 ||
- !MaskTy->getElementType()->isInteger(32))
+ !MaskTy->getElementType()->isIntegerTy(32))
return false;
return true;
}
@@ -1632,7 +1632,7 @@ const Type* ExtractValueInst::getIndexedType(const Type *Agg,
static BinaryOperator::BinaryOps AdjustIType(BinaryOperator::BinaryOps iType,
const Type *Ty) {
// API compatibility: Adjust integer opcodes to floating-point opcodes.
- if (Ty->isFPOrFPVector()) {
+ if (Ty->isFPOrFPVectorTy()) {
if (iType == BinaryOperator::Add) iType = BinaryOperator::FAdd;
else if (iType == BinaryOperator::Sub) iType = BinaryOperator::FSub;
else if (iType == BinaryOperator::Mul) iType = BinaryOperator::FMul;
@@ -1678,14 +1678,14 @@ void BinaryOperator::init(BinaryOps iType) {
case Mul:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert(getType()->isIntOrIntVector() &&
+ assert(getType()->isIntOrIntVectorTy() &&
"Tried to create an integer operation on a non-integer type!");
break;
case FAdd: case FSub:
case FMul:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert(getType()->isFPOrFPVector() &&
+ assert(getType()->isFPOrFPVectorTy() &&
"Tried to create a floating-point operation on a "
"non-floating-point type!");
break;
@@ -1693,28 +1693,28 @@ void BinaryOperator::init(BinaryOps iType) {
case SDiv:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isInteger() || (isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isInteger())) &&
+ assert((getType()->isIntegerTy() || (isa<VectorType>(getType()) &&
+ cast<VectorType>(getType())->getElementType()->isIntegerTy())) &&
"Incorrect operand type (not integer) for S/UDIV");
break;
case FDiv:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert(getType()->isFPOrFPVector() &&
+ assert(getType()->isFPOrFPVectorTy() &&
"Incorrect operand type (not floating point) for FDIV");
break;
case URem:
case SRem:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isInteger() || (isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isInteger())) &&
+ assert((getType()->isIntegerTy() || (isa<VectorType>(getType()) &&
+ cast<VectorType>(getType())->getElementType()->isIntegerTy())) &&
"Incorrect operand type (not integer) for S/UREM");
break;
case FRem:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert(getType()->isFPOrFPVector() &&
+ assert(getType()->isFPOrFPVectorTy() &&
"Incorrect operand type (not floating point) for FREM");
break;
case Shl:
@@ -1722,18 +1722,18 @@ void BinaryOperator::init(BinaryOps iType) {
case AShr:
assert(getType() == LHS->getType() &&
"Shift operation should return same type as operands!");
- assert((getType()->isInteger() ||
+ assert((getType()->isIntegerTy() ||
(isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isInteger())) &&
+ cast<VectorType>(getType())->getElementType()->isIntegerTy())) &&
"Tried to create a shift operation on a non-integral type!");
break;
case And: case Or:
case Xor:
assert(getType() == LHS->getType() &&
"Logical operation should return same type as operands!");
- assert((getType()->isInteger() ||
+ assert((getType()->isIntegerTy() ||
(isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isInteger())) &&
+ cast<VectorType>(getType())->getElementType()->isIntegerTy())) &&
"Tried to create a logical operation on a non-integral type!");
break;
default:
@@ -1786,6 +1786,18 @@ BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name,
return BinaryOperator::CreateNSWSub(zero, Op, Name, InsertAtEnd);
}
+BinaryOperator *BinaryOperator::CreateNUWNeg(Value *Op, const Twine &Name,
+ Instruction *InsertBefore) {
+ Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());
+ return BinaryOperator::CreateNUWSub(zero, Op, Name, InsertBefore);
+}
+
+BinaryOperator *BinaryOperator::CreateNUWNeg(Value *Op, const Twine &Name,
+ BasicBlock *InsertAtEnd) {
+ Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());
+ return BinaryOperator::CreateNUWSub(zero, Op, Name, InsertAtEnd);
+}
+
BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const Twine &Name,
Instruction *InsertBefore) {
Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());
@@ -1948,7 +1960,8 @@ bool CastInst::isIntegerCast() const {
case Instruction::Trunc:
return true;
case Instruction::BitCast:
- return getOperand(0)->getType()->isInteger() && getType()->isInteger();
+ return getOperand(0)->getType()->isIntegerTy() &&
+ getType()->isIntegerTy();
}
}
@@ -2081,25 +2094,25 @@ unsigned CastInst::isEliminableCastPair(
// no-op cast in second op implies firstOp as long as the DestTy
// is integer and we are not converting between a vector and a
// non vector type.
- if (!isa<VectorType>(SrcTy) && DstTy->isInteger())
+ if (!isa<VectorType>(SrcTy) && DstTy->isIntegerTy())
return firstOp;
return 0;
case 4:
// no-op cast in second op implies firstOp as long as the DestTy
// is floating point.
- if (DstTy->isFloatingPoint())
+ if (DstTy->isFloatingPointTy())
return firstOp;
return 0;
case 5:
// no-op cast in first op implies secondOp as long as the SrcTy
// is an integer.
- if (SrcTy->isInteger())
+ if (SrcTy->isIntegerTy())
return secondOp;
return 0;
case 6:
// no-op cast in first op implies secondOp as long as the SrcTy
// is a floating point.
- if (SrcTy->isFloatingPoint())
+ if (SrcTy->isFloatingPointTy())
return secondOp;
return 0;
case 7: {
@@ -2262,10 +2275,10 @@ CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty,
const Twine &Name,
BasicBlock *InsertAtEnd) {
assert(isa<PointerType>(S->getType()) && "Invalid cast");
- assert((Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Invalid cast");
- if (Ty->isInteger())
+ if (Ty->isIntegerTy())
return Create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd);
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
}
@@ -2275,10 +2288,10 @@ CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty,
const Twine &Name,
Instruction *InsertBefore) {
assert(isa<PointerType>(S->getType()) && "Invalid cast");
- assert((Ty->isInteger() || isa<PointerType>(Ty)) &&
+ assert((Ty->isIntegerTy() || isa<PointerType>(Ty)) &&
"Invalid cast");
- if (Ty->isInteger())
+ if (Ty->isIntegerTy())
return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
}
@@ -2286,7 +2299,7 @@ CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty,
CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
bool isSigned, const Twine &Name,
Instruction *InsertBefore) {
- assert(C->getType()->isIntOrIntVector() && Ty->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() &&
"Invalid integer cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
@@ -2300,7 +2313,7 @@ CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
bool isSigned, const Twine &Name,
BasicBlock *InsertAtEnd) {
- assert(C->getType()->isIntOrIntVector() && Ty->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() &&
"Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
@@ -2314,7 +2327,7 @@ CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
const Twine &Name,
Instruction *InsertBefore) {
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
"Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
@@ -2327,7 +2340,7 @@ CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
const Twine &Name,
BasicBlock *InsertAtEnd) {
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
"Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
@@ -2351,10 +2364,10 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
// Run through the possibilities ...
- if (DestTy->isInteger()) { // Casting to integral
- if (SrcTy->isInteger()) { // Casting from integral
+ if (DestTy->isIntegerTy()) { // Casting to integral
+ if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
- } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
return true;
} else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
// Casting from vector
@@ -2362,10 +2375,10 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
} else { // Casting from something else
return isa<PointerType>(SrcTy);
}
- } else if (DestTy->isFloatingPoint()) { // Casting to floating pt
- if (SrcTy->isInteger()) { // Casting from integral
+ } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt
+ if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
- } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
return true;
} else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
// Casting from vector
@@ -2384,7 +2397,7 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
} else if (isa<PointerType>(DestTy)) { // Casting to pointer
if (isa<PointerType>(SrcTy)) { // Casting from pointer
return true;
- } else if (SrcTy->isInteger()) { // Casting from integral
+ } else if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
} else { // Casting from something else
return false;
@@ -2413,8 +2426,8 @@ CastInst::getCastOpcode(
"Only first class types are castable!");
// Run through the possibilities ...
- if (DestTy->isInteger()) { // Casting to integral
- if (SrcTy->isInteger()) { // Casting from integral
+ if (DestTy->isIntegerTy()) { // Casting to integral
+ if (SrcTy->isIntegerTy()) { // Casting from integral
if (DestBits < SrcBits)
return Trunc; // int -> smaller int
else if (DestBits > SrcBits) { // its an extension
@@ -2425,7 +2438,7 @@ CastInst::getCastOpcode(
} else {
return BitCast; // Same size, No-op cast
}
- } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
if (DestIsSigned)
return FPToSI; // FP -> sint
else
@@ -2440,13 +2453,13 @@ CastInst::getCastOpcode(
"Casting from a value that is not first-class type");
return PtrToInt; // ptr -> int
}
- } else if (DestTy->isFloatingPoint()) { // Casting to floating pt
- if (SrcTy->isInteger()) { // Casting from integral
+ } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt
+ if (SrcTy->isIntegerTy()) { // Casting from integral
if (SrcIsSigned)
return SIToFP; // sint -> FP
else
return UIToFP; // uint -> FP
- } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
if (DestBits < SrcBits) {
return FPTrunc; // FP -> smaller FP
} else if (DestBits > SrcBits) {
@@ -2476,7 +2489,7 @@ CastInst::getCastOpcode(
} else if (isa<PointerType>(DestTy)) {
if (isa<PointerType>(SrcTy)) {
return BitCast; // ptr -> ptr
- } else if (SrcTy->isInteger()) {
+ } else if (SrcTy->isIntegerTy()) {
return IntToPtr; // int -> ptr
} else {
assert(!"Casting pointer to other than pointer or int");
@@ -2504,7 +2517,8 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
// Check for type sanity on the arguments
const Type *SrcTy = S->getType();
- if (!SrcTy->isFirstClassType() || !DstTy->isFirstClassType())
+ if (!SrcTy->isFirstClassType() || !DstTy->isFirstClassType() ||
+ SrcTy->isAggregateType() || DstTy->isAggregateType())
return false;
// Get the size of the types in bits, we'll need this later
@@ -2515,46 +2529,46 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
switch (op) {
default: return false; // This is an input error
case Instruction::Trunc:
- return SrcTy->isIntOrIntVector() &&
- DstTy->isIntOrIntVector()&& SrcBitSize > DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() &&
+ DstTy->isIntOrIntVectorTy()&& SrcBitSize > DstBitSize;
case Instruction::ZExt:
- return SrcTy->isIntOrIntVector() &&
- DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() &&
+ DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize;
case Instruction::SExt:
- return SrcTy->isIntOrIntVector() &&
- DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() &&
+ DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize;
case Instruction::FPTrunc:
- return SrcTy->isFPOrFPVector() &&
- DstTy->isFPOrFPVector() &&
+ return SrcTy->isFPOrFPVectorTy() &&
+ DstTy->isFPOrFPVectorTy() &&
SrcBitSize > DstBitSize;
case Instruction::FPExt:
- return SrcTy->isFPOrFPVector() &&
- DstTy->isFPOrFPVector() &&
+ return SrcTy->isFPOrFPVectorTy() &&
+ DstTy->isFPOrFPVectorTy() &&
SrcBitSize < DstBitSize;
case Instruction::UIToFP:
case Instruction::SIToFP:
if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- return SVTy->getElementType()->isIntOrIntVector() &&
- DVTy->getElementType()->isFPOrFPVector() &&
+ return SVTy->getElementType()->isIntOrIntVectorTy() &&
+ DVTy->getElementType()->isFPOrFPVectorTy() &&
SVTy->getNumElements() == DVTy->getNumElements();
}
}
- return SrcTy->isIntOrIntVector() && DstTy->isFPOrFPVector();
+ return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy();
case Instruction::FPToUI:
case Instruction::FPToSI:
if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- return SVTy->getElementType()->isFPOrFPVector() &&
- DVTy->getElementType()->isIntOrIntVector() &&
+ return SVTy->getElementType()->isFPOrFPVectorTy() &&
+ DVTy->getElementType()->isIntOrIntVectorTy() &&
SVTy->getNumElements() == DVTy->getNumElements();
}
}
- return SrcTy->isFPOrFPVector() && DstTy->isIntOrIntVector();
+ return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy();
case Instruction::PtrToInt:
- return isa<PointerType>(SrcTy) && DstTy->isInteger();
+ return isa<PointerType>(SrcTy) && DstTy->isIntegerTy();
case Instruction::IntToPtr:
- return SrcTy->isInteger() && isa<PointerType>(DstTy);
+ return SrcTy->isIntegerTy() && isa<PointerType>(DstTy);
case Instruction::BitCast:
// BitCast implies a no-op cast of type only. No bits change.
// However, you can't cast pointers to anything but pointers.
@@ -2865,25 +2879,53 @@ ICmpInst::makeConstantRange(Predicate pred, const APInt &C) {
default: llvm_unreachable("Invalid ICmp opcode to ConstantRange ctor!");
case ICmpInst::ICMP_EQ: Upper++; break;
case ICmpInst::ICMP_NE: Lower++; break;
- case ICmpInst::ICMP_ULT: Lower = APInt::getMinValue(BitWidth); break;
- case ICmpInst::ICMP_SLT: Lower = APInt::getSignedMinValue(BitWidth); break;
+ case ICmpInst::ICMP_ULT:
+ Lower = APInt::getMinValue(BitWidth);
+ // Check for an empty-set condition.
+ if (Lower == Upper)
+ return ConstantRange(BitWidth, /*isFullSet=*/false);
+ break;
+ case ICmpInst::ICMP_SLT:
+ Lower = APInt::getSignedMinValue(BitWidth);
+ // Check for an empty-set condition.
+ if (Lower == Upper)
+ return ConstantRange(BitWidth, /*isFullSet=*/false);
+ break;
case ICmpInst::ICMP_UGT:
Lower++; Upper = APInt::getMinValue(BitWidth); // Min = Next(Max)
+ // Check for an empty-set condition.
+ if (Lower == Upper)
+ return ConstantRange(BitWidth, /*isFullSet=*/false);
break;
case ICmpInst::ICMP_SGT:
Lower++; Upper = APInt::getSignedMinValue(BitWidth); // Min = Next(Max)
+ // Check for an empty-set condition.
+ if (Lower == Upper)
+ return ConstantRange(BitWidth, /*isFullSet=*/false);
break;
case ICmpInst::ICMP_ULE:
Lower = APInt::getMinValue(BitWidth); Upper++;
+ // Check for a full-set condition.
+ if (Lower == Upper)
+ return ConstantRange(BitWidth, /*isFullSet=*/true);
break;
case ICmpInst::ICMP_SLE:
Lower = APInt::getSignedMinValue(BitWidth); Upper++;
+ // Check for a full-set condition.
+ if (Lower == Upper)
+ return ConstantRange(BitWidth, /*isFullSet=*/true);
break;
case ICmpInst::ICMP_UGE:
Upper = APInt::getMinValue(BitWidth); // Min = Next(Max)
+ // Check for a full-set condition.
+ if (Lower == Upper)
+ return ConstantRange(BitWidth, /*isFullSet=*/true);
break;
case ICmpInst::ICMP_SGE:
Upper = APInt::getSignedMinValue(BitWidth); // Min = Next(Max)
+ // Check for a full-set condition.
+ if (Lower == Upper)
+ return ConstantRange(BitWidth, /*isFullSet=*/true);
break;
}
return ConstantRange(Lower, Upper);
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h
index ccca789..62491d8 100644
--- a/lib/VMCore/LLVMContextImpl.h
+++ b/lib/VMCore/LLVMContextImpl.h
@@ -116,6 +116,10 @@ public:
ConstantStruct, true /*largekey*/> StructConstantsTy;
StructConstantsTy StructConstants;
+ typedef ConstantUniqueMap<Constant*, UnionType, ConstantUnion>
+ UnionConstantsTy;
+ UnionConstantsTy UnionConstants;
+
typedef ConstantUniqueMap<std::vector<Constant*>, VectorType,
ConstantVector> VectorConstantsTy;
VectorConstantsTy VectorConstants;
@@ -159,12 +163,16 @@ public:
TypeMap<PointerValType, PointerType> PointerTypes;
TypeMap<FunctionValType, FunctionType> FunctionTypes;
TypeMap<StructValType, StructType> StructTypes;
+ TypeMap<UnionValType, UnionType> UnionTypes;
TypeMap<IntegerValType, IntegerType> IntegerTypes;
// Opaque types are not structurally uniqued, so don't use TypeMap.
typedef SmallPtrSet<const OpaqueType*, 8> OpaqueTypesTy;
OpaqueTypesTy OpaqueTypes;
-
+
+ /// Used as an abstract type that will never be resolved.
+ OpaqueType *const AlwaysOpaqueTy;
+
/// ValueHandles - This map keeps track of all of the value handles that are
/// watching a Value*. The Value::HasValueHandle bit is used to know
@@ -196,7 +204,12 @@ public:
Int8Ty(C, 8),
Int16Ty(C, 16),
Int32Ty(C, 32),
- Int64Ty(C, 64) { }
+ Int64Ty(C, 64),
+ AlwaysOpaqueTy(new OpaqueType(C)) {
+ // Make sure the AlwaysOpaqueTy stays alive as long as the Context.
+ AlwaysOpaqueTy->addRef();
+ OpaqueTypes.insert(AlwaysOpaqueTy);
+ }
~LLVMContextImpl() {
ExprConstants.freeConstants();
@@ -217,6 +230,7 @@ public:
delete I->second;
}
MDNodeSet.clear();
+ AlwaysOpaqueTy->dropRef();
for (OpaqueTypesTy::iterator I = OpaqueTypes.begin(), E = OpaqueTypes.end();
I != E; ++I) {
(*I)->AbstractTypeUsers.clear();
diff --git a/lib/VMCore/Makefile b/lib/VMCore/Makefile
index ecadaee..bc5e77d 100644
--- a/lib/VMCore/Makefile
+++ b/lib/VMCore/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
LIBRARYNAME = LLVMCore
BUILD_ARCHIVE = 1
-#CXXFLAGS = -fno-rtti
+REQUIRES_RTTI = 1
BUILT_SOURCES = $(PROJ_OBJ_ROOT)/include/llvm/Intrinsics.gen
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index ee8e713..07a5f3c 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/lib/VMCore/Metadata.cpp
@@ -186,43 +186,50 @@ void MDNode::destroy() {
}
MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals,
- unsigned NumVals, FunctionLocalness FL) {
+ unsigned NumVals, FunctionLocalness FL,
+ bool Insert) {
LLVMContextImpl *pImpl = Context.pImpl;
FoldingSetNodeID ID;
for (unsigned i = 0; i != NumVals; ++i)
ID.AddPointer(Vals[i]);
void *InsertPoint;
- MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
- if (!N) {
- bool isFunctionLocal = false;
- switch (FL) {
- case FL_Unknown:
- for (unsigned i = 0; i != NumVals; ++i) {
- Value *V = Vals[i];
- if (!V) continue;
- if (isa<Instruction>(V) || isa<Argument>(V) || isa<BasicBlock>(V) ||
- (isa<MDNode>(V) && cast<MDNode>(V)->isFunctionLocal())) {
- isFunctionLocal = true;
- break;
- }
+ MDNode *N = NULL;
+
+ if ((N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint)))
+ return N;
+
+ if (!Insert)
+ return NULL;
+
+ bool isFunctionLocal = false;
+ switch (FL) {
+ case FL_Unknown:
+ for (unsigned i = 0; i != NumVals; ++i) {
+ Value *V = Vals[i];
+ if (!V) continue;
+ if (isa<Instruction>(V) || isa<Argument>(V) || isa<BasicBlock>(V) ||
+ (isa<MDNode>(V) && cast<MDNode>(V)->isFunctionLocal())) {
+ isFunctionLocal = true;
+ break;
}
- break;
- case FL_No:
- isFunctionLocal = false;
- break;
- case FL_Yes:
- isFunctionLocal = true;
- break;
}
+ break;
+ case FL_No:
+ isFunctionLocal = false;
+ break;
+ case FL_Yes:
+ isFunctionLocal = true;
+ break;
+ }
- // Coallocate space for the node and Operands together, then placement new.
- void *Ptr = malloc(sizeof(MDNode)+NumVals*sizeof(MDNodeOperand));
- N = new (Ptr) MDNode(Context, Vals, NumVals, isFunctionLocal);
+ // Coallocate space for the node and Operands together, then placement new.
+ void *Ptr = malloc(sizeof(MDNode)+NumVals*sizeof(MDNodeOperand));
+ N = new (Ptr) MDNode(Context, Vals, NumVals, isFunctionLocal);
+
+ // InsertPoint will have been set by the FindNodeOrInsertPos call.
+ pImpl->MDNodeSet.InsertNode(N, InsertPoint);
- // InsertPoint will have been set by the FindNodeOrInsertPos call.
- pImpl->MDNodeSet.InsertNode(N, InsertPoint);
- }
return N;
}
@@ -230,11 +237,16 @@ MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) {
return getMDNode(Context, Vals, NumVals, FL_Unknown);
}
-MDNode *MDNode::getWhenValsUnresolved(LLVMContext &Context, Value*const* Vals,
+MDNode *MDNode::getWhenValsUnresolved(LLVMContext &Context, Value *const *Vals,
unsigned NumVals, bool isFunctionLocal) {
return getMDNode(Context, Vals, NumVals, isFunctionLocal ? FL_Yes : FL_No);
}
+MDNode *MDNode::getIfExists(LLVMContext &Context, Value *const *Vals,
+ unsigned NumVals) {
+ return getMDNode(Context, Vals, NumVals, FL_Unknown, false);
+}
+
/// getOperand - Return specified operand.
Value *MDNode::getOperand(unsigned i) const {
return *getOperandPtr(const_cast<MDNode*>(this), i);
diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp
index 503e708..001bb00 100644
--- a/lib/VMCore/Module.cpp
+++ b/lib/VMCore/Module.cpp
@@ -15,6 +15,7 @@
#include "llvm/InstrTypes.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/GVMaterializer.h"
#include "llvm/LLVMContext.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
@@ -56,7 +57,7 @@ template class llvm::SymbolTableListTraits<GlobalAlias, Module>;
//
Module::Module(StringRef MID, LLVMContext& C)
- : Context(C), ModuleID(MID), DataLayout("") {
+ : Context(C), Materializer(NULL), ModuleID(MID), DataLayout("") {
ValSymTab = new ValueSymbolTable();
TypeSymTab = new TypeSymbolTable();
NamedMDSymTab = new MDSymbolTable();
@@ -372,6 +373,52 @@ std::string Module::getTypeName(const Type *Ty) const {
}
//===----------------------------------------------------------------------===//
+// Methods to control the materialization of GlobalValues in the Module.
+//
+void Module::setMaterializer(GVMaterializer *GVM) {
+ assert(!Materializer &&
+ "Module already has a GVMaterializer. Call MaterializeAllPermanently"
+ " to clear it out before setting another one.");
+ Materializer.reset(GVM);
+}
+
+bool Module::isMaterializable(const GlobalValue *GV) const {
+ if (Materializer)
+ return Materializer->isMaterializable(GV);
+ return false;
+}
+
+bool Module::isDematerializable(const GlobalValue *GV) const {
+ if (Materializer)
+ return Materializer->isDematerializable(GV);
+ return false;
+}
+
+bool Module::Materialize(GlobalValue *GV, std::string *ErrInfo) {
+ if (Materializer)
+ return Materializer->Materialize(GV, ErrInfo);
+ return false;
+}
+
+void Module::Dematerialize(GlobalValue *GV) {
+ if (Materializer)
+ return Materializer->Dematerialize(GV);
+}
+
+bool Module::MaterializeAll(std::string *ErrInfo) {
+ if (!Materializer)
+ return false;
+ return Materializer->MaterializeModule(this, ErrInfo);
+}
+
+bool Module::MaterializeAllPermanently(std::string *ErrInfo) {
+ if (MaterializeAll(ErrInfo))
+ return true;
+ Materializer.reset();
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
// Other module related stuff.
//
diff --git a/lib/VMCore/ModuleProvider.cpp b/lib/VMCore/ModuleProvider.cpp
deleted file mode 100644
index cfff97c..0000000
--- a/lib/VMCore/ModuleProvider.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-//===-- ModuleProvider.cpp - Base implementation for module providers -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Minimal implementation of the abstract interface for providing a module.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ModuleProvider.h"
-#include "llvm/Module.h"
-using namespace llvm;
-
-/// ctor - always have a valid Module
-///
-ModuleProvider::ModuleProvider() : TheModule(0) { }
-
-/// dtor - when we leave, we take our Module with us
-///
-ModuleProvider::~ModuleProvider() {
- delete TheModule;
-}
diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp
index 45000f2..a782e5a 100644
--- a/lib/VMCore/Pass.cpp
+++ b/lib/VMCore/Pass.cpp
@@ -16,7 +16,6 @@
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Debug.h"
@@ -195,6 +194,9 @@ PassManagerType BasicBlockPass::getPotentialPassManagerType() const {
//
namespace {
class PassRegistrar {
+ /// Guards the contents of this class.
+ mutable sys::SmartMutex<true> Lock;
+
/// PassInfoMap - Keep track of the passinfo object for each registered llvm
/// pass.
typedef std::map<intptr_t, const PassInfo*> MapType;
@@ -214,16 +216,19 @@ class PassRegistrar {
public:
const PassInfo *GetPassInfo(intptr_t TI) const {
+ sys::SmartScopedLock<true> Guard(Lock);
MapType::const_iterator I = PassInfoMap.find(TI);
return I != PassInfoMap.end() ? I->second : 0;
}
const PassInfo *GetPassInfo(StringRef Arg) const {
+ sys::SmartScopedLock<true> Guard(Lock);
StringMapType::const_iterator I = PassInfoStringMap.find(Arg);
return I != PassInfoStringMap.end() ? I->second : 0;
}
void RegisterPass(const PassInfo &PI) {
+ sys::SmartScopedLock<true> Guard(Lock);
bool Inserted =
PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted;
@@ -231,6 +236,7 @@ public:
}
void UnregisterPass(const PassInfo &PI) {
+ sys::SmartScopedLock<true> Guard(Lock);
MapType::iterator I = PassInfoMap.find(PI.getTypeInfo());
assert(I != PassInfoMap.end() && "Pass registered but not in map!");
@@ -240,6 +246,7 @@ public:
}
void EnumerateWith(PassRegistrationListener *L) {
+ sys::SmartScopedLock<true> Guard(Lock);
for (MapType::const_iterator I = PassInfoMap.begin(),
E = PassInfoMap.end(); I != E; ++I)
L->passEnumerate(I->second);
@@ -250,6 +257,7 @@ public:
void RegisterAnalysisGroup(PassInfo *InterfaceInfo,
const PassInfo *ImplementationInfo,
bool isDefault) {
+ sys::SmartScopedLock<true> Guard(Lock);
AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo];
assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
"Cannot add a pass to the same analysis group more than once!");
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index 0c0d64e..8a3527e 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -18,7 +18,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/Timer.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
@@ -1194,15 +1193,13 @@ bool BBPassManager::doFinalization(Function &F) {
// FunctionPassManager implementation
/// Create new Function pass manager
-FunctionPassManager::FunctionPassManager(ModuleProvider *P) {
+FunctionPassManager::FunctionPassManager(Module *m) : M(m) {
FPM = new FunctionPassManagerImpl(0);
// FPM is the top level manager.
FPM->setTopLevelManager(FPM);
AnalysisResolver *AR = new AnalysisResolver(*FPM);
FPM->setResolver(AR);
-
- MP = P;
}
FunctionPassManager::~FunctionPassManager() {
@@ -1223,9 +1220,11 @@ void FunctionPassManager::add(Pass *P) {
/// so, return true.
///
bool FunctionPassManager::run(Function &F) {
- std::string errstr;
- if (MP->materializeFunction(&F, &errstr)) {
- llvm_report_error("Error reading bitcode file: " + errstr);
+ if (F.isMaterializable()) {
+ std::string errstr;
+ if (F.Materialize(&errstr)) {
+ llvm_report_error("Error reading bitcode file: " + errstr);
+ }
}
return FPM->run(F);
}
@@ -1234,13 +1233,13 @@ bool FunctionPassManager::run(Function &F) {
/// doInitialization - Run all of the initializers for the function passes.
///
bool FunctionPassManager::doInitialization() {
- return FPM->doInitialization(*MP->getModule());
+ return FPM->doInitialization(*M);
}
/// doFinalization - Run all of the finalizers for the function passes.
///
bool FunctionPassManager::doFinalization() {
- return FPM->doFinalization(*MP->getModule());
+ return FPM->doFinalization(*M);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index 044de4f..f4cd366 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -50,8 +50,8 @@ void AbstractTypeUser::setType(Value *V, const Type *NewTy) {
/// Because of the way Type subclasses are allocated, this function is necessary
/// to use the correct kind of "delete" operator to deallocate the Type object.
-/// Some type objects (FunctionTy, StructTy) allocate additional space after
-/// the space for their derived type to hold the contained types array of
+/// Some type objects (FunctionTy, StructTy, UnionTy) allocate additional space
+/// after the space for their derived type to hold the contained types array of
/// PATypeHandles. Using this allocation scheme means all the PATypeHandles are
/// allocated with the type object, decreasing allocations and eliminating the
/// need for a std::vector to be used in the Type class itself.
@@ -61,7 +61,8 @@ void Type::destroy() const {
// Structures and Functions allocate their contained types past the end of
// the type object itself. These need to be destroyed differently than the
// other types.
- if (isa<FunctionType>(this) || isa<StructType>(this)) {
+ if (isa<FunctionType>(this) || isa<StructType>(this) ||
+ isa<UnionType>(this)) {
// First, make sure we destruct any PATypeHandles allocated by these
// subclasses. They must be manually destructed.
for (unsigned i = 0; i < NumContainedTys; ++i)
@@ -71,8 +72,10 @@ void Type::destroy() const {
// to delete this as an array of char.
if (isa<FunctionType>(this))
static_cast<const FunctionType*>(this)->FunctionType::~FunctionType();
- else
+ else if (isa<StructType>(this))
static_cast<const StructType*>(this)->StructType::~StructType();
+ else
+ static_cast<const UnionType*>(this)->UnionType::~UnionType();
// Finally, remove the memory as an array deallocation of the chars it was
// constructed from.
@@ -124,32 +127,32 @@ const Type *Type::getScalarType() const {
return this;
}
-/// isInteger - Return true if this is an IntegerType of the specified width.
-bool Type::isInteger(unsigned Bitwidth) const {
- return isInteger() && cast<IntegerType>(this)->getBitWidth() == Bitwidth;
+/// isIntegerTy - Return true if this is an IntegerType of the specified width.
+bool Type::isIntegerTy(unsigned Bitwidth) const {
+ return isIntegerTy() && cast<IntegerType>(this)->getBitWidth() == Bitwidth;
}
-/// isIntOrIntVector - Return true if this is an integer type or a vector of
+/// isIntOrIntVectorTy - Return true if this is an integer type or a vector of
/// integer types.
///
-bool Type::isIntOrIntVector() const {
- if (isInteger())
+bool Type::isIntOrIntVectorTy() const {
+ if (isIntegerTy())
return true;
if (ID != Type::VectorTyID) return false;
- return cast<VectorType>(this)->getElementType()->isInteger();
+ return cast<VectorType>(this)->getElementType()->isIntegerTy();
}
-/// isFPOrFPVector - Return true if this is a FP type or a vector of FP types.
+/// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP types.
///
-bool Type::isFPOrFPVector() const {
+bool Type::isFPOrFPVectorTy() const {
if (ID == Type::FloatTyID || ID == Type::DoubleTyID ||
ID == Type::FP128TyID || ID == Type::X86_FP80TyID ||
ID == Type::PPC_FP128TyID)
return true;
if (ID != Type::VectorTyID) return false;
- return cast<VectorType>(this)->getElementType()->isFloatingPoint();
+ return cast<VectorType>(this)->getElementType()->isFloatingPointTy();
}
// canLosslesslyBitCastTo - Return true if this type can be converted to
@@ -204,7 +207,7 @@ unsigned Type::getScalarSizeInBits() const {
int Type::getFPMantissaWidth() const {
if (const VectorType *VTy = dyn_cast<VectorType>(this))
return VTy->getElementType()->getFPMantissaWidth();
- assert(isFloatingPoint() && "Not a floating point type!");
+ assert(isFloatingPointTy() && "Not a floating point type!");
if (ID == FloatTyID) return 24;
if (ID == DoubleTyID) return 53;
if (ID == X86_FP80TyID) return 64;
@@ -226,7 +229,7 @@ bool Type::isSizedDerivedType() const {
if (const VectorType *PTy = dyn_cast<VectorType>(this))
return PTy->getElementType()->isSized();
- if (!isa<StructType>(this))
+ if (!isa<StructType>(this) && !isa<UnionType>(this))
return false;
// Okay, our struct is sized if all of the elements are...
@@ -285,7 +288,7 @@ std::string Type::getDescription() const {
bool StructType::indexValid(const Value *V) const {
// Structure indexes require 32-bit integer constants.
- if (V->getType()->isInteger(32))
+ if (V->getType()->isIntegerTy(32))
if (const ConstantInt *CU = dyn_cast<ConstantInt>(V))
return indexValid(CU->getZExtValue());
return false;
@@ -308,6 +311,32 @@ const Type *StructType::getTypeAtIndex(unsigned Idx) const {
return ContainedTys[Idx];
}
+
+bool UnionType::indexValid(const Value *V) const {
+ // Union indexes require 32-bit integer constants.
+ if (V->getType()->isIntegerTy(32))
+ if (const ConstantInt *CU = dyn_cast<ConstantInt>(V))
+ return indexValid(CU->getZExtValue());
+ return false;
+}
+
+bool UnionType::indexValid(unsigned V) const {
+ return V < NumContainedTys;
+}
+
+// getTypeAtIndex - Given an index value into the type, return the type of the
+// element. For a structure type, this must be a constant value...
+//
+const Type *UnionType::getTypeAtIndex(const Value *V) const {
+ unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue();
+ return getTypeAtIndex(Idx);
+}
+
+const Type *UnionType::getTypeAtIndex(unsigned Idx) const {
+ assert(indexValid(Idx) && "Invalid structure index!");
+ return ContainedTys[Idx];
+}
+
//===----------------------------------------------------------------------===//
// Primitive 'Type' data
//===----------------------------------------------------------------------===//
@@ -463,6 +492,23 @@ StructType::StructType(LLVMContext &C,
setAbstract(isAbstract);
}
+UnionType::UnionType(LLVMContext &C,const Type* const* Types, unsigned NumTypes)
+ : CompositeType(C, UnionTyID) {
+ ContainedTys = reinterpret_cast<PATypeHandle*>(this + 1);
+ NumContainedTys = NumTypes;
+ bool isAbstract = false;
+ for (unsigned i = 0; i < NumTypes; ++i) {
+ assert(Types[i] && "<null> type for union field!");
+ assert(isValidElementType(Types[i]) &&
+ "Invalid type for union element!");
+ new (&ContainedTys[i]) PATypeHandle(Types[i], this);
+ isAbstract |= Types[i]->isAbstract();
+ }
+
+ // Calculate whether or not this type is abstract
+ setAbstract(isAbstract);
+}
+
ArrayType::ArrayType(const Type *ElType, uint64_t NumEl)
: SequentialType(ArrayTyID, ElType) {
NumElements = NumEl;
@@ -507,30 +553,7 @@ void DerivedType::dropAllTypeUses() {
if (NumContainedTys != 0) {
// The type must stay abstract. To do this, we insert a pointer to a type
// that will never get resolved, thus will always be abstract.
- static Type *AlwaysOpaqueTy = 0;
- static PATypeHolder* Holder = 0;
- Type *tmp = AlwaysOpaqueTy;
- if (llvm_is_multithreaded()) {
- sys::MemoryFence();
- if (!tmp) {
- llvm_acquire_global_lock();
- tmp = AlwaysOpaqueTy;
- if (!tmp) {
- tmp = OpaqueType::get(getContext());
- PATypeHolder* tmp2 = new PATypeHolder(tmp);
- sys::MemoryFence();
- AlwaysOpaqueTy = tmp;
- Holder = tmp2;
- }
-
- llvm_release_global_lock();
- }
- } else if (!AlwaysOpaqueTy) {
- AlwaysOpaqueTy = OpaqueType::get(getContext());
- Holder = new PATypeHolder(AlwaysOpaqueTy);
- }
-
- ContainedTys[0] = AlwaysOpaqueTy;
+ ContainedTys[0] = getContext().pImpl->AlwaysOpaqueTy;
// Change the rest of the types to be Int32Ty's. It doesn't matter what we
// pick so long as it doesn't point back to this type. We choose something
@@ -667,6 +690,13 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2,
if (!TypesEqual(STy->getElementType(i), STy2->getElementType(i), EqTypes))
return false;
return true;
+ } else if (const UnionType *UTy = dyn_cast<UnionType>(Ty)) {
+ const UnionType *UTy2 = cast<UnionType>(Ty2);
+ if (UTy->getNumElements() != UTy2->getNumElements()) return false;
+ for (unsigned i = 0, e = UTy2->getNumElements(); i != e; ++i)
+ if (!TypesEqual(UTy->getElementType(i), UTy2->getElementType(i), EqTypes))
+ return false;
+ return true;
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
const ArrayType *ATy2 = cast<ArrayType>(Ty2);
return ATy->getNumElements() == ATy2->getNumElements() &&
@@ -881,7 +911,7 @@ VectorType *VectorType::get(const Type *ElementType, unsigned NumElements) {
}
bool VectorType::isValidElementType(const Type *ElemTy) {
- return ElemTy->isInteger() || ElemTy->isFloatingPoint() ||
+ return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
isa<OpaqueType>(ElemTy);
}
@@ -924,10 +954,64 @@ StructType *StructType::get(LLVMContext &Context, const Type *type, ...) {
}
bool StructType::isValidElementType(const Type *ElemTy) {
- return ElemTy->getTypeID() != VoidTyID && ElemTy->getTypeID() != LabelTyID &&
- ElemTy->getTypeID() != MetadataTyID && !isa<FunctionType>(ElemTy);
+ return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
+ !ElemTy->isMetadataTy() && !isa<FunctionType>(ElemTy);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Union Type Factory...
+//
+
+UnionType *UnionType::get(const Type* const* Types, unsigned NumTypes) {
+ assert(NumTypes > 0 && "union must have at least one member type!");
+ UnionValType UTV(Types, NumTypes);
+ UnionType *UT = 0;
+
+ LLVMContextImpl *pImpl = Types[0]->getContext().pImpl;
+
+ UT = pImpl->UnionTypes.get(UTV);
+
+ if (!UT) {
+ // Value not found. Derive a new type!
+ UT = (UnionType*) operator new(sizeof(UnionType) +
+ sizeof(PATypeHandle) * NumTypes);
+ new (UT) UnionType(Types[0]->getContext(), Types, NumTypes);
+ pImpl->UnionTypes.add(UTV, UT);
+ }
+#ifdef DEBUG_MERGE_TYPES
+ DEBUG(dbgs() << "Derived new type: " << *UT << "\n");
+#endif
+ return UT;
+}
+
+UnionType *UnionType::get(const Type *type, ...) {
+ va_list ap;
+ SmallVector<const llvm::Type*, 8> UnionFields;
+ va_start(ap, type);
+ while (type) {
+ UnionFields.push_back(type);
+ type = va_arg(ap, llvm::Type*);
+ }
+ unsigned NumTypes = UnionFields.size();
+ assert(NumTypes > 0 && "union must have at least one member type!");
+ return llvm::UnionType::get(&UnionFields[0], NumTypes);
}
+bool UnionType::isValidElementType(const Type *ElemTy) {
+ return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
+ !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy();
+}
+
+int UnionType::getElementTypeIndex(const Type *ElemTy) const {
+ int index = 0;
+ for (UnionType::element_iterator I = element_begin(), E = element_end();
+ I != E; ++I, ++index) {
+ if (ElemTy == *I) return index;
+ }
+
+ return -1;
+}
//===----------------------------------------------------------------------===//
// Pointer Type Factory...
@@ -1192,6 +1276,21 @@ void StructType::typeBecameConcrete(const DerivedType *AbsTy) {
// concrete - this could potentially change us from an abstract type to a
// concrete type.
//
+void UnionType::refineAbstractType(const DerivedType *OldType,
+ const Type *NewType) {
+ LLVMContextImpl *pImpl = OldType->getContext().pImpl;
+ pImpl->UnionTypes.RefineAbstractType(this, OldType, NewType);
+}
+
+void UnionType::typeBecameConcrete(const DerivedType *AbsTy) {
+ LLVMContextImpl *pImpl = AbsTy->getContext().pImpl;
+ pImpl->UnionTypes.TypeBecameConcrete(this, AbsTy);
+}
+
+// refineAbstractType - Called when a contained type is found to be more
+// concrete - this could potentially change us from an abstract type to a
+// concrete type.
+//
void PointerType::refineAbstractType(const DerivedType *OldType,
const Type *NewType) {
LLVMContextImpl *pImpl = OldType->getContext().pImpl;
diff --git a/lib/VMCore/TypesContext.h b/lib/VMCore/TypesContext.h
index 93a801b..02ab113 100644
--- a/lib/VMCore/TypesContext.h
+++ b/lib/VMCore/TypesContext.h
@@ -68,7 +68,7 @@ static unsigned getSubElementHash(const Type *Ty) {
class IntegerValType {
uint32_t bits;
public:
- IntegerValType(uint16_t numbits) : bits(numbits) {}
+ IntegerValType(uint32_t numbits) : bits(numbits) {}
static IntegerValType get(const IntegerType *Ty) {
return IntegerValType(Ty->getBitWidth());
@@ -180,6 +180,32 @@ public:
}
};
+// UnionValType - Define a class to hold the key that goes into the TypeMap
+//
+class UnionValType {
+ std::vector<const Type*> ElTypes;
+public:
+ UnionValType(const Type* const* Types, unsigned NumTypes)
+ : ElTypes(&Types[0], &Types[NumTypes]) {}
+
+ static UnionValType get(const UnionType *UT) {
+ std::vector<const Type *> ElTypes;
+ ElTypes.reserve(UT->getNumElements());
+ for (unsigned i = 0, e = UT->getNumElements(); i != e; ++i)
+ ElTypes.push_back(UT->getElementType(i));
+
+ return UnionValType(&ElTypes[0], ElTypes.size());
+ }
+
+ static unsigned hashTypeStructure(const UnionType *UT) {
+ return UT->getNumElements();
+ }
+
+ inline bool operator<(const UnionValType &UTV) const {
+ return (ElTypes < UTV.ElTypes);
+ }
+};
+
// FunctionValType - Define a class to hold the key that goes into the TypeMap
//
class FunctionValType {
@@ -216,7 +242,6 @@ protected:
///
std::multimap<unsigned, PATypeHolder> TypesByHash;
-public:
~TypeMapBase() {
// PATypeHolder won't destroy non-abstract types.
// We can't destroy them by simply iterating, because
@@ -236,6 +261,7 @@ public:
}
}
+public:
void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) {
std::multimap<unsigned, PATypeHolder>::iterator I =
TypesByHash.lower_bound(Hash);
@@ -281,7 +307,6 @@ class TypeMap : public TypeMapBase {
std::map<ValType, PATypeHolder> Map;
public:
typedef typename std::map<ValType, PATypeHolder>::iterator iterator;
- ~TypeMap() { print("ON EXIT"); }
inline TypeClass *get(const ValType &V) {
iterator I = Map.find(V);
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index 40679bf..3759b8a 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -341,12 +341,11 @@ Value *Value::stripPointerCasts() {
} while (1);
}
-Value *Value::getUnderlyingObject() {
+Value *Value::getUnderlyingObject(unsigned MaxLookup) {
if (!isa<PointerType>(getType()))
return this;
Value *V = this;
- unsigned MaxLookup = 6;
- do {
+ for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) {
if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
V = GEP->getPointerOperand();
} else if (Operator::getOpcode(V) == Instruction::BitCast) {
@@ -359,7 +358,7 @@ Value *Value::getUnderlyingObject() {
return V;
}
assert(isa<PointerType>(V->getType()) && "Unexpected operand type!");
- } while (--MaxLookup);
+ }
return V;
}
diff --git a/lib/VMCore/ValueTypes.cpp b/lib/VMCore/ValueTypes.cpp
index 7f9a6cd..62b9034 100644
--- a/lib/VMCore/ValueTypes.cpp
+++ b/lib/VMCore/ValueTypes.cpp
@@ -36,12 +36,12 @@ EVT EVT::getExtendedVectorVT(LLVMContext &Context, EVT VT,
bool EVT::isExtendedFloatingPoint() const {
assert(isExtended() && "Type is not extended!");
- return LLVMTy->isFPOrFPVector();
+ return LLVMTy->isFPOrFPVectorTy();
}
bool EVT::isExtendedInteger() const {
assert(isExtended() && "Type is not extended!");
- return LLVMTy->isIntOrIntVector();
+ return LLVMTy->isIntOrIntVectorTy();
}
bool EVT::isExtendedVector() const {
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 76d9d43..2b4892b 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -47,7 +47,6 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/Metadata.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/TypeSymbolTable.h"
@@ -162,7 +161,8 @@ namespace {
VerifierFailureAction action;
// What to do if verification fails.
Module *Mod; // Module we are verifying right now
- DominatorTree *DT; // Dominator Tree, caution can be null!
+ LLVMContext *Context; // Context within which we are verifying
+ DominatorTree *DT; // Dominator Tree, caution can be null!
std::string Messages;
raw_string_ostream MessagesStr;
@@ -179,24 +179,25 @@ namespace {
Verifier()
: FunctionPass(&ID),
Broken(false), RealPass(true), action(AbortProcessAction),
- DT(0), MessagesStr(Messages) {}
+ Mod(0), Context(0), DT(0), MessagesStr(Messages) {}
explicit Verifier(VerifierFailureAction ctn)
: FunctionPass(&ID),
- Broken(false), RealPass(true), action(ctn), DT(0),
+ Broken(false), RealPass(true), action(ctn), Mod(0), Context(0), DT(0),
MessagesStr(Messages) {}
explicit Verifier(bool AB)
: FunctionPass(&ID),
Broken(false), RealPass(true),
- action( AB ? AbortProcessAction : PrintMessageAction), DT(0),
- MessagesStr(Messages) {}
+ action( AB ? AbortProcessAction : PrintMessageAction), Mod(0),
+ Context(0), DT(0), MessagesStr(Messages) {}
explicit Verifier(DominatorTree &dt)
: FunctionPass(&ID),
- Broken(false), RealPass(false), action(PrintMessageAction),
- DT(&dt), MessagesStr(Messages) {}
+ Broken(false), RealPass(false), action(PrintMessageAction), Mod(0),
+ Context(0), DT(&dt), MessagesStr(Messages) {}
bool doInitialization(Module &M) {
Mod = &M;
+ Context = &M.getContext();
verifyTypeSymbolTable(M.getTypeSymbolTable());
// If this is a real pass, in a pass manager, we must abort before
@@ -212,6 +213,7 @@ namespace {
if (RealPass) DT = &getAnalysis<DominatorTree>();
Mod = F.getParent();
+ if (!Context) Context = &F.getContext();
visit(F);
InstsInThisBlock.clear();
@@ -315,6 +317,7 @@ namespace {
void visitStoreInst(StoreInst &SI);
void visitInstruction(Instruction &I);
void visitTerminatorInst(TerminatorInst &I);
+ void visitBranchInst(BranchInst &BI);
void visitReturnInst(ReturnInst &RI);
void visitSwitchInst(SwitchInst &SI);
void visitSelectInst(SelectInst &SI);
@@ -413,10 +416,10 @@ void Verifier::visit(Instruction &I) {
void Verifier::visitGlobalValue(GlobalValue &GV) {
Assert1(!GV.isDeclaration() ||
+ GV.isMaterializable() ||
GV.hasExternalLinkage() ||
GV.hasDLLImportLinkage() ||
GV.hasExternalWeakLinkage() ||
- GV.hasGhostLinkage() ||
(isa<GlobalAlias>(GV) &&
(GV.hasLocalLinkage() || GV.hasWeakLinkage())),
"Global is external, but doesn't have external or dllimport or weak linkage!",
@@ -597,6 +600,9 @@ void Verifier::visitFunction(Function &F) {
const FunctionType *FT = F.getFunctionType();
unsigned NumArgs = F.arg_size();
+ Assert1(Context == &F.getContext(),
+ "Function context does not match Module context!", &F);
+
Assert1(!F.hasCommonLinkage(), "Functions may not have common linkage", &F);
Assert2(FT->getNumParams() == NumArgs,
"# formal arguments must match # of arguments for function type!",
@@ -648,9 +654,11 @@ void Verifier::visitFunction(Function &F) {
"Function takes metadata but isn't an intrinsic", I, &F);
}
- if (F.isDeclaration()) {
+ if (F.isMaterializable()) {
+ // Function has a body somewhere we can't see.
+ } else if (F.isDeclaration()) {
Assert1(F.hasExternalLinkage() || F.hasDLLImportLinkage() ||
- F.hasExternalWeakLinkage() || F.hasGhostLinkage(),
+ F.hasExternalWeakLinkage(),
"invalid linkage type for function declaration", &F);
} else {
// Verify that this function (which has a body) is not named "llvm.*". It
@@ -742,6 +750,14 @@ void Verifier::visitTerminatorInst(TerminatorInst &I) {
visitInstruction(I);
}
+void Verifier::visitBranchInst(BranchInst &BI) {
+ if (BI.isConditional()) {
+ Assert2(BI.getCondition()->getType()->isIntegerTy(1),
+ "Branch condition is not 'i1' type!", &BI, BI.getCondition());
+ }
+ visitTerminatorInst(BI);
+}
+
void Verifier::visitReturnInst(ReturnInst &RI) {
Function *F = RI.getParent()->getParent();
unsigned N = RI.getNumOperands();
@@ -820,8 +836,8 @@ void Verifier::visitTruncInst(TruncInst &I) {
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DestBitSize = DestTy->getScalarSizeInBits();
- Assert1(SrcTy->isIntOrIntVector(), "Trunc only operates on integer", &I);
- Assert1(DestTy->isIntOrIntVector(), "Trunc only produces integer", &I);
+ Assert1(SrcTy->isIntOrIntVectorTy(), "Trunc only operates on integer", &I);
+ Assert1(DestTy->isIntOrIntVectorTy(), "Trunc only produces integer", &I);
Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
"trunc source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize > DestBitSize,"DestTy too big for Trunc", &I);
@@ -835,8 +851,8 @@ void Verifier::visitZExtInst(ZExtInst &I) {
const Type *DestTy = I.getType();
// Get the size of the types in bits, we'll need this later
- Assert1(SrcTy->isIntOrIntVector(), "ZExt only operates on integer", &I);
- Assert1(DestTy->isIntOrIntVector(), "ZExt only produces an integer", &I);
+ Assert1(SrcTy->isIntOrIntVectorTy(), "ZExt only operates on integer", &I);
+ Assert1(DestTy->isIntOrIntVectorTy(), "ZExt only produces an integer", &I);
Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
"zext source and destination must both be a vector or neither", &I);
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
@@ -856,8 +872,8 @@ void Verifier::visitSExtInst(SExtInst &I) {
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DestBitSize = DestTy->getScalarSizeInBits();
- Assert1(SrcTy->isIntOrIntVector(), "SExt only operates on integer", &I);
- Assert1(DestTy->isIntOrIntVector(), "SExt only produces an integer", &I);
+ Assert1(SrcTy->isIntOrIntVectorTy(), "SExt only operates on integer", &I);
+ Assert1(DestTy->isIntOrIntVectorTy(), "SExt only produces an integer", &I);
Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
"sext source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize < DestBitSize,"Type too small for SExt", &I);
@@ -873,8 +889,8 @@ void Verifier::visitFPTruncInst(FPTruncInst &I) {
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DestBitSize = DestTy->getScalarSizeInBits();
- Assert1(SrcTy->isFPOrFPVector(),"FPTrunc only operates on FP", &I);
- Assert1(DestTy->isFPOrFPVector(),"FPTrunc only produces an FP", &I);
+ Assert1(SrcTy->isFPOrFPVectorTy(),"FPTrunc only operates on FP", &I);
+ Assert1(DestTy->isFPOrFPVectorTy(),"FPTrunc only produces an FP", &I);
Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
"fptrunc source and destination must both be a vector or neither",&I);
Assert1(SrcBitSize > DestBitSize,"DestTy too big for FPTrunc", &I);
@@ -891,8 +907,8 @@ void Verifier::visitFPExtInst(FPExtInst &I) {
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DestBitSize = DestTy->getScalarSizeInBits();
- Assert1(SrcTy->isFPOrFPVector(),"FPExt only operates on FP", &I);
- Assert1(DestTy->isFPOrFPVector(),"FPExt only produces an FP", &I);
+ Assert1(SrcTy->isFPOrFPVectorTy(),"FPExt only operates on FP", &I);
+ Assert1(DestTy->isFPOrFPVectorTy(),"FPExt only produces an FP", &I);
Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
"fpext source and destination must both be a vector or neither", &I);
Assert1(SrcBitSize < DestBitSize,"DestTy too small for FPExt", &I);
@@ -910,9 +926,9 @@ void Verifier::visitUIToFPInst(UIToFPInst &I) {
Assert1(SrcVec == DstVec,
"UIToFP source and dest must both be vector or scalar", &I);
- Assert1(SrcTy->isIntOrIntVector(),
+ Assert1(SrcTy->isIntOrIntVectorTy(),
"UIToFP source must be integer or integer vector", &I);
- Assert1(DestTy->isFPOrFPVector(),
+ Assert1(DestTy->isFPOrFPVectorTy(),
"UIToFP result must be FP or FP vector", &I);
if (SrcVec && DstVec)
@@ -933,9 +949,9 @@ void Verifier::visitSIToFPInst(SIToFPInst &I) {
Assert1(SrcVec == DstVec,
"SIToFP source and dest must both be vector or scalar", &I);
- Assert1(SrcTy->isIntOrIntVector(),
+ Assert1(SrcTy->isIntOrIntVectorTy(),
"SIToFP source must be integer or integer vector", &I);
- Assert1(DestTy->isFPOrFPVector(),
+ Assert1(DestTy->isFPOrFPVectorTy(),
"SIToFP result must be FP or FP vector", &I);
if (SrcVec && DstVec)
@@ -956,8 +972,9 @@ void Verifier::visitFPToUIInst(FPToUIInst &I) {
Assert1(SrcVec == DstVec,
"FPToUI source and dest must both be vector or scalar", &I);
- Assert1(SrcTy->isFPOrFPVector(), "FPToUI source must be FP or FP vector", &I);
- Assert1(DestTy->isIntOrIntVector(),
+ Assert1(SrcTy->isFPOrFPVectorTy(), "FPToUI source must be FP or FP vector",
+ &I);
+ Assert1(DestTy->isIntOrIntVectorTy(),
"FPToUI result must be integer or integer vector", &I);
if (SrcVec && DstVec)
@@ -978,9 +995,9 @@ void Verifier::visitFPToSIInst(FPToSIInst &I) {
Assert1(SrcVec == DstVec,
"FPToSI source and dest must both be vector or scalar", &I);
- Assert1(SrcTy->isFPOrFPVector(),
+ Assert1(SrcTy->isFPOrFPVectorTy(),
"FPToSI source must be FP or FP vector", &I);
- Assert1(DestTy->isIntOrIntVector(),
+ Assert1(DestTy->isIntOrIntVectorTy(),
"FPToSI result must be integer or integer vector", &I);
if (SrcVec && DstVec)
@@ -997,7 +1014,7 @@ void Verifier::visitPtrToIntInst(PtrToIntInst &I) {
const Type *DestTy = I.getType();
Assert1(isa<PointerType>(SrcTy), "PtrToInt source must be pointer", &I);
- Assert1(DestTy->isInteger(), "PtrToInt result must be integral", &I);
+ Assert1(DestTy->isIntegerTy(), "PtrToInt result must be integral", &I);
visitInstruction(I);
}
@@ -1007,7 +1024,7 @@ void Verifier::visitIntToPtrInst(IntToPtrInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- Assert1(SrcTy->isInteger(), "IntToPtr source must be an integral", &I);
+ Assert1(SrcTy->isIntegerTy(), "IntToPtr source must be an integral", &I);
Assert1(isa<PointerType>(DestTy), "IntToPtr result must be a pointer",&I);
visitInstruction(I);
@@ -1150,7 +1167,7 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
case Instruction::UDiv:
case Instruction::SRem:
case Instruction::URem:
- Assert1(B.getType()->isIntOrIntVector(),
+ Assert1(B.getType()->isIntOrIntVectorTy(),
"Integer arithmetic operators only work with integral types!", &B);
Assert1(B.getType() == B.getOperand(0)->getType(),
"Integer arithmetic operators must have same type "
@@ -1163,7 +1180,7 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
case Instruction::FMul:
case Instruction::FDiv:
case Instruction::FRem:
- Assert1(B.getType()->isFPOrFPVector(),
+ Assert1(B.getType()->isFPOrFPVectorTy(),
"Floating-point arithmetic operators only work with "
"floating-point types!", &B);
Assert1(B.getType() == B.getOperand(0)->getType(),
@@ -1174,7 +1191,7 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
- Assert1(B.getType()->isIntOrIntVector(),
+ Assert1(B.getType()->isIntOrIntVectorTy(),
"Logical operators only work with integral types!", &B);
Assert1(B.getType() == B.getOperand(0)->getType(),
"Logical operators must have same type for operands and result!",
@@ -1183,7 +1200,7 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
- Assert1(B.getType()->isIntOrIntVector(),
+ Assert1(B.getType()->isIntOrIntVectorTy(),
"Shifts only work with integral types!", &B);
Assert1(B.getType() == B.getOperand(0)->getType(),
"Shift return type must be same as operands!", &B);
@@ -1202,7 +1219,7 @@ void Verifier::visitICmpInst(ICmpInst& IC) {
Assert1(Op0Ty == Op1Ty,
"Both operands to ICmp instruction are not of the same type!", &IC);
// Check that the operands are the right type
- Assert1(Op0Ty->isIntOrIntVector() || isa<PointerType>(Op0Ty),
+ Assert1(Op0Ty->isIntOrIntVectorTy() || isa<PointerType>(Op0Ty),
"Invalid operand types for ICmp instruction", &IC);
visitInstruction(IC);
@@ -1215,7 +1232,7 @@ void Verifier::visitFCmpInst(FCmpInst& FC) {
Assert1(Op0Ty == Op1Ty,
"Both operands to FCmp instruction are not of the same type!", &FC);
// Check that the operands are the right type
- Assert1(Op0Ty->isFPOrFPVector(),
+ Assert1(Op0Ty->isFPOrFPVectorTy(),
"Invalid operand types for FCmp instruction", &FC);
visitInstruction(FC);
}
@@ -1301,7 +1318,7 @@ void Verifier::visitAllocaInst(AllocaInst &AI) {
&AI);
Assert1(PTy->getElementType()->isSized(), "Cannot allocate unsized type",
&AI);
- Assert1(AI.getArraySize()->getType()->isInteger(32),
+ Assert1(AI.getArraySize()->getType()->isIntegerTy(32),
"Alloca array size must be i32", &AI);
visitInstruction(AI);
}
@@ -1480,7 +1497,7 @@ void Verifier::visitInstruction(Instruction &I) {
void Verifier::VerifyType(const Type *Ty) {
if (!Types.insert(Ty)) return;
- Assert1(&Mod->getContext() == &Ty->getContext(),
+ Assert1(Context == &Ty->getContext(),
"Type context does not match Module context!", Ty);
switch (Ty->getTypeID()) {
@@ -1733,7 +1750,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
}
}
} else if (VT == MVT::iAny) {
- if (!EltTy->isInteger()) {
+ if (!EltTy->isIntegerTy()) {
CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
"an integer type.", F);
return false;
@@ -1758,7 +1775,7 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty,
break;
}
} else if (VT == MVT::fAny) {
- if (!EltTy->isFloatingPoint()) {
+ if (!EltTy->isFloatingPointTy()) {
CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not "
"a floating-point type.", F);
return false;
@@ -1913,12 +1930,10 @@ bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) {
Function &F = const_cast<Function&>(f);
assert(!F.isDeclaration() && "Cannot verify external functions");
- ExistingModuleProvider MP(F.getParent());
- FunctionPassManager FPM(&MP);
+ FunctionPassManager FPM(F.getParent());
Verifier *V = new Verifier(action);
FPM.add(V);
FPM.run(F);
- MP.releaseModule();
return V->Broken;
}
diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt
index 1a286db..415530e 100644
--- a/projects/CMakeLists.txt
+++ b/projects/CMakeLists.txt
@@ -4,7 +4,7 @@
file(GLOB entries *)
foreach(entry ${entries})
if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt)
- if(NOT (${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt))
+ if(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt)
add_subdirectory(${entry})
endif()
endif()
diff --git a/projects/sample/autoconf/configure.ac b/projects/sample/autoconf/configure.ac
index 37c93a8..221dcc4 100644
--- a/projects/sample/autoconf/configure.ac
+++ b/projects/sample/autoconf/configure.ac
@@ -6,14 +6,15 @@ AC_INIT([[[SAMPLE]]],[[[x.xx]]],[bugs@yourdomain])
dnl Identify where LLVM source tree is
LLVM_SRC_ROOT="../../"
LLVM_OBJ_ROOT="../../"
-dnl Tell autoconf that the auxilliary files are actually located in
-dnl the LLVM autoconf directory, not here.
-AC_CONFIG_AUX_DIR($LLVM_SRC_ROOT/autoconf)
dnl Tell autoconf that this is an LLVM project being configured
dnl This provides the --with-llvmsrc and --with-llvmobj options
LLVM_CONFIG_PROJECT($LLVM_SRC_ROOT,$LLVM_OBJ_ROOT)
+dnl Tell autoconf that the auxilliary files are actually located in
+dnl the LLVM autoconf directory, not here.
+AC_CONFIG_AUX_DIR($LLVM_SRC/autoconf)
+
dnl Verify that the source directory is valid
AC_CONFIG_SRCDIR(["Makefile.common.in"])
diff --git a/test/Analysis/LoopDependenceAnalysis/alias.ll b/test/Analysis/LoopDependenceAnalysis/alias.ll
index a5f504b..97be3fd 100644
--- a/test/Analysis/LoopDependenceAnalysis/alias.ll
+++ b/test/Analysis/LoopDependenceAnalysis/alias.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -disable-output -analyze -lda | FileCheck %s
+; RUN: opt < %s -analyze -lda | FileCheck %s
;; x[5] = x[6] // with x being a pointer passed as argument
diff --git a/test/Analysis/LoopDependenceAnalysis/siv-strong.ll b/test/Analysis/LoopDependenceAnalysis/siv-strong.ll
index 3270895..36ac153 100644
--- a/test/Analysis/LoopDependenceAnalysis/siv-strong.ll
+++ b/test/Analysis/LoopDependenceAnalysis/siv-strong.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -disable-output -analyze -lda | FileCheck %s
+; RUN: opt < %s -analyze -lda | FileCheck %s
@x = common global [256 x i32] zeroinitializer, align 4
@y = common global [256 x i32] zeroinitializer, align 4
diff --git a/test/Analysis/LoopDependenceAnalysis/siv-weak-crossing.ll b/test/Analysis/LoopDependenceAnalysis/siv-weak-crossing.ll
index 3d9f258..a7f9bda 100644
--- a/test/Analysis/LoopDependenceAnalysis/siv-weak-crossing.ll
+++ b/test/Analysis/LoopDependenceAnalysis/siv-weak-crossing.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -disable-output -analyze -lda | FileCheck %s
+; RUN: opt < %s -analyze -lda | FileCheck %s
@x = common global [256 x i32] zeroinitializer, align 4
@y = common global [256 x i32] zeroinitializer, align 4
diff --git a/test/Analysis/LoopDependenceAnalysis/siv-weak-zero.ll b/test/Analysis/LoopDependenceAnalysis/siv-weak-zero.ll
index 4433138..e75aefd 100644
--- a/test/Analysis/LoopDependenceAnalysis/siv-weak-zero.ll
+++ b/test/Analysis/LoopDependenceAnalysis/siv-weak-zero.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -disable-output -analyze -lda | FileCheck %s
+; RUN: opt < %s -analyze -lda | FileCheck %s
@x = common global [256 x i32] zeroinitializer, align 4
@y = common global [256 x i32] zeroinitializer, align 4
diff --git a/test/Analysis/LoopDependenceAnalysis/ziv.ll b/test/Analysis/LoopDependenceAnalysis/ziv.ll
index 0a93762..ba45948 100644
--- a/test/Analysis/LoopDependenceAnalysis/ziv.ll
+++ b/test/Analysis/LoopDependenceAnalysis/ziv.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -disable-output -analyze -lda | FileCheck %s
+; RUN: opt < %s -analyze -lda | FileCheck %s
@x = common global [256 x i32] zeroinitializer, align 4
diff --git a/test/Analysis/ScalarEvolution/2007-07-15-NegativeStride.ll b/test/Analysis/ScalarEvolution/2007-07-15-NegativeStride.ll
index ba57662..7ff130f 100644
--- a/test/Analysis/ScalarEvolution/2007-07-15-NegativeStride.ll
+++ b/test/Analysis/ScalarEvolution/2007-07-15-NegativeStride.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | grep {Loop %bb: backedge-taken count is 100}
; PR1533
diff --git a/test/Analysis/ScalarEvolution/2007-08-06-Unsigned.ll b/test/Analysis/ScalarEvolution/2007-08-06-Unsigned.ll
index ce8f725..ab96243 100644
--- a/test/Analysis/ScalarEvolution/2007-08-06-Unsigned.ll
+++ b/test/Analysis/ScalarEvolution/2007-08-06-Unsigned.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -scalar-evolution -analyze -disable-output | grep {Loop %bb: backedge-taken count is (-1 + (-1 \\* %x) + %y)}
+; RUN: opt < %s -scalar-evolution -analyze | grep {Loop %bb: backedge-taken count is (-1 + (-1 \\* %x) + %y)}
; PR1597
define i32 @f(i32 %x, i32 %y) {
diff --git a/test/Analysis/ScalarEvolution/2007-09-27-LargeStepping.ll b/test/Analysis/ScalarEvolution/2007-09-27-LargeStepping.ll
index 817090f..b678fee 100644
--- a/test/Analysis/ScalarEvolution/2007-09-27-LargeStepping.ll
+++ b/test/Analysis/ScalarEvolution/2007-09-27-LargeStepping.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | grep {backedge-taken count is 13}
; PR1706
diff --git a/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll b/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll
index 27fe714..c12721d 100644
--- a/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll
+++ b/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | FileCheck %s
+; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
; PR1810
define void @fun() {
diff --git a/test/Analysis/ScalarEvolution/2008-02-11-ReversedCondition.ll b/test/Analysis/ScalarEvolution/2008-02-11-ReversedCondition.ll
index 6685778..fe3a7f4 100644
--- a/test/Analysis/ScalarEvolution/2008-02-11-ReversedCondition.ll
+++ b/test/Analysis/ScalarEvolution/2008-02-11-ReversedCondition.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -scalar-evolution -analyze -disable-output | grep {Loop %header: backedge-taken count is (0 smax %n)}
+; RUN: opt < %s -scalar-evolution -analyze | grep {Loop %header: backedge-taken count is (0 smax %n)}
define void @foo(i32 %n) {
entry:
diff --git a/test/Analysis/ScalarEvolution/2008-02-12-SMAXTripCount.ll b/test/Analysis/ScalarEvolution/2008-02-12-SMAXTripCount.ll
index addf346..4f14a0d 100644
--- a/test/Analysis/ScalarEvolution/2008-02-12-SMAXTripCount.ll
+++ b/test/Analysis/ScalarEvolution/2008-02-12-SMAXTripCount.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -scalar-evolution -analyze -disable-output | grep {Loop %loop: backedge-taken count is (100 + (-100 smax %n))}
+; RUN: opt < %s -scalar-evolution -analyze | grep {Loop %loop: backedge-taken count is (100 + (-100 smax %n))}
; PR2002
define void @foo(i8 %n) {
diff --git a/test/Analysis/ScalarEvolution/2008-02-15-UMax.ll b/test/Analysis/ScalarEvolution/2008-02-15-UMax.ll
index bf9f4a9..52c7985 100644
--- a/test/Analysis/ScalarEvolution/2008-02-15-UMax.ll
+++ b/test/Analysis/ScalarEvolution/2008-02-15-UMax.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep umax
+; RUN: opt < %s -analyze -scalar-evolution | grep umax
; PR2003
define i32 @foo(i32 %n) {
diff --git a/test/Analysis/ScalarEvolution/2008-05-25-NegativeStepToZero.ll b/test/Analysis/ScalarEvolution/2008-05-25-NegativeStepToZero.ll
index 8d15b77..bcc124d 100644
--- a/test/Analysis/ScalarEvolution/2008-05-25-NegativeStepToZero.ll
+++ b/test/Analysis/ScalarEvolution/2008-05-25-NegativeStepToZero.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | grep {backedge-taken count is 61}
; PR2364
diff --git a/test/Analysis/ScalarEvolution/2008-07-12-UnneededSelect1.ll b/test/Analysis/ScalarEvolution/2008-07-12-UnneededSelect1.ll
index 850b670..9db9b71 100644
--- a/test/Analysis/ScalarEvolution/2008-07-12-UnneededSelect1.ll
+++ b/test/Analysis/ScalarEvolution/2008-07-12-UnneededSelect1.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output |& not grep smax
+; RUN: opt < %s -analyze -scalar-evolution |& not grep smax
; PR2261
@lut = common global [256 x i8] zeroinitializer, align 32 ; <[256 x i8]*> [#uses=1]
diff --git a/test/Analysis/ScalarEvolution/2008-07-12-UnneededSelect2.ll b/test/Analysis/ScalarEvolution/2008-07-12-UnneededSelect2.ll
index 59e9fda..1847665 100644
--- a/test/Analysis/ScalarEvolution/2008-07-12-UnneededSelect2.ll
+++ b/test/Analysis/ScalarEvolution/2008-07-12-UnneededSelect2.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output |& not grep smax
+; RUN: opt < %s -analyze -scalar-evolution |& not grep smax
; PR2070
define i32 @a(i32 %x) nounwind {
diff --git a/test/Analysis/ScalarEvolution/2008-07-19-InfiniteLoop.ll b/test/Analysis/ScalarEvolution/2008-07-19-InfiniteLoop.ll
index 989ac51..1865c05 100644
--- a/test/Analysis/ScalarEvolution/2008-07-19-InfiniteLoop.ll
+++ b/test/Analysis/ScalarEvolution/2008-07-19-InfiniteLoop.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | grep Unpredictable
; PR2088
diff --git a/test/Analysis/ScalarEvolution/2008-07-19-WrappingIV.ll b/test/Analysis/ScalarEvolution/2008-07-19-WrappingIV.ll
index 803c7d1..86e07ec4 100644
--- a/test/Analysis/ScalarEvolution/2008-07-19-WrappingIV.ll
+++ b/test/Analysis/ScalarEvolution/2008-07-19-WrappingIV.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | grep {backedge-taken count is 113}
; PR2088
diff --git a/test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll b/test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll
index 37b5b94..75bd634 100644
--- a/test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll
+++ b/test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | FileCheck %s
; PR2607
diff --git a/test/Analysis/ScalarEvolution/2008-07-29-SMinExpr.ll b/test/Analysis/ScalarEvolution/2008-07-29-SMinExpr.ll
index d54b3b4..1626c1f 100644
--- a/test/Analysis/ScalarEvolution/2008-07-29-SMinExpr.ll
+++ b/test/Analysis/ScalarEvolution/2008-07-29-SMinExpr.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | FileCheck %s
; PR2607
diff --git a/test/Analysis/ScalarEvolution/2008-08-04-IVOverflow.ll b/test/Analysis/ScalarEvolution/2008-08-04-IVOverflow.ll
index 06200ae..3b31d79 100644
--- a/test/Analysis/ScalarEvolution/2008-08-04-IVOverflow.ll
+++ b/test/Analysis/ScalarEvolution/2008-08-04-IVOverflow.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | FileCheck %s
; PR2621
diff --git a/test/Analysis/ScalarEvolution/2008-08-04-LongAddRec.ll b/test/Analysis/ScalarEvolution/2008-08-04-LongAddRec.ll
index f3c703a..b296a19 100644
--- a/test/Analysis/ScalarEvolution/2008-08-04-LongAddRec.ll
+++ b/test/Analysis/ScalarEvolution/2008-08-04-LongAddRec.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | FileCheck %s
; PR2621
diff --git a/test/Analysis/ScalarEvolution/2008-11-02-QuadraticCrash.ll b/test/Analysis/ScalarEvolution/2008-11-02-QuadraticCrash.ll
index 9daff99..7722122 100644
--- a/test/Analysis/ScalarEvolution/2008-11-02-QuadraticCrash.ll
+++ b/test/Analysis/ScalarEvolution/2008-11-02-QuadraticCrash.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output
+; RUN: opt < %s -analyze -scalar-evolution
; PR1827
declare void @use(i32)
diff --git a/test/Analysis/ScalarEvolution/2008-11-15-CubicOOM.ll b/test/Analysis/ScalarEvolution/2008-11-15-CubicOOM.ll
index 5a2c366..2e2aabc 100644
--- a/test/Analysis/ScalarEvolution/2008-11-15-CubicOOM.ll
+++ b/test/Analysis/ScalarEvolution/2008-11-15-CubicOOM.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output
+; RUN: opt < %s -analyze -scalar-evolution
; PR2602
define i32 @a() nounwind {
diff --git a/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll b/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll
index f9dd40f..06637b5 100644
--- a/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll
+++ b/test/Analysis/ScalarEvolution/2008-11-18-LessThanOrEqual.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output |& \
+; RUN: opt < %s -analyze -scalar-evolution |& \
; RUN: grep {Loop %bb: backedge-taken count is (7 + (-1 \\* %argc))}
; XFAIL: *
diff --git a/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll b/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll
index 9ee781f..db527fe 100644
--- a/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll
+++ b/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: | grep {Loop %bb: Unpredictable backedge-taken count\\.}
; ScalarEvolution can't compute a trip count because it doesn't know if
diff --git a/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll b/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll
index bcbe92f..102acc6 100644
--- a/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll
+++ b/test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output |& grep {/u 3}
+; RUN: opt < %s -analyze -scalar-evolution |& grep {/u 3}
; XFAIL: *
define i32 @f(i32 %x) nounwind readnone {
diff --git a/test/Analysis/ScalarEvolution/2008-12-08-FiniteSGE.ll b/test/Analysis/ScalarEvolution/2008-12-08-FiniteSGE.ll
index 2ee107a..226221b 100644
--- a/test/Analysis/ScalarEvolution/2008-12-08-FiniteSGE.ll
+++ b/test/Analysis/ScalarEvolution/2008-12-08-FiniteSGE.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep {backedge-taken count is 255}
+; RUN: opt < %s -analyze -scalar-evolution | grep {backedge-taken count is 255}
; XFAIL: *
define i32 @foo(i32 %x, i32 %y, i32* %lam, i32* %alp) nounwind {
diff --git a/test/Analysis/ScalarEvolution/2008-12-11-SMaxOverflow.ll b/test/Analysis/ScalarEvolution/2008-12-11-SMaxOverflow.ll
index 0cfd84c..33a7479 100644
--- a/test/Analysis/ScalarEvolution/2008-12-11-SMaxOverflow.ll
+++ b/test/Analysis/ScalarEvolution/2008-12-11-SMaxOverflow.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep {0 smax}
+; RUN: opt < %s -analyze -scalar-evolution | grep {0 smax}
; XFAIL: *
define i32 @f(i32 %c.idx.val) {
diff --git a/test/Analysis/ScalarEvolution/2008-12-14-StrideAndSigned.ll b/test/Analysis/ScalarEvolution/2008-12-14-StrideAndSigned.ll
index 4ec358c..8152e98 100644
--- a/test/Analysis/ScalarEvolution/2008-12-14-StrideAndSigned.ll
+++ b/test/Analysis/ScalarEvolution/2008-12-14-StrideAndSigned.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output |& \
+; RUN: opt < %s -analyze -scalar-evolution |& \
; RUN: grep {(((-1 \\* %i0) + (100005 smax %i0)) /u 5)}
; XFAIL: *
diff --git a/test/Analysis/ScalarEvolution/2008-12-15-DontUseSDiv.ll b/test/Analysis/ScalarEvolution/2008-12-15-DontUseSDiv.ll
index 1fe1068..3eaa492 100644
--- a/test/Analysis/ScalarEvolution/2008-12-15-DontUseSDiv.ll
+++ b/test/Analysis/ScalarEvolution/2008-12-15-DontUseSDiv.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output |& grep {/u 5}
+; RUN: opt < %s -analyze -scalar-evolution |& grep {/u 5}
; XFAIL: *
define i8 @foo0(i8 %i0) nounwind {
diff --git a/test/Analysis/ScalarEvolution/2009-01-02-SignedNegativeStride.ll b/test/Analysis/ScalarEvolution/2009-01-02-SignedNegativeStride.ll
index 9d13695..cc2a2e4 100644
--- a/test/Analysis/ScalarEvolution/2009-01-02-SignedNegativeStride.ll
+++ b/test/Analysis/ScalarEvolution/2009-01-02-SignedNegativeStride.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | not grep {/u -1}
+; RUN: opt < %s -analyze -scalar-evolution | not grep {/u -1}
; PR3275
@g_16 = external global i16 ; <i16*> [#uses=3]
diff --git a/test/Analysis/ScalarEvolution/2009-04-22-TruncCast.ll b/test/Analysis/ScalarEvolution/2009-04-22-TruncCast.ll
index 78a7fd0..c2e108a 100644
--- a/test/Analysis/ScalarEvolution/2009-04-22-TruncCast.ll
+++ b/test/Analysis/ScalarEvolution/2009-04-22-TruncCast.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep {(trunc i} | not grep ext
+; RUN: opt < %s -analyze -scalar-evolution | grep {(trunc i} | not grep ext
define i16 @test1(i8 %x) {
%A = sext i8 %x to i32
diff --git a/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll b/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll
index e81530e..dc7bd29 100644
--- a/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll
+++ b/test/Analysis/ScalarEvolution/2009-05-09-PointerEdgeCount.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep {count is 2}
+; RUN: opt < %s -analyze -scalar-evolution | grep {count is 2}
; PR3171
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
diff --git a/test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll b/test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll
index fcc6fc3..9573aed 100644
--- a/test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll
+++ b/test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | grep {backedge-taken count is 100}
; PR1101
diff --git a/test/Analysis/ScalarEvolution/and-xor.ll b/test/Analysis/ScalarEvolution/and-xor.ll
index 90d947f..1772573 100644
--- a/test/Analysis/ScalarEvolution/and-xor.ll
+++ b/test/Analysis/ScalarEvolution/and-xor.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -scalar-evolution -analyze -disable-output \
+; RUN: opt < %s -scalar-evolution -analyze \
; RUN: | grep {\\--> (zext} | count 2
define i32 @foo(i32 %x) {
diff --git a/test/Analysis/ScalarEvolution/avoid-infinite-recursion-0.ll b/test/Analysis/ScalarEvolution/avoid-infinite-recursion-0.ll
index f638eb3..7eeb308 100644
--- a/test/Analysis/ScalarEvolution/avoid-infinite-recursion-0.ll
+++ b/test/Analysis/ScalarEvolution/avoid-infinite-recursion-0.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output
+; RUN: opt < %s -analyze -scalar-evolution
; PR4537
; ModuleID = 'b.bc'
diff --git a/test/Analysis/ScalarEvolution/avoid-smax-0.ll b/test/Analysis/ScalarEvolution/avoid-smax-0.ll
index 55d3bd5..24275f9 100644
--- a/test/Analysis/ScalarEvolution/avoid-smax-0.ll
+++ b/test/Analysis/ScalarEvolution/avoid-smax-0.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -scalar-evolution -analyze -disable-output | grep {Loop %bb3: backedge-taken count is (-1 + %n)}
+; RUN: opt < %s -scalar-evolution -analyze | grep {Loop %bb3: backedge-taken count is (-1 + %n)}
; We don't want to use a max in the trip count expression in
; this testcase.
diff --git a/test/Analysis/ScalarEvolution/div-overflow.ll b/test/Analysis/ScalarEvolution/div-overflow.ll
index 0c01044..4f6f1e2 100644
--- a/test/Analysis/ScalarEvolution/div-overflow.ll
+++ b/test/Analysis/ScalarEvolution/div-overflow.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -scalar-evolution -analyze -disable-output \
+; RUN: opt < %s -scalar-evolution -analyze \
; RUN: | grep {\\--> ((-128 \\* %a) /u -128)}
; Don't let ScalarEvolution fold this div away.
diff --git a/test/Analysis/ScalarEvolution/do-loop.ll b/test/Analysis/ScalarEvolution/do-loop.ll
index f8d7da7..6e3295a 100644
--- a/test/Analysis/ScalarEvolution/do-loop.ll
+++ b/test/Analysis/ScalarEvolution/do-loop.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep smax
+; RUN: opt < %s -analyze -scalar-evolution | grep smax
; PR1614
define i32 @f(i32 %x, i32 %y) {
diff --git a/test/Analysis/ScalarEvolution/max-trip-count.ll b/test/Analysis/ScalarEvolution/max-trip-count.ll
index a4fdcd0..a8966be 100644
--- a/test/Analysis/ScalarEvolution/max-trip-count.ll
+++ b/test/Analysis/ScalarEvolution/max-trip-count.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: | grep {\{%d,+,\[^\{\}\]\*\}<%bb>}
; ScalarEvolution should be able to understand the loop and eliminate the casts.
diff --git a/test/Analysis/ScalarEvolution/nsw-offset.ll b/test/Analysis/ScalarEvolution/nsw-offset.ll
index fd0dfe6..4cd9a6d 100644
--- a/test/Analysis/ScalarEvolution/nsw-offset.ll
+++ b/test/Analysis/ScalarEvolution/nsw-offset.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -S -analyze -scalar-evolution -disable-output | FileCheck %s
+; RUN: opt < %s -S -analyze -scalar-evolution | FileCheck %s
; ScalarEvolution should be able to fold away the sign-extensions
; on this loop with a primary induction variable incremented with
@@ -6,8 +6,9 @@
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
-define void @foo(i32 %n, double* nocapture %d, double* nocapture %q) nounwind {
+define void @foo(i32 %no, double* nocapture %d, double* nocapture %q) nounwind {
entry:
+ %n = and i32 %no, 4294967294
%0 = icmp sgt i32 %n, 0 ; <i1> [#uses=1]
br i1 %0, label %bb.nph, label %return
@@ -73,4 +74,4 @@ return: ; preds = %bb1.return_crit_edg
}
; CHECK: Loop %bb: backedge-taken count is ((-1 + %n) /u 2)
-; CHECK: Loop %bb: max backedge-taken count is 1073741823
+; CHECK: Loop %bb: max backedge-taken count is 1073741822
diff --git a/test/Analysis/ScalarEvolution/nsw.ll b/test/Analysis/ScalarEvolution/nsw.ll
index e4f2b29..456f3f0 100644
--- a/test/Analysis/ScalarEvolution/nsw.ll
+++ b/test/Analysis/ScalarEvolution/nsw.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep { --> {.*,+,.*}<%bb>} | count 8
+; RUN: opt < %s -analyze -scalar-evolution | grep { --> {.*,+,.*}<%bb>} | count 8
; The addrecs in this loop are analyzable only by using nsw information.
diff --git a/test/Analysis/ScalarEvolution/pointer-sign-bits.ll b/test/Analysis/ScalarEvolution/pointer-sign-bits.ll
index 4de006c..b2cec2d 100644
--- a/test/Analysis/ScalarEvolution/pointer-sign-bits.ll
+++ b/test/Analysis/ScalarEvolution/pointer-sign-bits.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output
+; RUN: opt < %s -analyze -scalar-evolution
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
%JavaObject = type { [0 x i32 (...)*]*, i8* }
diff --git a/test/Analysis/ScalarEvolution/sext-inreg.ll b/test/Analysis/ScalarEvolution/sext-inreg.ll
index 44878225..23e1210 100644
--- a/test/Analysis/ScalarEvolution/sext-inreg.ll
+++ b/test/Analysis/ScalarEvolution/sext-inreg.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output > %t
+; RUN: opt < %s -analyze -scalar-evolution > %t
; RUN: grep {sext i57 \{0,+,199\}<%bb> to i64} %t | count 1
; RUN: grep {sext i59 \{0,+,199\}<%bb> to i64} %t | count 1
diff --git a/test/Analysis/ScalarEvolution/sext-iv-0.ll b/test/Analysis/ScalarEvolution/sext-iv-0.ll
index 05983c1..2af794f 100644
--- a/test/Analysis/ScalarEvolution/sext-iv-0.ll
+++ b/test/Analysis/ScalarEvolution/sext-iv-0.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -disable-output -scalar-evolution -analyze \
+; RUN: opt < %s -scalar-evolution -analyze \
; RUN: | grep { --> \{-128,+,1\}<%bb1> Exits: 127} | count 5
; Convert (sext {-128,+,1}) to {sext(-128),+,sext(1)}, since the
diff --git a/test/Analysis/ScalarEvolution/sext-iv-1.ll b/test/Analysis/ScalarEvolution/sext-iv-1.ll
index 0bf51d9..9063cbb 100644
--- a/test/Analysis/ScalarEvolution/sext-iv-1.ll
+++ b/test/Analysis/ScalarEvolution/sext-iv-1.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -disable-output -scalar-evolution -analyze \
+; RUN: opt < %s -scalar-evolution -analyze \
; RUN: | grep { --> (sext i. \{.\*,+,.\*\}<%bb1> to i64)} | count 5
; Don't convert (sext {...,+,...}) to {sext(...),+,sext(...)} in cases
diff --git a/test/Analysis/ScalarEvolution/sext-iv-2.ll b/test/Analysis/ScalarEvolution/sext-iv-2.ll
index fc39cae..97e252c 100644
--- a/test/Analysis/ScalarEvolution/sext-iv-2.ll
+++ b/test/Analysis/ScalarEvolution/sext-iv-2.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | FileCheck %s
+; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
; CHECK: %tmp3 = sext i8 %tmp2 to i32
; CHECK: --> (sext i8 {0,+,1}<%bb1> to i32) Exits: -1
diff --git a/test/Analysis/ScalarEvolution/smax.ll b/test/Analysis/ScalarEvolution/smax.ll
index 39de8d6..15dd744 100644
--- a/test/Analysis/ScalarEvolution/smax.ll
+++ b/test/Analysis/ScalarEvolution/smax.ll
@@ -1,5 +1,5 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep smax | count 2
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep \
+; RUN: opt < %s -analyze -scalar-evolution | grep smax | count 2
+; RUN: opt < %s -analyze -scalar-evolution | grep \
; RUN: {%. smax %. smax %.}
; PR1614
diff --git a/test/Analysis/ScalarEvolution/trip-count.ll b/test/Analysis/ScalarEvolution/trip-count.ll
index 66cc304..d750d4a 100644
--- a/test/Analysis/ScalarEvolution/trip-count.ll
+++ b/test/Analysis/ScalarEvolution/trip-count.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: -scalar-evolution-max-iterations=0 | grep {backedge-taken count is 10000}
; PR1101
diff --git a/test/Analysis/ScalarEvolution/trip-count2.ll b/test/Analysis/ScalarEvolution/trip-count2.ll
index bbe6435..79f3161 100644
--- a/test/Analysis/ScalarEvolution/trip-count2.ll
+++ b/test/Analysis/ScalarEvolution/trip-count2.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output | \
+; RUN: opt < %s -analyze -scalar-evolution | \
; RUN: grep {backedge-taken count is 4}
; PR1101
diff --git a/test/Analysis/ScalarEvolution/trip-count3.ll b/test/Analysis/ScalarEvolution/trip-count3.ll
index 7d8e0c6..10b798b 100644
--- a/test/Analysis/ScalarEvolution/trip-count3.ll
+++ b/test/Analysis/ScalarEvolution/trip-count3.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -scalar-evolution -analyze -disable-output \
+; RUN: opt < %s -scalar-evolution -analyze \
; RUN: | grep {Loop %bb3\\.i: Unpredictable backedge-taken count\\.}
; ScalarEvolution can't compute a trip count because it doesn't know if
diff --git a/test/Analysis/ScalarEvolution/trip-count4.ll b/test/Analysis/ScalarEvolution/trip-count4.ll
index e8d59cf..116f62d 100644
--- a/test/Analysis/ScalarEvolution/trip-count4.ll
+++ b/test/Analysis/ScalarEvolution/trip-count4.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: | grep {sext.*trunc.*Exits: 11}
; ScalarEvolution should be able to compute a loop exit value for %indvar.i8.
diff --git a/test/Analysis/ScalarEvolution/trip-count5.ll b/test/Analysis/ScalarEvolution/trip-count5.ll
index 2512a96..1194a1d 100644
--- a/test/Analysis/ScalarEvolution/trip-count5.ll
+++ b/test/Analysis/ScalarEvolution/trip-count5.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output > %t
+; RUN: opt < %s -analyze -scalar-evolution > %t
; RUN: grep sext %t | count 2
; RUN: not grep {(sext} %t
diff --git a/test/Analysis/ScalarEvolution/trip-count6.ll b/test/Analysis/ScalarEvolution/trip-count6.ll
index 5833286..956fb81 100644
--- a/test/Analysis/ScalarEvolution/trip-count6.ll
+++ b/test/Analysis/ScalarEvolution/trip-count6.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -disable-output -scalar-evolution \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: | grep {max backedge-taken count is 1\$}
@mode_table = global [4 x i32] zeroinitializer ; <[4 x i32]*> [#uses=1]
diff --git a/test/Analysis/ScalarEvolution/trip-count7.ll b/test/Analysis/ScalarEvolution/trip-count7.ll
index 74c856f..a8b797e 100644
--- a/test/Analysis/ScalarEvolution/trip-count7.ll
+++ b/test/Analysis/ScalarEvolution/trip-count7.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: | grep {Loop %bb7.i: Unpredictable backedge-taken count\\.}
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
diff --git a/test/Analysis/ScalarEvolution/trip-count8.ll b/test/Analysis/ScalarEvolution/trip-count8.ll
index 5063342..ac5ee60 100644
--- a/test/Analysis/ScalarEvolution/trip-count8.ll
+++ b/test/Analysis/ScalarEvolution/trip-count8.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: | grep {Loop %for\\.body: backedge-taken count is (-1 + \[%\]ecx)}
; PR4599
diff --git a/test/Analysis/ScalarEvolution/trip-count9.ll b/test/Analysis/ScalarEvolution/trip-count9.ll
new file mode 100644
index 0000000..9180f2b
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/trip-count9.ll
@@ -0,0 +1,408 @@
+; RUN: opt -analyze -scalar-evolution -S < %s | FileCheck %s
+
+; Every combination of
+; - starting at 0, 1, or %x
+; - steping by 1 or 2
+; - stopping at %n or %n*2
+; - using nsw, or not
+
+; Some of these represent missed opportunities.
+
+; CHECK: Determining loop execution counts for: @foo
+; CHECK: Loop %loop: backedge-taken count is (-1 + %n)
+; CHECK: Loop %loop: max backedge-taken count is 6
+define void @foo(i4 %n) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 0, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 1
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @step2
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: Unpredictable max backedge-taken count.
+define void @step2(i4 %n) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 0, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 2
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @start1
+; CHECK: Loop %loop: backedge-taken count is (-2 + (2 smax %n))
+; CHECK: Loop %loop: max backedge-taken count is 5
+define void @start1(i4 %n) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 1, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 1
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @start1_step2
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: Unpredictable max backedge-taken count.
+define void @start1_step2(i4 %n) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 1, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 2
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @startx
+; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax %n))
+; CHECK: Loop %loop: max backedge-taken count is -1
+define void @startx(i4 %n, i4 %x) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ %x, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 1
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @startx_step2
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: Unpredictable max backedge-taken count.
+define void @startx_step2(i4 %n, i4 %x) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ %x, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 2
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @nsw
+; CHECK: Loop %loop: backedge-taken count is (-1 + %n)
+; CHECK: Loop %loop: max backedge-taken count is 6
+define void @nsw(i4 %n) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 0, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 1
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; Be careful with this one. If %n is INT4_MAX, %i.next will wrap. The nsw bit
+; says that the result is undefined, but ScalarEvolution must respect that
+; subsequent passes may result the undefined behavior in predictable ways.
+; CHECK: Determining loop execution counts for: @nsw_step2
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: Unpredictable max backedge-taken count.
+define void @nsw_step2(i4 %n) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 0, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 2
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @nsw_start1
+; CHECK: Loop %loop: backedge-taken count is (-2 + (2 smax %n))
+; CHECK: Loop %loop: max backedge-taken count is 5
+define void @nsw_start1(i4 %n) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 1, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 1
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @nsw_start1_step2
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: Unpredictable max backedge-taken count.
+define void @nsw_start1_step2(i4 %n) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 1, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 2
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @nsw_startx
+; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax %n))
+; CHECK: Loop %loop: max backedge-taken count is -1
+define void @nsw_startx(i4 %n, i4 %x) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ %x, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 1
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @nsw_startx_step2
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: Unpredictable max backedge-taken count.
+define void @nsw_startx_step2(i4 %n, i4 %x) {
+entry:
+ %s = icmp sgt i4 %n, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ %x, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 2
+ %t = icmp slt i4 %i.next, %n
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even
+; CHECK: Loop %loop: backedge-taken count is (-1 + (2 * %n))
+; CHECK: Loop %loop: max backedge-taken count is 5
+define void @even(i4 %n) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 0, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 1
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_step2
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: max backedge-taken count is 2
+define void @even_step2(i4 %n) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 0, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 2
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_start1
+; CHECK: Loop %loop: backedge-taken count is (-2 + (2 smax (2 * %n)))
+; CHECK: Loop %loop: max backedge-taken count is 4
+define void @even_start1(i4 %n) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 1, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 1
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_start1_step2
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: max backedge-taken count is 2
+define void @even_start1_step2(i4 %n) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 1, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 2
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_startx
+; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax (2 * %n)))
+; CHECK: Loop %loop: max backedge-taken count is -1
+define void @even_startx(i4 %n, i4 %x) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ %x, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 1
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_startx_step2
+; CHECK: Loop %loop: Unpredictable backedge-taken count.
+; CHECK: Loop %loop: max backedge-taken count is 7
+define void @even_startx_step2(i4 %n, i4 %x) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ %x, %entry ], [ %i.next, %loop ]
+ %i.next = add i4 %i, 2
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_nsw
+; CHECK: Loop %loop: backedge-taken count is (-1 + (2 * %n))
+; CHECK: Loop %loop: max backedge-taken count is 5
+define void @even_nsw(i4 %n) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 0, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 1
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_nsw_step2
+; CHECK: Loop %loop: backedge-taken count is ((-1 + (2 * %n)) /u 2)
+; CHECK: Loop %loop: max backedge-taken count is 2
+define void @even_nsw_step2(i4 %n) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 0, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 2
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_nsw_start1
+; CHECK: Loop %loop: backedge-taken count is (-2 + (2 smax (2 * %n)))
+; CHECK: Loop %loop: max backedge-taken count is 4
+define void @even_nsw_start1(i4 %n) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 1, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 1
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_nsw_start1_step2
+; CHECK: Loop %loop: backedge-taken count is ((-2 + (3 smax (2 * %n))) /u 2)
+; CHECK: Loop %loop: max backedge-taken count is 2
+define void @even_nsw_start1_step2(i4 %n) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ 1, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 2
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_nsw_startx
+; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax (2 * %n)))
+; CHECK: Loop %loop: max backedge-taken count is -1
+define void @even_nsw_startx(i4 %n, i4 %x) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ %x, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 1
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
+
+; CHECK: Determining loop execution counts for: @even_nsw_startx_step2
+; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax (2 * %n))) /u 2)
+; CHECK: Loop %loop: max backedge-taken count is 7
+define void @even_nsw_startx_step2(i4 %n, i4 %x) {
+entry:
+ %m = shl i4 %n, 1
+ %s = icmp sgt i4 %m, 0
+ br i1 %s, label %loop, label %exit
+loop:
+ %i = phi i4 [ %x, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i4 %i, 2
+ %t = icmp slt i4 %i.next, %m
+ br i1 %t, label %loop, label %exit
+exit:
+ ret void
+}
diff --git a/test/Analysis/ScalarEvolution/xor-and.ll b/test/Analysis/ScalarEvolution/xor-and.ll
index c8339d7..c0530bb 100644
--- a/test/Analysis/ScalarEvolution/xor-and.ll
+++ b/test/Analysis/ScalarEvolution/xor-and.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -scalar-evolution -disable-output -analyze \
+; RUN: opt < %s -scalar-evolution -analyze \
; RUN: | grep {\\--> (zext i4 (-8 + (trunc i64 (8 \\* %x) to i4)) to i64)}
; ScalarEvolution shouldn't try to analyze %z into something like
diff --git a/test/Analysis/ScalarEvolution/zext-wrap.ll b/test/Analysis/ScalarEvolution/zext-wrap.ll
index c4ac5de..38d15ff 100644
--- a/test/Analysis/ScalarEvolution/zext-wrap.ll
+++ b/test/Analysis/ScalarEvolution/zext-wrap.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -scalar-evolution -disable-output \
+; RUN: opt < %s -analyze -scalar-evolution \
; RUN: | FileCheck %s
; PR4569
diff --git a/test/Archive/MacOSX.a b/test/Archive/MacOSX.a
index 77f88a2..8ba1e6d 100644
--- a/test/Archive/MacOSX.a
+++ b/test/Archive/MacOSX.a
Binary files differ
diff --git a/test/Archive/MacOSX.toc b/test/Archive/MacOSX.toc
index 61cbd3b..f971df7 100644
--- a/test/Archive/MacOSX.toc
+++ b/test/Archive/MacOSX.toc
Binary files differ
diff --git a/test/Assembler/2010-01-06-UnionType.ll b/test/Assembler/2010-01-06-UnionType.ll
new file mode 100644
index 0000000..37130d6
--- /dev/null
+++ b/test/Assembler/2010-01-06-UnionType.ll
@@ -0,0 +1,3 @@
+; RUN: llvm-as %s -o /dev/null
+
+%X = type union { i32, i32* }
diff --git a/test/Assembler/2010-02-05-FunctionLocalMetadataBecomesNull.ll b/test/Assembler/2010-02-05-FunctionLocalMetadataBecomesNull.ll
new file mode 100644
index 0000000..b2256b1
--- /dev/null
+++ b/test/Assembler/2010-02-05-FunctionLocalMetadataBecomesNull.ll
@@ -0,0 +1,25 @@
+; RUN: opt -std-compile-opts < %s | llvm-dis | not grep badref
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin10.2"
+
+%struct.anon = type { i32, i32 }
+%struct.test = type { i64, %struct.anon, %struct.test* }
+
+@TestArrayPtr = global %struct.test* getelementptr inbounds ([10 x %struct.test]* @TestArray, i64 0, i64 3) ; <%struct.test**> [#uses=1]
+@TestArray = common global [10 x %struct.test] zeroinitializer, align 32 ; <[10 x %struct.test]*> [#uses=2]
+
+define i32 @main() nounwind readonly {
+ %diff1 = alloca i64 ; <i64*> [#uses=2]
+ call void @llvm.dbg.declare(metadata !{i64* %diff1}, metadata !0)
+ store i64 72, i64* %diff1, align 8
+ %v1 = load %struct.test** @TestArrayPtr, align 8 ; <%struct.test*> [#uses=1]
+ %v2 = ptrtoint %struct.test* %v1 to i64 ; <i64> [#uses=1]
+ %v3 = sub i64 %v2, ptrtoint ([10 x %struct.test]* @TestArray to i64) ; <i64> [#uses=1]
+ store i64 %v3, i64* %diff1, align 8
+ ret i32 4
+}
+
+declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
+
+!0 = metadata !{i32 459008, metadata !0, metadata !0, metadata !0, i32 38, metadata !0} ; [ DW_TAG_auto_variable ]
diff --git a/test/Assembler/functionlocal-metadata.ll b/test/Assembler/functionlocal-metadata.ll
index 16bc9d0..216587d 100644
--- a/test/Assembler/functionlocal-metadata.ll
+++ b/test/Assembler/functionlocal-metadata.ll
@@ -2,6 +2,8 @@
define void @Foo(i32 %a, i32 %b) {
entry:
+ call void @llvm.dbg.value(metadata !{ i32* %1 }, i64 16, metadata !"bar")
+; CHECK: call void @llvm.dbg.value(metadata !{i32* %1}, i64 16, metadata !"bar")
%0 = add i32 %a, 1 ; <i32> [#uses=1]
%two = add i32 %b, %0 ; <i32> [#uses=0]
%1 = alloca i32 ; <i32*> [#uses=1]
diff --git a/test/Bitcode/flags.ll b/test/Bitcode/flags.ll
new file mode 100644
index 0000000..7b0c5b5
--- /dev/null
+++ b/test/Bitcode/flags.ll
@@ -0,0 +1,27 @@
+; RUN: llvm-as < %s | llvm-dis > %t0
+; RUN: opt -S < %s > %t1
+; RUN: diff %t0 %t1
+; PR6140
+
+; Make sure the flags are serialized/deserialized properly for both
+; forward and backward references.
+
+define void @foo() nounwind {
+entry:
+ br label %first
+
+second: ; preds = %first
+ %u = add nuw i32 %a, 0 ; <i32> [#uses=0]
+ %s = add nsw i32 %a, 0 ; <i32> [#uses=0]
+ %us = add nuw nsw i32 %a, 0 ; <i32> [#uses=0]
+ %z = add i32 %a, 0 ; <i32> [#uses=0]
+ unreachable
+
+first: ; preds = %entry
+ %a = bitcast i32 0 to i32 ; <i32> [#uses=8]
+ %uu = add nuw i32 %a, 0 ; <i32> [#uses=0]
+ %ss = add nsw i32 %a, 0 ; <i32> [#uses=0]
+ %uuss = add nuw nsw i32 %a, 0 ; <i32> [#uses=0]
+ %zz = add i32 %a, 0 ; <i32> [#uses=0]
+ br label %second
+}
diff --git a/test/CodeGen/ARM/2009-10-30.ll b/test/CodeGen/ARM/2009-10-30.ll
index 8256386..90a5bd2 100644
--- a/test/CodeGen/ARM/2009-10-30.ll
+++ b/test/CodeGen/ARM/2009-10-30.ll
@@ -5,8 +5,8 @@
define void @f(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, ...) {
entry:
;CHECK: sub sp, sp, #4
-;CHECK: add r0, sp, #8
-;CHECK: str r0, [sp], #+4
+;CHECK: add r{{[0-9]+}}, sp, #8
+;CHECK: str r{{[0-9]+}}, [sp], #+4
;CHECK: bx lr
%ap = alloca i8*, align 4
%ap1 = bitcast i8** %ap to i8*
diff --git a/test/CodeGen/ARM/aliases.ll b/test/CodeGen/ARM/aliases.ll
index b2c0314..31c5007 100644
--- a/test/CodeGen/ARM/aliases.ll
+++ b/test/CodeGen/ARM/aliases.ll
@@ -1,5 +1,5 @@
; RUN: llc < %s -mtriple=arm-linux-gnueabi -o %t
-; RUN: grep set %t | count 5
+; RUN: grep { = } %t | count 5
; RUN: grep globl %t | count 4
; RUN: grep weak %t | count 1
diff --git a/test/CodeGen/ARM/align.ll b/test/CodeGen/ARM/align.ll
index d73abe6a..d4d0128 100644
--- a/test/CodeGen/ARM/align.ll
+++ b/test/CodeGen/ARM/align.ll
@@ -1,15 +1,42 @@
-; RUN: llc < %s -march=arm | grep align.*1 | count 1
-; RUN: llc < %s -mtriple=arm-linux-gnueabi | \
-; RUN: grep align.*2 | count 2
-; RUN: llc < %s -mtriple=arm-linux-gnueabi | \
-; RUN: grep align.*3 | count 2
-; RUN: llc < %s -mtriple=arm-apple-darwin | \
-; RUN: grep align.*2 | count 4
+; RUN: llc < %s -mtriple=arm-linux-gnueabi | FileCheck %s -check-prefix=ELF
+; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=DARWIN
@a = global i1 true
+; no alignment
+
@b = global i8 1
+; no alignment
+
@c = global i16 2
+;ELF: .align 1
+;ELF: c:
+;DARWIN: .align 1
+;DARWIN: _c:
+
@d = global i32 3
+;ELF: .align 2
+;ELF: d:
+;DARWIN: .align 2
+;DARWIN: _d:
+
@e = global i64 4
+;ELF: .align 3
+;ELF: e
+;DARWIN: .align 2
+;DARWIN: _e:
+
@f = global float 5.0
+;ELF: .align 2
+;ELF: f:
+;DARWIN: .align 2
+;DARWIN: _f:
+
@g = global double 6.0
+;ELF: .align 3
+;ELF: g:
+;DARWIN: .align 2
+;DARWIN: _g:
+
+@bar = common global [75 x i8] zeroinitializer, align 128
+;ELF: .comm bar,75,128
+;DARWIN: .comm _bar,75,7
diff --git a/test/CodeGen/ARM/arm-negative-stride.ll b/test/CodeGen/ARM/arm-negative-stride.ll
index 72ec8ef..52ab871 100644
--- a/test/CodeGen/ARM/arm-negative-stride.ll
+++ b/test/CodeGen/ARM/arm-negative-stride.ll
@@ -1,7 +1,32 @@
; RUN: llc < %s -march=arm | FileCheck %s
+; This loop is rewritten with an indvar which counts down, which
+; frees up a register from holding the trip count.
+
define void @test(i32* %P, i32 %A, i32 %i) nounwind {
entry:
+; CHECK: str r1, [{{r.*}}, +{{r.*}}, lsl #2]
+ icmp eq i32 %i, 0 ; <i1>:0 [#uses=1]
+ br i1 %0, label %return, label %bb
+
+bb: ; preds = %bb, %entry
+ %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=2]
+ %i_addr.09.0 = sub i32 %i, %indvar ; <i32> [#uses=1]
+ %tmp2 = getelementptr i32* %P, i32 %i_addr.09.0 ; <i32*> [#uses=1]
+ store i32 %A, i32* %tmp2
+ %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2]
+ icmp eq i32 %indvar.next, %i ; <i1>:1 [#uses=1]
+ br i1 %1, label %return, label %bb
+
+return: ; preds = %bb, %entry
+ ret void
+}
+
+; This loop has a non-address use of the count-up indvar, so
+; it'll remain. Now the original store uses a negative-stride address.
+
+define void @test_with_forced_iv(i32* %P, i32 %A, i32 %i) nounwind {
+entry:
; CHECK: str r1, [{{r.*}}, -{{r.*}}, lsl #2]
icmp eq i32 %i, 0 ; <i1>:0 [#uses=1]
br i1 %0, label %return, label %bb
@@ -11,6 +36,7 @@ bb: ; preds = %bb, %entry
%i_addr.09.0 = sub i32 %i, %indvar ; <i32> [#uses=1]
%tmp2 = getelementptr i32* %P, i32 %i_addr.09.0 ; <i32*> [#uses=1]
store i32 %A, i32* %tmp2
+ store i32 %indvar, i32* null
%indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2]
icmp eq i32 %indvar.next, %i ; <i1>:1 [#uses=1]
br i1 %1, label %return, label %bb
diff --git a/test/CodeGen/ARM/iabs.ll b/test/CodeGen/ARM/iabs.ll
index 1054f27..63808b2 100644
--- a/test/CodeGen/ARM/iabs.ll
+++ b/test/CodeGen/ARM/iabs.ll
@@ -1,5 +1,4 @@
-; RUN: llc < %s -march=arm -stats |& \
-; RUN: grep {3 .*Number of machine instrs printed}
+; RUN: llc < %s -march=arm | FileCheck %s
;; Integer absolute value, should produce something as good as: ARM:
;; add r3, r0, r0, asr #31
@@ -11,5 +10,7 @@ define i32 @test(i32 %a) {
%b = icmp sgt i32 %a, -1
%abs = select i1 %b, i32 %a, i32 %tmp1neg
ret i32 %abs
+; CHECK: add r1, r0, r0, asr #31
+; CHECK: eor r0, r1, r0, asr #31
+; CHECK: bx lr
}
-
diff --git a/test/CodeGen/ARM/long_shift.ll b/test/CodeGen/ARM/long_shift.ll
index 688b7bc..76332cc 100644
--- a/test/CodeGen/ARM/long_shift.ll
+++ b/test/CodeGen/ARM/long_shift.ll
@@ -23,10 +23,10 @@ define i32 @f1(i64 %x, i64 %y) {
define i32 @f2(i64 %x, i64 %y) {
; CHECK: f2
; CHECK: mov r0, r0, lsr r2
-; CHECK-NEXT: rsb r3, r2, #32
+; CHECK-NEXT: rsb r12, r2, #32
; CHECK-NEXT: sub r2, r2, #32
; CHECK-NEXT: cmp r2, #0
-; CHECK-NEXT: orr r0, r0, r1, lsl r3
+; CHECK-NEXT: orr r0, r0, r1, lsl r12
; CHECK-NEXT: movge r0, r1, asr r2
%a = ashr i64 %x, %y
%b = trunc i64 %a to i32
@@ -36,10 +36,10 @@ define i32 @f2(i64 %x, i64 %y) {
define i32 @f3(i64 %x, i64 %y) {
; CHECK: f3
; CHECK: mov r0, r0, lsr r2
-; CHECK-NEXT: rsb r3, r2, #32
+; CHECK-NEXT: rsb r12, r2, #32
; CHECK-NEXT: sub r2, r2, #32
; CHECK-NEXT: cmp r2, #0
-; CHECK-NEXT: orr r0, r0, r1, lsl r3
+; CHECK-NEXT: orr r0, r0, r1, lsl r12
; CHECK-NEXT: movge r0, r1, lsr r2
%a = lshr i64 %x, %y
%b = trunc i64 %a to i32
diff --git a/test/CodeGen/ARM/lsr-code-insertion.ll b/test/CodeGen/ARM/lsr-code-insertion.ll
index 507ec2c..1bbb96d 100644
--- a/test/CodeGen/ARM/lsr-code-insertion.ll
+++ b/test/CodeGen/ARM/lsr-code-insertion.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -stats |& grep {40.*Number of machine instrs printed}
-; RUN: llc < %s -stats |& grep {.*Number of re-materialization}
+; RUN: llc < %s -stats |& grep {39.*Number of machine instrs printed}
+; RUN: llc < %s -stats |& not grep {.*Number of re-materialization}
; This test really wants to check that the resultant "cond_true" block only
; has a single store in it, and that cond_true55 only has code to materialize
; the constant and do a store. We do *not* want something like this:
diff --git a/test/CodeGen/ARM/remat-2.ll b/test/CodeGen/ARM/remat-2.ll
deleted file mode 100644
index 1a871d2..0000000
--- a/test/CodeGen/ARM/remat-2.ll
+++ /dev/null
@@ -1,65 +0,0 @@
-; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 -stats -info-output-file - | grep "Number of re-materialization"
-
-define arm_apcscc i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
-entry:
- br i1 undef, label %smvp.exit, label %bb.i3
-
-bb.i3: ; preds = %bb.i3, %bb134
- br i1 undef, label %smvp.exit, label %bb.i3
-
-smvp.exit: ; preds = %bb.i3
- %0 = fmul double undef, 2.400000e-03 ; <double> [#uses=2]
- br i1 undef, label %bb138.preheader, label %bb159
-
-bb138.preheader: ; preds = %smvp.exit
- br label %bb138
-
-bb138: ; preds = %bb138, %bb138.preheader
- br i1 undef, label %bb138, label %bb145.loopexit
-
-bb142: ; preds = %bb.nph218.bb.nph218.split_crit_edge, %phi0.exit
- %1 = fmul double undef, -1.200000e-03 ; <double> [#uses=1]
- %2 = fadd double undef, %1 ; <double> [#uses=1]
- %3 = fmul double %2, undef ; <double> [#uses=1]
- %4 = fsub double 0.000000e+00, %3 ; <double> [#uses=1]
- br i1 %14, label %phi1.exit, label %bb.i35
-
-bb.i35: ; preds = %bb142
- %5 = call arm_apcscc double @sin(double %15) nounwind readonly ; <double> [#uses=1]
- %6 = fmul double %5, 0x4031740AFA84AD8A ; <double> [#uses=1]
- %7 = fsub double 1.000000e+00, undef ; <double> [#uses=1]
- %8 = fdiv double %7, 6.000000e-01 ; <double> [#uses=1]
- br label %phi1.exit
-
-phi1.exit: ; preds = %bb.i35, %bb142
- %.pn = phi double [ %6, %bb.i35 ], [ 0.000000e+00, %bb142 ] ; <double> [#uses=0]
- %9 = phi double [ %8, %bb.i35 ], [ 0.000000e+00, %bb142 ] ; <double> [#uses=1]
- %10 = fmul double undef, %9 ; <double> [#uses=0]
- br i1 %14, label %phi0.exit, label %bb.i
-
-bb.i: ; preds = %phi1.exit
- unreachable
-
-phi0.exit: ; preds = %phi1.exit
- %11 = fsub double %4, undef ; <double> [#uses=1]
- %12 = fadd double 0.000000e+00, %11 ; <double> [#uses=1]
- store double %12, double* undef, align 4
- br label %bb142
-
-bb145.loopexit: ; preds = %bb138
- br i1 undef, label %bb.nph218.bb.nph218.split_crit_edge, label %bb159
-
-bb.nph218.bb.nph218.split_crit_edge: ; preds = %bb145.loopexit
- %13 = fmul double %0, 0x401921FB54442D18 ; <double> [#uses=1]
- %14 = fcmp ugt double %0, 6.000000e-01 ; <i1> [#uses=2]
- %15 = fdiv double %13, 6.000000e-01 ; <double> [#uses=1]
- br label %bb142
-
-bb159: ; preds = %bb145.loopexit, %smvp.exit, %bb134
- unreachable
-
-bb166: ; preds = %bb127
- unreachable
-}
-
-declare arm_apcscc double @sin(double) nounwind readonly
diff --git a/test/CodeGen/ARM/remat.ll b/test/CodeGen/ARM/remat.ll
index 9565c8b..92c1cf1 100644
--- a/test/CodeGen/ARM/remat.ll
+++ b/test/CodeGen/ARM/remat.ll
@@ -1,119 +1,65 @@
-; RUN: llc < %s -mtriple=arm-apple-darwin
-; RUN: llc < %s -mtriple=arm-apple-darwin -stats -info-output-file - | grep "Number of re-materialization" | grep 3
+; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 -stats -info-output-file - | grep "Number of re-materialization"
- %struct.CONTENTBOX = type { i32, i32, i32, i32, i32 }
- %struct.LOCBOX = type { i32, i32, i32, i32 }
- %struct.SIDEBOX = type { i32, i32 }
- %struct.UNCOMBOX = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }
- %struct.cellbox = type { i8*, i32, i32, i32, [9 x i32], i32, i32, i32, i32, i32, i32, i32, double, double, double, double, double, i32, i32, %struct.CONTENTBOX*, %struct.UNCOMBOX*, [8 x %struct.tilebox*], %struct.SIDEBOX* }
- %struct.termbox = type { %struct.termbox*, i32, i32, i32, i32, i32 }
- %struct.tilebox = type { %struct.tilebox*, double, double, double, double, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.termbox*, %struct.LOCBOX* }
-@numcells = external global i32 ; <i32*> [#uses=1]
-@cellarray = external global %struct.cellbox** ; <%struct.cellbox***> [#uses=1]
-@numBinsY = external global i32 ; <i32*> [#uses=1]
-
-define fastcc void @fixpenal() {
+define arm_apcscc i32 @main(i32 %argc, i8** nocapture %argv, double %d1, double %d2) nounwind {
entry:
- %tmp491 = load i32* @numcells, align 4 ; <i32> [#uses=1]
- %tmp9 = load %struct.cellbox*** @cellarray, align 4 ; <%struct.cellbox**> [#uses=1]
- %tmp77.i = load i32* @numBinsY, align 4 ; <i32> [#uses=2]
- br label %bb490
-
-bb8: ; preds = %bb490, %cond_false428
- %foo3 = phi i1 [ 0, %bb490 ], [ 1, %cond_false428 ]
- br i1 %foo3, label %cond_false58.i, label %cond_false.i
-
-cond_false.i: ; preds = %bb8
- ret void
-
-cond_false58.i: ; preds = %bb8
- %highBinX.0.i = select i1 false, i32 1, i32 0 ; <i32> [#uses=2]
- br i1 %foo3, label %cond_next85.i, label %cond_false76.i
-
-cond_false76.i: ; preds = %cond_false58.i
- ret void
-
-cond_next85.i: ; preds = %cond_false58.i
- br i1 %foo3, label %cond_next105.i, label %cond_false98.i
-
-cond_false98.i: ; preds = %cond_next85.i
- ret void
-
-cond_next105.i: ; preds = %cond_next85.i
- %tmp108.i = icmp eq i32 1, %highBinX.0.i ; <i1> [#uses=1]
- %tmp115.i = icmp eq i32 1, %tmp77.i ; <i1> [#uses=1]
- %bothcond.i = and i1 %tmp115.i, %tmp108.i ; <i1> [#uses=1]
- %storemerge.i = select i1 %bothcond.i, i32 1, i32 0 ; <i32> [#uses=2]
- br i1 %bothcond.i, label %whoOverlaps.exit, label %bb503.preheader.i
-
-bb503.preheader.i: ; preds = %bb513.i, %cond_next105.i
- %i.022.0.i = phi i32 [ %tmp512.i, %bb513.i ], [ 0, %cond_next105.i ] ; <i32> [#uses=2]
- %tmp165.i = getelementptr i32*** null, i32 %i.022.0.i ; <i32***> [#uses=0]
- br label %bb503.i
-
-bb137.i: ; preds = %bb503.i
- br i1 %tmp506.i, label %bb162.i, label %bb148.i
-
-bb148.i: ; preds = %bb137.i
- ret void
-
-bb162.i: ; preds = %bb137.i
- %tmp49435.i = load i32* null ; <i32> [#uses=1]
- br label %bb170.i
-
-bb170.i: ; preds = %bb491.i, %bb162.i
- %indvar.i = phi i32 [ %k.032.0.i, %bb491.i ], [ 0, %bb162.i ] ; <i32> [#uses=2]
- %k.032.0.i = add i32 %indvar.i, 1 ; <i32> [#uses=2]
- %tmp173.i = getelementptr i32* null, i32 %k.032.0.i ; <i32*> [#uses=1]
- %tmp174.i = load i32* %tmp173.i ; <i32> [#uses=4]
- %tmp177.i = icmp eq i32 %tmp174.i, %cell.1 ; <i1> [#uses=1]
- %tmp184.i = icmp sgt i32 %tmp174.i, %tmp491 ; <i1> [#uses=1]
- %bothcond = or i1 %tmp177.i, %tmp184.i ; <i1> [#uses=1]
- br i1 %bothcond, label %bb491.i, label %cond_next188.i
-
-cond_next188.i: ; preds = %bb170.i
- %tmp191.i = getelementptr %struct.cellbox** %tmp9, i32 %tmp174.i ; <%struct.cellbox**> [#uses=1]
- %tmp192.i = load %struct.cellbox** %tmp191.i ; <%struct.cellbox*> [#uses=1]
- %tmp195.i = icmp eq i32 %tmp174.i, 0 ; <i1> [#uses=1]
- br i1 %tmp195.i, label %bb491.i, label %cond_true198.i
-
-cond_true198.i: ; preds = %cond_next188.i
- %tmp210.i = getelementptr %struct.cellbox* %tmp192.i, i32 0, i32 3 ; <i32*> [#uses=0]
- ret void
-
-bb491.i: ; preds = %cond_next188.i, %bb170.i
- %tmp490.i = add i32 %indvar.i, 2 ; <i32> [#uses=1]
- %tmp496.i = icmp slt i32 %tmp49435.i, %tmp490.i ; <i1> [#uses=1]
- br i1 %tmp496.i, label %bb500.i, label %bb170.i
-
-bb500.i: ; preds = %bb491.i
- %indvar.next82.i = add i32 %j.0.i, 1 ; <i32> [#uses=1]
- br label %bb503.i
-
-bb503.i: ; preds = %bb500.i, %bb503.preheader.i
- %j.0.i = phi i32 [ 0, %bb503.preheader.i ], [ %indvar.next82.i, %bb500.i ] ; <i32> [#uses=2]
- %tmp506.i = icmp sgt i32 %j.0.i, %tmp77.i ; <i1> [#uses=1]
- br i1 %tmp506.i, label %bb513.i, label %bb137.i
-
-bb513.i: ; preds = %bb503.i
- %tmp512.i = add i32 %i.022.0.i, 1 ; <i32> [#uses=2]
- %tmp516.i = icmp sgt i32 %tmp512.i, %highBinX.0.i ; <i1> [#uses=1]
- br i1 %tmp516.i, label %whoOverlaps.exit, label %bb503.preheader.i
-
-whoOverlaps.exit: ; preds = %bb513.i, %cond_next105.i
- %foo = phi i1 [ 1, %bb513.i], [0, %cond_next105.i]
- br i1 %foo, label %cond_false428, label %bb490
-
-cond_false428: ; preds = %whoOverlaps.exit
- br i1 %foo, label %bb497, label %bb8
-
-bb490: ; preds = %whoOverlaps.exit, %entry
- %binY.tmp.2 = phi i32 [ 0, %entry ], [ %storemerge.i, %whoOverlaps.exit ] ; <i32> [#uses=1]
- %cell.1 = phi i32 [ 1, %entry ], [ 0, %whoOverlaps.exit ] ; <i32> [#uses=1]
- %foo2 = phi i1 [ 1, %entry], [0, %whoOverlaps.exit]
- br i1 %foo2, label %bb497, label %bb8
-
-bb497: ; preds = %bb490, %cond_false428
- %binY.tmp.3 = phi i32 [ %binY.tmp.2, %bb490 ], [ %storemerge.i, %cond_false428 ] ; <i32> [#uses=0]
- ret void
+ br i1 undef, label %smvp.exit, label %bb.i3
+
+bb.i3: ; preds = %bb.i3, %bb134
+ br i1 undef, label %smvp.exit, label %bb.i3
+
+smvp.exit: ; preds = %bb.i3
+ %0 = fmul double %d1, 2.400000e-03 ; <double> [#uses=2]
+ br i1 undef, label %bb138.preheader, label %bb159
+
+bb138.preheader: ; preds = %smvp.exit
+ br label %bb138
+
+bb138: ; preds = %bb138, %bb138.preheader
+ br i1 undef, label %bb138, label %bb145.loopexit
+
+bb142: ; preds = %bb.nph218.bb.nph218.split_crit_edge, %phi0.exit
+ %1 = fmul double %d1, -1.200000e-03 ; <double> [#uses=1]
+ %2 = fadd double %d2, %1 ; <double> [#uses=1]
+ %3 = fmul double %2, %d2 ; <double> [#uses=1]
+ %4 = fsub double 0.000000e+00, %3 ; <double> [#uses=1]
+ br i1 %14, label %phi1.exit, label %bb.i35
+
+bb.i35: ; preds = %bb142
+ %5 = call arm_apcscc double @sin(double %15) nounwind readonly ; <double> [#uses=1]
+ %6 = fmul double %5, 0x4031740AFA84AD8A ; <double> [#uses=1]
+ %7 = fsub double 1.000000e+00, undef ; <double> [#uses=1]
+ %8 = fdiv double %7, 6.000000e-01 ; <double> [#uses=1]
+ br label %phi1.exit
+
+phi1.exit: ; preds = %bb.i35, %bb142
+ %.pn = phi double [ %6, %bb.i35 ], [ 0.000000e+00, %bb142 ] ; <double> [#uses=1]
+ %9 = phi double [ %8, %bb.i35 ], [ 0.000000e+00, %bb142 ] ; <double> [#uses=1]
+ %10 = fmul double %.pn, %9 ; <double> [#uses=1]
+ br i1 %14, label %phi0.exit, label %bb.i
+
+bb.i: ; preds = %phi1.exit
+ unreachable
+
+phi0.exit: ; preds = %phi1.exit
+ %11 = fsub double %4, %10 ; <double> [#uses=1]
+ %12 = fadd double 0.000000e+00, %11 ; <double> [#uses=1]
+ store double %12, double* undef, align 4
+ br label %bb142
+
+bb145.loopexit: ; preds = %bb138
+ br i1 undef, label %bb.nph218.bb.nph218.split_crit_edge, label %bb159
+
+bb.nph218.bb.nph218.split_crit_edge: ; preds = %bb145.loopexit
+ %13 = fmul double %0, 0x401921FB54442D18 ; <double> [#uses=1]
+ %14 = fcmp ugt double %0, 6.000000e-01 ; <i1> [#uses=2]
+ %15 = fdiv double %13, 6.000000e-01 ; <double> [#uses=1]
+ br label %bb142
+
+bb159: ; preds = %bb145.loopexit, %smvp.exit, %bb134
+ unreachable
+
+bb166: ; preds = %bb127
+ unreachable
}
+
+declare arm_apcscc double @sin(double) nounwind readonly
diff --git a/test/CodeGen/ARM/unaligned_load_store.ll b/test/CodeGen/ARM/unaligned_load_store.ll
index fcaa2b3..a4494f3 100644
--- a/test/CodeGen/ARM/unaligned_load_store.ll
+++ b/test/CodeGen/ARM/unaligned_load_store.ll
@@ -1,6 +1,6 @@
; RUN: llc < %s -march=arm | FileCheck %s -check-prefix=GENERIC
; RUN: llc < %s -mtriple=armv6-apple-darwin | FileCheck %s -check-prefix=DARWIN_V6
-; RUN: llc < %s -march=arm -mattr=+v7a | FileCheck %s -check-prefix=V7
+; RUN: llc < %s -mtriple=armv6-linux | FileCheck %s -check-prefix=GENERIC
; rdar://7113725
@@ -20,9 +20,6 @@ entry:
; DARWIN_V6: ldr r1
; DARWIN_V6: str r1
-; V7: t:
-; V7: ldr r1
-; V7: str r1
%__src1.i = bitcast i8* %b to i32* ; <i32*> [#uses=1]
%__dest2.i = bitcast i8* %a to i32* ; <i32*> [#uses=1]
%tmp.i = load i32* %__src1.i, align 1 ; <i32> [#uses=1]
diff --git a/test/CodeGen/Generic/2006-04-11-vecload.ll b/test/CodeGen/Generic/2006-04-11-vecload.ll
deleted file mode 100644
index a68ed83..0000000
--- a/test/CodeGen/Generic/2006-04-11-vecload.ll
+++ /dev/null
@@ -1,12 +0,0 @@
-; RUN: llc < %s -march=x86 -mcpu=yonah
-
-; The vload was getting memoized to the previous scalar load!
-
-define void @VertexProgram2() {
- %xFloat0.688 = load float* null ; <float> [#uses=0]
- %loadVector37.712 = load <4 x float>* null ; <<4 x float>> [#uses=1]
- %inFloat3.713 = insertelement <4 x float> %loadVector37.712, float 0.000000e+00, i32 3 ; <<4 x float>> [#uses=1]
- store <4 x float> %inFloat3.713, <4 x float>* null
- unreachable
-}
-
diff --git a/test/CodeGen/Generic/2006-11-06-MemIntrinsicExpand.ll b/test/CodeGen/Generic/2006-11-06-MemIntrinsicExpand.ll
deleted file mode 100644
index ad3e49f..0000000
--- a/test/CodeGen/Generic/2006-11-06-MemIntrinsicExpand.ll
+++ /dev/null
@@ -1,11 +0,0 @@
-; RUN: llc < %s -march=x86 | not grep adc
-; PR987
-
-declare void @llvm.memcpy.i64(i8*, i8*, i64, i32)
-
-define void @foo(i64 %a) {
- %b = add i64 %a, 1 ; <i64> [#uses=1]
- call void @llvm.memcpy.i64( i8* null, i8* null, i64 %b, i32 1 )
- ret void
-}
-
diff --git a/test/CodeGen/Generic/2007-04-14-BitTestsBadMask.ll b/test/CodeGen/Generic/2007-04-14-BitTestsBadMask.ll
deleted file mode 100644
index 00337b9..0000000
--- a/test/CodeGen/Generic/2007-04-14-BitTestsBadMask.ll
+++ /dev/null
@@ -1,160 +0,0 @@
-; RUN: llc < %s -march=x86 | grep 8388635
-; RUN: llc < %s -march=x86-64 | grep 4294981120
-; PR 1325
-
-; ModuleID = 'bugpoint.test.bc'
-target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
-target triple = "powerpc-apple-darwin8.8.0"
-;target triple = "i686-linux-gnu"
- %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
- %struct.__sFILEX = type opaque
- %struct.__sbuf = type { i8*, i32 }
-@PL_rsfp = external global %struct.FILE* ; <%struct.FILE**> [#uses=1]
-@PL_bufend = external global i8* ; <i8**> [#uses=1]
-@PL_in_eval = external global i32 ; <i32*> [#uses=1]
-
-declare fastcc void @incline(i8*)
-
-define i16 @Perl_skipspace_bb60(i8* %s, i8** %s_addr.4.out) {
-newFuncRoot:
- %tmp138.loc = alloca i8* ; <i8**> [#uses=2]
- %s_addr.4.loc = alloca i8* ; <i8**> [#uses=2]
- %tmp274.loc = alloca i8* ; <i8**> [#uses=2]
- br label %bb60
-
-cond_next154.UnifiedReturnBlock_crit_edge.exitStub: ; preds = %codeRepl
- store i8* %s_addr.4.reload, i8** %s_addr.4.out
- ret i16 0
-
-cond_next161.UnifiedReturnBlock_crit_edge.exitStub: ; preds = %codeRepl
- store i8* %s_addr.4.reload, i8** %s_addr.4.out
- ret i16 1
-
-cond_next167.UnifiedReturnBlock_crit_edge.exitStub: ; preds = %codeRepl
- store i8* %s_addr.4.reload, i8** %s_addr.4.out
- ret i16 2
-
-cond_false29.i.cond_true190_crit_edge.exitStub: ; preds = %codeRepl
- store i8* %s_addr.4.reload, i8** %s_addr.4.out
- ret i16 3
-
-cond_next.i.cond_true190_crit_edge.exitStub: ; preds = %codeRepl
- store i8* %s_addr.4.reload, i8** %s_addr.4.out
- ret i16 4
-
-cond_true19.i.cond_true190_crit_edge.exitStub: ; preds = %codeRepl
- store i8* %s_addr.4.reload, i8** %s_addr.4.out
- ret i16 5
-
-bb60: ; preds = %bb60.backedge, %newFuncRoot
- %s_addr.2 = phi i8* [ %s, %newFuncRoot ], [ %s_addr.2.be, %bb60.backedge ] ; <i8*> [#uses=3]
- %tmp61 = load i8** @PL_bufend ; <i8*> [#uses=1]
- %tmp63 = icmp ult i8* %s_addr.2, %tmp61 ; <i1> [#uses=1]
- br i1 %tmp63, label %bb60.cond_next67_crit_edge, label %bb60.bb101_crit_edge
-
-bb37: ; preds = %cond_next67.bb37_crit_edge5, %cond_next67.bb37_crit_edge4, %cond_next67.bb37_crit_edge3, %cond_next67.bb37_crit_edge2, %cond_next67.bb37_crit_edge
- %tmp40 = icmp eq i8 %tmp69, 10 ; <i1> [#uses=1]
- %tmp43 = getelementptr i8* %s_addr.27.2, i32 1 ; <i8*> [#uses=5]
- br i1 %tmp40, label %cond_true45, label %bb37.bb60_crit_edge
-
-cond_true45: ; preds = %bb37
- %tmp46 = volatile load i32* @PL_in_eval ; <i32> [#uses=1]
- %tmp47 = icmp eq i32 %tmp46, 0 ; <i1> [#uses=1]
- br i1 %tmp47, label %cond_true45.bb60_crit_edge, label %cond_true50
-
-cond_true50: ; preds = %cond_true45
- %tmp51 = volatile load %struct.FILE** @PL_rsfp ; <%struct.FILE*> [#uses=1]
- %tmp52 = icmp eq %struct.FILE* %tmp51, null ; <i1> [#uses=1]
- br i1 %tmp52, label %cond_true55, label %cond_true50.bb60_crit_edge
-
-cond_true55: ; preds = %cond_true50
- tail call fastcc void @incline( i8* %tmp43 )
- br label %bb60.backedge
-
-cond_next67: ; preds = %Perl_newSV.exit.cond_next67_crit_edge, %cond_true148.cond_next67_crit_edge, %bb60.cond_next67_crit_edge
- %s_addr.27.2 = phi i8* [ %s_addr.2, %bb60.cond_next67_crit_edge ], [ %tmp274.reload, %Perl_newSV.exit.cond_next67_crit_edge ], [ %tmp138.reload, %cond_true148.cond_next67_crit_edge ] ; <i8*> [#uses=3]
- %tmp69 = load i8* %s_addr.27.2 ; <i8> [#uses=2]
- switch i8 %tmp69, label %cond_next67.bb101_crit_edge [
- i8 32, label %cond_next67.bb37_crit_edge
- i8 9, label %cond_next67.bb37_crit_edge2
- i8 10, label %cond_next67.bb37_crit_edge3
- i8 13, label %cond_next67.bb37_crit_edge4
- i8 12, label %cond_next67.bb37_crit_edge5
- ]
-
-codeRepl: ; preds = %bb101.preheader
- %targetBlock = call i16 @Perl_skipspace_bb60_bb101( i8* %s_addr.27.3.ph, i8** %tmp274.loc, i8** %s_addr.4.loc, i8** %tmp138.loc ) ; <i16> [#uses=1]
- %tmp274.reload = load i8** %tmp274.loc ; <i8*> [#uses=4]
- %s_addr.4.reload = load i8** %s_addr.4.loc ; <i8*> [#uses=6]
- %tmp138.reload = load i8** %tmp138.loc ; <i8*> [#uses=1]
- switch i16 %targetBlock, label %cond_true19.i.cond_true190_crit_edge.exitStub [
- i16 0, label %cond_next271.bb60_crit_edge
- i16 1, label %cond_true290.bb60_crit_edge
- i16 2, label %cond_true295.bb60_crit_edge
- i16 3, label %Perl_newSV.exit.cond_next67_crit_edge
- i16 4, label %cond_true148.cond_next67_crit_edge
- i16 5, label %cond_next154.UnifiedReturnBlock_crit_edge.exitStub
- i16 6, label %cond_next161.UnifiedReturnBlock_crit_edge.exitStub
- i16 7, label %cond_next167.UnifiedReturnBlock_crit_edge.exitStub
- i16 8, label %cond_false29.i.cond_true190_crit_edge.exitStub
- i16 9, label %cond_next.i.cond_true190_crit_edge.exitStub
- ]
-
-bb37.bb60_crit_edge: ; preds = %bb37
- br label %bb60.backedge
-
-cond_true45.bb60_crit_edge: ; preds = %cond_true45
- br label %bb60.backedge
-
-cond_true50.bb60_crit_edge: ; preds = %cond_true50
- br label %bb60.backedge
-
-bb60.cond_next67_crit_edge: ; preds = %bb60
- br label %cond_next67
-
-bb60.bb101_crit_edge: ; preds = %bb60
- br label %bb101.preheader
-
-cond_next67.bb101_crit_edge: ; preds = %cond_next67
- br label %bb101.preheader
-
-cond_next67.bb37_crit_edge: ; preds = %cond_next67
- br label %bb37
-
-cond_next67.bb37_crit_edge2: ; preds = %cond_next67
- br label %bb37
-
-cond_next67.bb37_crit_edge3: ; preds = %cond_next67
- br label %bb37
-
-cond_next67.bb37_crit_edge4: ; preds = %cond_next67
- br label %bb37
-
-cond_next67.bb37_crit_edge5: ; preds = %cond_next67
- br label %bb37
-
-cond_true148.cond_next67_crit_edge: ; preds = %codeRepl
- br label %cond_next67
-
-cond_next271.bb60_crit_edge: ; preds = %codeRepl
- br label %bb60.backedge
-
-cond_true290.bb60_crit_edge: ; preds = %codeRepl
- br label %bb60.backedge
-
-cond_true295.bb60_crit_edge: ; preds = %codeRepl
- br label %bb60.backedge
-
-Perl_newSV.exit.cond_next67_crit_edge: ; preds = %codeRepl
- br label %cond_next67
-
-bb101.preheader: ; preds = %cond_next67.bb101_crit_edge, %bb60.bb101_crit_edge
- %s_addr.27.3.ph = phi i8* [ %s_addr.27.2, %cond_next67.bb101_crit_edge ], [ %s_addr.2, %bb60.bb101_crit_edge ] ; <i8*> [#uses=1]
- br label %codeRepl
-
-bb60.backedge: ; preds = %cond_true295.bb60_crit_edge, %cond_true290.bb60_crit_edge, %cond_next271.bb60_crit_edge, %cond_true50.bb60_crit_edge, %cond_true45.bb60_crit_edge, %bb37.bb60_crit_edge, %cond_true55
- %s_addr.2.be = phi i8* [ %tmp43, %cond_true55 ], [ %tmp43, %bb37.bb60_crit_edge ], [ %tmp43, %cond_true45.bb60_crit_edge ], [ %tmp43, %cond_true50.bb60_crit_edge ], [ %tmp274.reload, %cond_next271.bb60_crit_edge ], [ %tmp274.reload, %cond_true290.bb60_crit_edge ], [ %tmp274.reload, %cond_true295.bb60_crit_edge ] ; <i8*> [#uses=1]
- br label %bb60
-}
-
-declare i16 @Perl_skipspace_bb60_bb101(i8*, i8**, i8**, i8**)
diff --git a/test/CodeGen/Generic/2007-04-27-BitTestsBadMask.ll b/test/CodeGen/Generic/2007-04-27-BitTestsBadMask.ll
deleted file mode 100644
index 3e8857f..0000000
--- a/test/CodeGen/Generic/2007-04-27-BitTestsBadMask.ll
+++ /dev/null
@@ -1,18 +0,0 @@
-; RUN: llc < %s -march=x86 | grep je | count 3
-; RUN: llc < %s -march=x86-64 | grep 4297064449
-; PR 1325+
-
-define i32 @foo(i8 %bar) {
-entry:
- switch i8 %bar, label %bb1203 [
- i8 117, label %bb1204
- i8 85, label %bb1204
- i8 106, label %bb1204
- ]
-
-bb1203: ; preds = %entry
- ret i32 1
-
-bb1204: ; preds = %entry, %entry, %entry
- ret i32 2
-}
diff --git a/test/CodeGen/Generic/2007-05-03-EHTypeInfo.ll b/test/CodeGen/Generic/2007-05-03-EHTypeInfo.ll
index 533aa4a..bb774b4 100644
--- a/test/CodeGen/Generic/2007-05-03-EHTypeInfo.ll
+++ b/test/CodeGen/Generic/2007-05-03-EHTypeInfo.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -enable-eh -march=x86
+; RUN: llc < %s -enable-eh
%struct.exception = type { i8, i8, i32, i8*, i8*, i32, i8* }
@program_error = external global %struct.exception ; <%struct.exception*> [#uses=1]
diff --git a/test/CodeGen/Generic/2007-05-05-Personality.ll b/test/CodeGen/Generic/2007-05-05-Personality.ll
index 2749326..c92783e 100644
--- a/test/CodeGen/Generic/2007-05-05-Personality.ll
+++ b/test/CodeGen/Generic/2007-05-05-Personality.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=i686-pc-linux-gnu -enable-eh -o - | grep zPLR
+; RUN: llc < %s -mtriple=i686-pc-linux-gnu -enable-eh -o - | grep zPL
@error = external global i8 ; <i8*> [#uses=2]
diff --git a/test/CodeGen/Generic/2007-06-06-CriticalEdgeLandingPad.ll b/test/CodeGen/Generic/2007-06-06-CriticalEdgeLandingPad.ll
deleted file mode 100644
index 1519fe6..0000000
--- a/test/CodeGen/Generic/2007-06-06-CriticalEdgeLandingPad.ll
+++ /dev/null
@@ -1,2870 +0,0 @@
-; RUN: llc < %s -march=x86 -enable-eh -asm-verbose -o - | FileCheck %s
-; PR1422
-; PR1508
-
-target triple = "i686-pc-linux-gnu"
- %struct.exception = type { i8, i8, i32, i8*, i8*, i32, i8* }
- %struct.string___XUB = type { i32, i32 }
- %struct.string___XUP = type { i8*, %struct.string___XUB* }
- %struct.system__secondary_stack__mark_id = type { i8*, i32 }
-@weekS.154 = internal constant [28 x i8] c"SSUNSMONSTUESWEDSTHUSFRISSAT" ; <[28 x i8]*> [#uses=1]
-@weekN.179 = internal constant [8 x i8] c"\01\05\09\0D\11\15\19\1D" ; <[8 x i8]*> [#uses=1]
-@C.28.862 = internal constant %struct.string___XUB { i32 1, i32 85 } ; <%struct.string___XUB*> [#uses=1]
-@C.29.865 = internal constant %struct.string___XUB { i32 1, i32 7 } ; <%struct.string___XUB*> [#uses=1]
-@C.30.904 = internal constant %struct.string___XUB { i32 1, i32 30 } ; <%struct.string___XUB*> [#uses=1]
-@C.32.910 = internal constant %struct.string___XUB { i32 1, i32 28 } ; <%struct.string___XUB*> [#uses=1]
-@C.35.915 = internal constant %struct.string___XUB { i32 1, i32 24 } ; <%struct.string___XUB*> [#uses=1]
-@C.36.923 = internal constant %struct.string___XUB { i32 1, i32 29 } ; <%struct.string___XUB*> [#uses=1]
-@C.98.1466 = internal constant %struct.string___XUB { i32 1, i32 31 } ; <%struct.string___XUB*> [#uses=1]
-@C.101.1473 = internal constant %struct.string___XUB { i32 1, i32 46 } ; <%struct.string___XUB*> [#uses=1]
-@C.104.1478 = internal constant %struct.string___XUB { i32 1, i32 25 } ; <%struct.string___XUB*> [#uses=1]
-@C.124.1606 = internal constant %struct.string___XUB { i32 1, i32 18 } ; <%struct.string___XUB*> [#uses=1]
-@C.143.1720 = internal constant [2 x i32] [ i32 1, i32 2 ] ; <[2 x i32]*> [#uses=1]
-@C.146.1725 = internal constant %struct.string___XUB { i32 1, i32 37 } ; <%struct.string___XUB*> [#uses=1]
-@C.170.1990 = internal constant %struct.string___XUB { i32 1, i32 19 } ; <%struct.string___XUB*> [#uses=1]
-@C.178.2066 = internal constant %struct.string___XUB { i32 1, i32 27 } ; <%struct.string___XUB*> [#uses=1]
-@.str = internal constant [13 x i8] c"c36104b.adb\00\00" ; <[13 x i8]*> [#uses=1]
-@.str1 = internal constant [85 x i8] c"CONSTRAINT_ERROR IS RAISED OR NOT IN DYNAMIC DISCRETE_RANGES WITH EXPLICIT TYPE_MARKS" ; <[85 x i8]*> [#uses=1]
-@.str2 = internal constant [7 x i8] c"C36104B" ; <[7 x i8]*> [#uses=1]
-@constraint_error = external global %struct.exception ; <%struct.exception*> [#uses=18]
-@__gnat_others_value = external constant i32 ; <i32*> [#uses=37]
-@.str3 = internal constant [30 x i8] c"CONSTRAINT_ERROR NOT RAISED 1 " ; <[30 x i8]*> [#uses=1]
-@system__soft_links__abort_undefer = external global void ()* ; <void ()**> [#uses=30]
-@.str4 = internal constant [28 x i8] c"UNHANDLED EXCEPTION RAISED 1" ; <[28 x i8]*> [#uses=1]
-@.str5 = internal constant [24 x i8] c"WRONG EXCEPTION RAISED 1" ; <[24 x i8]*> [#uses=1]
-@.str6 = internal constant [29 x i8] c"CONSTRAINT_ERROR NOT RAISED 3" ; <[29 x i8]*> [#uses=1]
-@.str7 = internal constant [24 x i8] c"WRONG EXCEPTION RAISED 3" ; <[24 x i8]*> [#uses=1]
-@.str10 = internal constant [24 x i8] c"WRONG EXCEPTION RAISED 4" ; <[24 x i8]*> [#uses=1]
-@.str11 = internal constant [30 x i8] c"CONSTRAINT_ERROR NOT RAISED 7 " ; <[30 x i8]*> [#uses=1]
-@.str12 = internal constant [28 x i8] c"UNHANDLED EXCEPTION RAISED 7" ; <[28 x i8]*> [#uses=1]
-@.str13 = internal constant [24 x i8] c"WRONG EXCEPTION RAISED 7" ; <[24 x i8]*> [#uses=1]
-@.str14 = internal constant [30 x i8] c"CONSTRAINT_ERROR NOT RAISED 8 " ; <[30 x i8]*> [#uses=1]
-@.str15 = internal constant [28 x i8] c"UNHANDLED EXCEPTION RAISED 8" ; <[28 x i8]*> [#uses=1]
-@.str16 = internal constant [24 x i8] c"WRONG EXCEPTION RAISED 8" ; <[24 x i8]*> [#uses=1]
-@.str17 = internal constant [30 x i8] c"CONSTRAINT_ERROR NOT RAISED 9 " ; <[30 x i8]*> [#uses=1]
-@.str18 = internal constant [24 x i8] c"WRONG EXCEPTION RAISED 9" ; <[24 x i8]*> [#uses=1]
-@.str19 = internal constant [31 x i8] c"CONSTRAINT_ERROR NOT RAISED 10 " ; <[31 x i8]*> [#uses=1]
-@.str20 = internal constant [46 x i8] c"DID NOT RAISE CONSTRAINT_ERROR AT PROPER PLACE" ; <[46 x i8]*> [#uses=1]
-@.str21 = internal constant [25 x i8] c"WRONG EXCEPTION RAISED 10" ; <[25 x i8]*> [#uses=1]
-@.str22 = internal constant [31 x i8] c"CONSTRAINT_ERROR NOT RAISED 11 " ; <[31 x i8]*> [#uses=1]
-@.str23 = internal constant [25 x i8] c"WRONG EXCEPTION RAISED 11" ; <[25 x i8]*> [#uses=1]
-@.str24 = internal constant [30 x i8] c"'FIRST OF NULL ARRAY INCORRECT" ; <[30 x i8]*> [#uses=1]
-@.str25 = internal constant [18 x i8] c"EXCEPTION RAISED 1" ; <[18 x i8]*> [#uses=1]
-@.str26 = internal constant [18 x i8] c"EXCEPTION RAISED 3" ; <[18 x i8]*> [#uses=1]
-@.str27 = internal constant [31 x i8] c"'LENGTH OF NULL ARRAY INCORRECT" ; <[31 x i8]*> [#uses=1]
-@.str28 = internal constant [18 x i8] c"EXCEPTION RAISED 5" ; <[18 x i8]*> [#uses=1]
-@.str29 = internal constant [37 x i8] c"EVALUATION OF EXPRESSION IS INCORRECT" ; <[37 x i8]*> [#uses=1]
-@.str30 = internal constant [18 x i8] c"EXCEPTION RAISED 7" ; <[18 x i8]*> [#uses=1]
-@.str32 = internal constant [18 x i8] c"EXCEPTION RAISED 9" ; <[18 x i8]*> [#uses=1]
-@.str33 = internal constant [19 x i8] c"EXCEPTION RAISED 10" ; <[19 x i8]*> [#uses=1]
-@.str34 = internal constant [19 x i8] c"EXCEPTION RAISED 12" ; <[19 x i8]*> [#uses=1]
-@.str35 = internal constant [27 x i8] c"INCORRECT 'IN' EVALUATION 1" ; <[27 x i8]*> [#uses=1]
-@.str36 = internal constant [27 x i8] c"INCORRECT 'IN' EVALUATION 2" ; <[27 x i8]*> [#uses=1]
-@.str37 = internal constant [29 x i8] c"INCORRECT 'NOT IN' EVALUATION" ; <[29 x i8]*> [#uses=1]
-@.str38 = internal constant [19 x i8] c"EXCEPTION RAISED 52" ; <[19 x i8]*> [#uses=1]
-
-define void @_ada_c36104b() {
-entry:
- %tmp9 = alloca %struct.system__secondary_stack__mark_id, align 8 ; <%struct.system__secondary_stack__mark_id*> [#uses=3]
- %tmp12 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp15 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp31 = alloca %struct.system__secondary_stack__mark_id, align 8 ; <%struct.system__secondary_stack__mark_id*> [#uses=3]
- %tmp34 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp37 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp46 = alloca %struct.system__secondary_stack__mark_id, align 8 ; <%struct.system__secondary_stack__mark_id*> [#uses=3]
- %tmp49 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp52 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp55 = alloca %struct.system__secondary_stack__mark_id, align 8 ; <%struct.system__secondary_stack__mark_id*> [#uses=3]
- %tmp58 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp61 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp63 = alloca %struct.system__secondary_stack__mark_id, align 8 ; <%struct.system__secondary_stack__mark_id*> [#uses=3]
- %tmp66 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp69 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp72 = alloca %struct.system__secondary_stack__mark_id, align 8 ; <%struct.system__secondary_stack__mark_id*> [#uses=3]
- %tmp75 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp78 = alloca %struct.string___XUP, align 8 ; <%struct.string___XUP*> [#uses=3]
- %tmp123 = call i32 @report__ident_int( i32 0 ) ; <i32> [#uses=3]
- %tmp125 = icmp ugt i32 %tmp123, 6 ; <i1> [#uses=1]
- br i1 %tmp125, label %cond_true, label %cond_next136
-
-cond_true: ; preds = %entry
- call void @__gnat_rcheck_10( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 50 )
- unreachable
-
-cond_next136: ; preds = %entry
- %tmp137138 = trunc i32 %tmp123 to i8 ; <i8> [#uses=21]
- %tmp139 = icmp ugt i8 %tmp137138, 6 ; <i1> [#uses=1]
- br i1 %tmp139, label %bb, label %bb144
-
-bb: ; preds = %cond_next136
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 50 )
- unreachable
-
-bb144: ; preds = %cond_next136
- %tmp150 = call i32 @report__ident_int( i32 1 ) ; <i32> [#uses=4]
- %tmp154 = icmp ugt i32 %tmp150, 6 ; <i1> [#uses=1]
- br i1 %tmp154, label %cond_true157, label %cond_next169
-
-cond_true157: ; preds = %bb144
- call void @__gnat_rcheck_10( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 51 )
- unreachable
-
-cond_next169: ; preds = %bb144
- %tmp170171 = trunc i32 %tmp150 to i8 ; <i8> [#uses=34]
- %tmp172 = icmp ugt i8 %tmp170171, 6 ; <i1> [#uses=1]
- br i1 %tmp172, label %bb175, label %bb178
-
-bb175: ; preds = %cond_next169
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 51 )
- unreachable
-
-bb178: ; preds = %cond_next169
- %tmp184 = call i32 @report__ident_int( i32 2 ) ; <i32> [#uses=3]
- %tmp188 = icmp ugt i32 %tmp184, 6 ; <i1> [#uses=1]
- br i1 %tmp188, label %cond_true191, label %cond_next203
-
-cond_true191: ; preds = %bb178
- call void @__gnat_rcheck_10( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 52 )
- unreachable
-
-cond_next203: ; preds = %bb178
- %tmp204205 = trunc i32 %tmp184 to i8 ; <i8> [#uses=30]
- %tmp206 = icmp ugt i8 %tmp204205, 6 ; <i1> [#uses=3]
- br i1 %tmp206, label %bb209, label %bb212
-
-bb209: ; preds = %cond_next203
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 52 )
- unreachable
-
-bb212: ; preds = %cond_next203
- %tmp218 = call i32 @report__ident_int( i32 3 ) ; <i32> [#uses=4]
- %tmp222 = icmp ugt i32 %tmp218, 6 ; <i1> [#uses=1]
- br i1 %tmp222, label %cond_true225, label %cond_next237
-
-cond_true225: ; preds = %bb212
- call void @__gnat_rcheck_10( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 53 )
- unreachable
-
-cond_next237: ; preds = %bb212
- %tmp238239 = trunc i32 %tmp218 to i8 ; <i8> [#uses=34]
- %tmp240 = icmp ugt i8 %tmp238239, 6 ; <i1> [#uses=2]
- br i1 %tmp240, label %bb243, label %bb246
-
-bb243: ; preds = %cond_next237
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 53 )
- unreachable
-
-bb246: ; preds = %cond_next237
- %tmp252 = call i32 @report__ident_int( i32 4 ) ; <i32> [#uses=3]
- %tmp256 = icmp ugt i32 %tmp252, 6 ; <i1> [#uses=1]
- br i1 %tmp256, label %cond_true259, label %cond_next271
-
-cond_true259: ; preds = %bb246
- call void @__gnat_rcheck_10( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 54 )
- unreachable
-
-cond_next271: ; preds = %bb246
- %tmp272273 = trunc i32 %tmp252 to i8 ; <i8> [#uses=27]
- %tmp274 = icmp ugt i8 %tmp272273, 6 ; <i1> [#uses=4]
- br i1 %tmp274, label %bb277, label %bb280
-
-bb277: ; preds = %cond_next271
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 54 )
- unreachable
-
-bb280: ; preds = %cond_next271
- %tmp286 = call i32 @report__ident_int( i32 5 ) ; <i32> [#uses=3]
- %tmp290 = icmp ugt i32 %tmp286, 6 ; <i1> [#uses=1]
- br i1 %tmp290, label %cond_true293, label %cond_next305
-
-cond_true293: ; preds = %bb280
- call void @__gnat_rcheck_10( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 55 )
- unreachable
-
-cond_next305: ; preds = %bb280
- %tmp306307 = trunc i32 %tmp286 to i8 ; <i8> [#uses=16]
- %tmp308 = icmp ugt i8 %tmp306307, 6 ; <i1> [#uses=1]
- br i1 %tmp308, label %bb311, label %bb314
-
-bb311: ; preds = %cond_next305
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 55 )
- unreachable
-
-bb314: ; preds = %cond_next305
- %tmp320 = call i32 @report__ident_int( i32 6 ) ; <i32> [#uses=2]
- %tmp324 = icmp ugt i32 %tmp320, 6 ; <i1> [#uses=1]
- br i1 %tmp324, label %cond_true327, label %cond_next339
-
-cond_true327: ; preds = %bb314
- call void @__gnat_rcheck_10( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 56 )
- unreachable
-
-cond_next339: ; preds = %bb314
- %tmp340341 = trunc i32 %tmp320 to i8 ; <i8> [#uses=4]
- %tmp342 = icmp ugt i8 %tmp340341, 6 ; <i1> [#uses=1]
- br i1 %tmp342, label %bb345, label %bb348
-
-bb345: ; preds = %cond_next339
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 56 )
- unreachable
-
-bb348: ; preds = %cond_next339
- %tmp364 = icmp ult i8 %tmp272273, %tmp204205 ; <i1> [#uses=2]
- br i1 %tmp364, label %cond_next383, label %cond_true367
-
-cond_true367: ; preds = %bb348
- %tmp370 = icmp ult i8 %tmp204205, %tmp170171 ; <i1> [#uses=1]
- %tmp374 = icmp ugt i8 %tmp272273, %tmp306307 ; <i1> [#uses=1]
- %tmp378 = or i1 %tmp374, %tmp370 ; <i1> [#uses=1]
- br i1 %tmp378, label %cond_true381, label %cond_next383
-
-cond_true381: ; preds = %cond_true367
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 59 )
- unreachable
-
-cond_next383: ; preds = %cond_true367, %bb348
- %tmp384 = call i32 @report__ident_int( i32 -5 ) ; <i32> [#uses=15]
- %tmp388 = add i32 %tmp384, 10 ; <i32> [#uses=1]
- %tmp389 = icmp ugt i32 %tmp388, 20 ; <i1> [#uses=1]
- br i1 %tmp389, label %cond_true392, label %cond_next393
-
-cond_true392: ; preds = %cond_next383
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 63 )
- unreachable
-
-cond_next393: ; preds = %cond_next383
- %tmp394 = call i32 @report__ident_int( i32 5 ) ; <i32> [#uses=18]
- %tmp398 = add i32 %tmp394, 10 ; <i32> [#uses=1]
- %tmp399 = icmp ugt i32 %tmp398, 20 ; <i1> [#uses=1]
- br i1 %tmp399, label %cond_true402, label %cond_next403
-
-cond_true402: ; preds = %cond_next393
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 64 )
- unreachable
-
-cond_next403: ; preds = %cond_next393
- %tmp416 = icmp slt i32 %tmp394, %tmp384 ; <i1> [#uses=1]
- br i1 %tmp416, label %cond_next437, label %cond_true419
-
-cond_true419: ; preds = %cond_next403
- %tmp423 = icmp slt i32 %tmp384, -10 ; <i1> [#uses=1]
- %tmp428 = icmp sgt i32 %tmp394, 10 ; <i1> [#uses=1]
- %tmp432 = or i1 %tmp428, %tmp423 ; <i1> [#uses=1]
- br i1 %tmp432, label %cond_true435, label %cond_next437
-
-cond_true435: ; preds = %cond_true419
- call void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 63 )
- unreachable
-
-cond_next437: ; preds = %cond_true419, %cond_next403
- call void @report__test( i64 or (i64 zext (i32 ptrtoint ([7 x i8]* @.str2 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.29.865 to i32) to i64), i64 32)), i64 or (i64 zext (i32 ptrtoint ([85 x i8]* @.str1 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.28.862 to i32) to i64), i64 32)) )
- %tmp453 = icmp sgt i32 %tmp384, 0 ; <i1> [#uses=1]
- %tmp458 = icmp slt i32 %tmp394, 6 ; <i1> [#uses=1]
- %tmp462 = or i1 %tmp458, %tmp453 ; <i1> [#uses=3]
- br i1 %tmp462, label %cond_true465, label %cond_next467
-
-cond_true465: ; preds = %cond_next437
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 80 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind
-
-unwind: ; preds = %cleanup798, %unwind783, %cond_true465
- %eh_ptr = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid8065921 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp8085923 = icmp eq i32 %eh_select, %eh_typeid8065921 ; <i1> [#uses=1]
- br i1 %tmp8085923, label %eh_then809, label %eh_else823
-
-cond_next467: ; preds = %cond_next437
- invoke void @system__secondary_stack__ss_mark( %struct.system__secondary_stack__mark_id* %tmp9 sret )
- to label %invcont472 unwind label %unwind468
-
-unwind468: ; preds = %cleanup, %unwind480, %cond_next467
- %eh_ptr469 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select471 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr469, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid5928 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp7815929 = icmp eq i32 %eh_select471, %eh_typeid5928 ; <i1> [#uses=1]
- br i1 %tmp7815929, label %eh_then, label %cleanup805
-
-invcont472: ; preds = %cond_next467
- %tmp475 = getelementptr %struct.system__secondary_stack__mark_id* %tmp9, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp476 = load i8** %tmp475 ; <i8*> [#uses=2]
- %tmp478 = getelementptr %struct.system__secondary_stack__mark_id* %tmp9, i32 0, i32 1 ; <i32*> [#uses=1]
- %tmp479 = load i32* %tmp478 ; <i32> [#uses=2]
- %tmp485 = invoke i32 @report__ident_int( i32 1 )
- to label %invcont484 unwind label %unwind480 ; <i32> [#uses=2]
-
-unwind480: ; preds = %invcont734, %invcont717, %cond_next665, %cond_true663, %cond_next639, %cond_true637, %cond_next613, %cond_true611, %cond_next587, %cond_true585, %cond_next561, %cond_true559, %cond_next535, %cond_true533, %cond_next509, %cond_true507, %invcont472
- %eh_ptr481 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select483 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr481, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %tmp7685575 = ptrtoint i8* %tmp476 to i32 ; <i32> [#uses=1]
- %tmp76855755576 = zext i32 %tmp7685575 to i64 ; <i64> [#uses=1]
- %tmp7715572 = zext i32 %tmp479 to i64 ; <i64> [#uses=1]
- %tmp77155725573 = shl i64 %tmp7715572, 32 ; <i64> [#uses=1]
- %tmp77155725573.ins = or i64 %tmp77155725573, %tmp76855755576 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp77155725573.ins )
- to label %cleanup779 unwind label %unwind468
-
-invcont484: ; preds = %invcont472
- %tmp492 = icmp slt i32 %tmp485, %tmp384 ; <i1> [#uses=1]
- %tmp500 = icmp sgt i32 %tmp485, %tmp394 ; <i1> [#uses=1]
- %tmp504 = or i1 %tmp492, %tmp500 ; <i1> [#uses=1]
- br i1 %tmp504, label %cond_true507, label %cond_next509
-
-cond_true507: ; preds = %invcont484
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 86 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind480
-
-cond_next509: ; preds = %invcont484
- %tmp511 = invoke i32 @report__ident_int( i32 1 )
- to label %invcont510 unwind label %unwind480 ; <i32> [#uses=3]
-
-invcont510: ; preds = %cond_next509
- %tmp518 = icmp slt i32 %tmp511, %tmp384 ; <i1> [#uses=1]
- %tmp526 = icmp sgt i32 %tmp511, %tmp394 ; <i1> [#uses=1]
- %tmp530 = or i1 %tmp518, %tmp526 ; <i1> [#uses=1]
- br i1 %tmp530, label %cond_true533, label %cond_next535
-
-cond_true533: ; preds = %invcont510
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 86 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind480
-
-cond_next535: ; preds = %invcont510
- %tmp537 = invoke i32 @report__ident_int( i32 1 )
- to label %invcont536 unwind label %unwind480 ; <i32> [#uses=2]
-
-invcont536: ; preds = %cond_next535
- %tmp544 = icmp slt i32 %tmp537, %tmp384 ; <i1> [#uses=1]
- %tmp552 = icmp sgt i32 %tmp537, %tmp394 ; <i1> [#uses=1]
- %tmp556 = or i1 %tmp544, %tmp552 ; <i1> [#uses=1]
- br i1 %tmp556, label %cond_true559, label %cond_next561
-
-cond_true559: ; preds = %invcont536
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 86 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind480
-
-cond_next561: ; preds = %invcont536
- %tmp563 = invoke i32 @report__ident_int( i32 1 )
- to label %invcont562 unwind label %unwind480 ; <i32> [#uses=2]
-
-invcont562: ; preds = %cond_next561
- %tmp570 = icmp slt i32 %tmp563, %tmp384 ; <i1> [#uses=1]
- %tmp578 = icmp sgt i32 %tmp563, %tmp394 ; <i1> [#uses=1]
- %tmp582 = or i1 %tmp570, %tmp578 ; <i1> [#uses=1]
- br i1 %tmp582, label %cond_true585, label %cond_next587
-
-cond_true585: ; preds = %invcont562
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 86 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind480
-
-cond_next587: ; preds = %invcont562
- %tmp589 = invoke i32 @report__ident_int( i32 1 )
- to label %invcont588 unwind label %unwind480 ; <i32> [#uses=2]
-
-invcont588: ; preds = %cond_next587
- %tmp596 = icmp slt i32 %tmp589, %tmp384 ; <i1> [#uses=1]
- %tmp604 = icmp sgt i32 %tmp589, %tmp394 ; <i1> [#uses=1]
- %tmp608 = or i1 %tmp596, %tmp604 ; <i1> [#uses=1]
- br i1 %tmp608, label %cond_true611, label %cond_next613
-
-cond_true611: ; preds = %invcont588
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 86 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind480
-
-cond_next613: ; preds = %invcont588
- %tmp615 = invoke i32 @report__ident_int( i32 1 )
- to label %invcont614 unwind label %unwind480 ; <i32> [#uses=2]
-
-invcont614: ; preds = %cond_next613
- %tmp622 = icmp slt i32 %tmp615, %tmp384 ; <i1> [#uses=1]
- %tmp630 = icmp sgt i32 %tmp615, %tmp394 ; <i1> [#uses=1]
- %tmp634 = or i1 %tmp622, %tmp630 ; <i1> [#uses=1]
- br i1 %tmp634, label %cond_true637, label %cond_next639
-
-cond_true637: ; preds = %invcont614
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 86 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind480
-
-cond_next639: ; preds = %invcont614
- %tmp641 = invoke i32 @report__ident_int( i32 1 )
- to label %invcont640 unwind label %unwind480 ; <i32> [#uses=2]
-
-invcont640: ; preds = %cond_next639
- %tmp648 = icmp slt i32 %tmp641, %tmp384 ; <i1> [#uses=1]
- %tmp656 = icmp sgt i32 %tmp641, %tmp394 ; <i1> [#uses=1]
- %tmp660 = or i1 %tmp648, %tmp656 ; <i1> [#uses=1]
- br i1 %tmp660, label %cond_true663, label %cond_next665
-
-cond_true663: ; preds = %invcont640
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 86 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind480
-
-cond_next665: ; preds = %invcont640
- invoke void @system__img_int__image_integer( %struct.string___XUP* %tmp12 sret , i32 %tmp511 )
- to label %invcont717 unwind label %unwind480
-
-invcont717: ; preds = %cond_next665
- %tmp719 = getelementptr %struct.string___XUP* %tmp12, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp720 = load i8** %tmp719 ; <i8*> [#uses=1]
- %tmp7205888 = ptrtoint i8* %tmp720 to i32 ; <i32> [#uses=1]
- %tmp72058885889 = zext i32 %tmp7205888 to i64 ; <i64> [#uses=1]
- %tmp722 = getelementptr %struct.string___XUP* %tmp12, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp723 = load %struct.string___XUB** %tmp722 ; <%struct.string___XUB*> [#uses=1]
- %tmp7235884 = ptrtoint %struct.string___XUB* %tmp723 to i32 ; <i32> [#uses=1]
- %tmp72358845885 = zext i32 %tmp7235884 to i64 ; <i64> [#uses=1]
- %tmp723588458855886 = shl i64 %tmp72358845885, 32 ; <i64> [#uses=1]
- %tmp723588458855886.ins = or i64 %tmp723588458855886, %tmp72058885889 ; <i64> [#uses=1]
- invoke void @system__string_ops__str_concat( %struct.string___XUP* %tmp15 sret , i64 or (i64 zext (i32 ptrtoint ([30 x i8]* @.str3 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.30.904 to i32) to i64), i64 32)), i64 %tmp723588458855886.ins )
- to label %invcont734 unwind label %unwind480
-
-invcont734: ; preds = %invcont717
- %tmp736 = getelementptr %struct.string___XUP* %tmp15, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp737 = load i8** %tmp736 ; <i8*> [#uses=1]
- %tmp7375876 = ptrtoint i8* %tmp737 to i32 ; <i32> [#uses=1]
- %tmp73758765877 = zext i32 %tmp7375876 to i64 ; <i64> [#uses=1]
- %tmp739 = getelementptr %struct.string___XUP* %tmp15, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp740 = load %struct.string___XUB** %tmp739 ; <%struct.string___XUB*> [#uses=1]
- %tmp7405872 = ptrtoint %struct.string___XUB* %tmp740 to i32 ; <i32> [#uses=1]
- %tmp74058725873 = zext i32 %tmp7405872 to i64 ; <i64> [#uses=1]
- %tmp740587258735874 = shl i64 %tmp74058725873, 32 ; <i64> [#uses=1]
- %tmp740587258735874.ins = or i64 %tmp740587258735874, %tmp73758765877 ; <i64> [#uses=1]
- invoke void @report__failed( i64 %tmp740587258735874.ins )
- to label %cleanup unwind label %unwind480
-
-cleanup: ; preds = %invcont734
- %tmp7515581 = ptrtoint i8* %tmp476 to i32 ; <i32> [#uses=1]
- %tmp75155815582 = zext i32 %tmp7515581 to i64 ; <i64> [#uses=1]
- %tmp7545578 = zext i32 %tmp479 to i64 ; <i64> [#uses=1]
- %tmp75455785579 = shl i64 %tmp7545578, 32 ; <i64> [#uses=1]
- %tmp75455785579.ins = or i64 %tmp75455785579, %tmp75155815582 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp75455785579.ins )
- to label %cond_true856 unwind label %unwind468
-
-cleanup779: ; preds = %unwind480
- %eh_typeid = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp781 = icmp eq i32 %eh_select483, %eh_typeid ; <i1> [#uses=1]
- br i1 %tmp781, label %eh_then, label %cleanup805
-
-eh_then: ; preds = %cleanup779, %unwind468
- %eh_exception.35924.0 = phi i8* [ %eh_ptr469, %unwind468 ], [ %eh_ptr481, %cleanup779 ] ; <i8*> [#uses=3]
- invoke void @__gnat_begin_handler( i8* %eh_exception.35924.0 )
- to label %invcont787 unwind label %unwind783
-
-unwind783: ; preds = %invcont789, %invcont787, %eh_then
- %eh_ptr784 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=2]
- %eh_select786 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr784, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_exception.35924.0 )
- to label %cleanup805 unwind label %unwind
-
-invcont787: ; preds = %eh_then
- %tmp788 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp788( )
- to label %invcont789 unwind label %unwind783
-
-invcont789: ; preds = %invcont787
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([28 x i8]* @.str4 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.32.910 to i32) to i64), i64 32)) )
- to label %cleanup798 unwind label %unwind783
-
-cleanup798: ; preds = %invcont789
- invoke void @__gnat_end_handler( i8* %eh_exception.35924.0 )
- to label %cond_true856 unwind label %unwind
-
-cleanup805: ; preds = %unwind783, %cleanup779, %unwind468
- %eh_selector.0 = phi i32 [ %eh_select471, %unwind468 ], [ %eh_select483, %cleanup779 ], [ %eh_select786, %unwind783 ] ; <i32> [#uses=2]
- %eh_exception.0 = phi i8* [ %eh_ptr469, %unwind468 ], [ %eh_ptr481, %cleanup779 ], [ %eh_ptr784, %unwind783 ] ; <i8*> [#uses=2]
- %eh_typeid806 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp808 = icmp eq i32 %eh_selector.0, %eh_typeid806 ; <i1> [#uses=1]
- br i1 %tmp808, label %eh_then809, label %eh_else823
-
-eh_then809: ; preds = %cleanup805, %unwind
- %eh_exception.05914.0 = phi i8* [ %eh_ptr, %unwind ], [ %eh_exception.0, %cleanup805 ] ; <i8*> [#uses=3]
- invoke void @__gnat_begin_handler( i8* %eh_exception.05914.0 )
- to label %invcont815 unwind label %unwind813
-
-unwind813: ; preds = %invcont815, %eh_then809
- %eh_ptr814 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_exception.05914.0 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr814 ) ; <i32>:0 [#uses=0]
- unreachable
-
-invcont815: ; preds = %eh_then809
- %tmp816 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp816( )
- to label %cleanup819 unwind label %unwind813
-
-cleanup819: ; preds = %invcont815
- call void @__gnat_end_handler( i8* %eh_exception.05914.0 )
- %tmp8595931 = icmp ult i8 %tmp170171, %tmp204205 ; <i1> [#uses=1]
- %tmp8635932 = icmp ugt i8 %tmp170171, %tmp272273 ; <i1> [#uses=1]
- %tmp8675933 = or i1 %tmp8635932, %tmp8595931 ; <i1> [#uses=1]
- br i1 %tmp8675933, label %cond_true870, label %bb887
-
-eh_else823: ; preds = %cleanup805, %unwind
- %eh_selector.05912.1 = phi i32 [ %eh_select, %unwind ], [ %eh_selector.0, %cleanup805 ] ; <i32> [#uses=1]
- %eh_exception.05914.1 = phi i8* [ %eh_ptr, %unwind ], [ %eh_exception.0, %cleanup805 ] ; <i8*> [#uses=4]
- %eh_typeid824 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp826 = icmp eq i32 %eh_selector.05912.1, %eh_typeid824 ; <i1> [#uses=1]
- br i1 %tmp826, label %eh_then827, label %Unwind
-
-eh_then827: ; preds = %eh_else823
- invoke void @__gnat_begin_handler( i8* %eh_exception.05914.1 )
- to label %invcont833 unwind label %unwind831
-
-unwind831: ; preds = %invcont835, %invcont833, %eh_then827
- %eh_ptr832 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_exception.05914.1 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr832 ) ; <i32>:1 [#uses=0]
- unreachable
-
-invcont833: ; preds = %eh_then827
- %tmp834 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp834( )
- to label %invcont835 unwind label %unwind831
-
-invcont835: ; preds = %invcont833
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([24 x i8]* @.str5 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.35.915 to i32) to i64), i64 32)) )
- to label %cleanup844 unwind label %unwind831
-
-cleanup844: ; preds = %invcont835
- call void @__gnat_end_handler( i8* %eh_exception.05914.1 )
- br label %cond_true856
-
-cond_true856: ; preds = %cleanup844, %cleanup798, %cleanup
- %tmp859 = icmp ult i8 %tmp170171, %tmp204205 ; <i1> [#uses=1]
- %tmp863 = icmp ugt i8 %tmp170171, %tmp272273 ; <i1> [#uses=1]
- %tmp867 = or i1 %tmp863, %tmp859 ; <i1> [#uses=1]
- br i1 %tmp867, label %cond_true870, label %bb887
-
-cond_true870: ; preds = %cond_true856, %cleanup819
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 103 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind871
-
-unwind871: ; preds = %cond_next905, %bb887, %cond_true870
- %sat.3 = phi i8 [ %tmp340341, %cond_true870 ], [ %sat.1, %bb887 ], [ %sat.0, %cond_next905 ] ; <i8> [#uses=2]
- %eh_ptr872 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=8]
- %eh_select874 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr872, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid915 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp917 = icmp eq i32 %eh_select874, %eh_typeid915 ; <i1> [#uses=1]
- br i1 %tmp917, label %eh_then918, label %eh_else932
-
-bb887: ; preds = %cond_next901, %cond_true856, %cleanup819
- %indvar = phi i8 [ %indvar.next10, %cond_next901 ], [ 0, %cond_true856 ], [ 0, %cleanup819 ] ; <i8> [#uses=2]
- %sat.1 = phi i8 [ %sat.0, %cond_next901 ], [ %tmp340341, %cond_true856 ], [ %tmp340341, %cleanup819 ] ; <i8> [#uses=2]
- %tmp889 = invoke i8 @report__equal( i32 2, i32 2 )
- to label %invcont888 unwind label %unwind871 ; <i8> [#uses=1]
-
-invcont888: ; preds = %bb887
- %i.4 = add i8 %indvar, %tmp170171 ; <i8> [#uses=1]
- %tmp890 = icmp eq i8 %tmp889, 0 ; <i1> [#uses=1]
- %sat.0 = select i1 %tmp890, i8 %sat.1, i8 6 ; <i8> [#uses=3]
- %tmp897 = icmp eq i8 %i.4, %tmp170171 ; <i1> [#uses=1]
- br i1 %tmp897, label %cond_next905, label %cond_next901
-
-cond_next901: ; preds = %invcont888
- %indvar.next10 = add i8 %indvar, 1 ; <i8> [#uses=1]
- br label %bb887
-
-cond_next905: ; preds = %invcont888
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([29 x i8]* @.str6 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.36.923 to i32) to i64), i64 32)) )
- to label %finally913 unwind label %unwind871
-
-eh_then918: ; preds = %unwind871
- invoke void @__gnat_begin_handler( i8* %eh_ptr872 )
- to label %invcont924 unwind label %unwind922
-
-unwind922: ; preds = %invcont924, %eh_then918
- %eh_ptr923 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr872 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr923 ) ; <i32>:2 [#uses=0]
- unreachable
-
-invcont924: ; preds = %eh_then918
- %tmp925 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp925( )
- to label %cleanup928 unwind label %unwind922
-
-cleanup928: ; preds = %invcont924
- call void @__gnat_end_handler( i8* %eh_ptr872 )
- br i1 %tmp462, label %cond_true973, label %UnifiedReturnBlock35
-
-eh_else932: ; preds = %unwind871
- %eh_typeid933 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp935 = icmp eq i32 %eh_select874, %eh_typeid933 ; <i1> [#uses=1]
- br i1 %tmp935, label %eh_then936, label %Unwind
-
-eh_then936: ; preds = %eh_else932
- invoke void @__gnat_begin_handler( i8* %eh_ptr872 )
- to label %invcont942 unwind label %unwind940
-
-unwind940: ; preds = %invcont944, %invcont942, %eh_then936
- %eh_ptr941 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr872 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr941 ) ; <i32>:3 [#uses=0]
- unreachable
-
-invcont942: ; preds = %eh_then936
- %tmp943 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp943( )
- to label %invcont944 unwind label %unwind940
-
-invcont944: ; preds = %invcont942
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([24 x i8]* @.str7 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.35.915 to i32) to i64), i64 32)) )
- to label %cleanup953 unwind label %unwind940
-
-cleanup953: ; preds = %invcont944
- call void @__gnat_end_handler( i8* %eh_ptr872 )
- br label %finally913
-
-finally913: ; preds = %cleanup953, %cond_next905
- %sat.4 = phi i8 [ %sat.3, %cleanup953 ], [ %sat.0, %cond_next905 ] ; <i8> [#uses=1]
- br i1 %tmp462, label %cond_true973, label %UnifiedReturnBlock35
-
-cond_true973: ; preds = %finally913, %cleanup928
- %sat.45934.0 = phi i8 [ %sat.3, %cleanup928 ], [ %sat.4, %finally913 ] ; <i8> [#uses=9]
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 119 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind974
-
-unwind974: ; preds = %cond_true973
- %eh_ptr975 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=8]
- %eh_select977 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr975, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid13135959 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp13155961 = icmp eq i32 %eh_select977, %eh_typeid13135959 ; <i1> [#uses=1]
- br i1 %tmp13155961, label %eh_then1316, label %eh_else1330
-
-eh_then1316: ; preds = %unwind974
- invoke void @__gnat_begin_handler( i8* %eh_ptr975 )
- to label %invcont1322 unwind label %unwind1320
-
-unwind1320: ; preds = %invcont1322, %eh_then1316
- %eh_ptr1321 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr975 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr1321 ) ; <i32>:4 [#uses=0]
- unreachable
-
-invcont1322: ; preds = %eh_then1316
- %tmp1323 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp1323( )
- to label %cleanup1326 unwind label %unwind1320
-
-cleanup1326: ; preds = %invcont1322
- call void @__gnat_end_handler( i8* %eh_ptr975 )
- br label %finally1311
-
-eh_else1330: ; preds = %unwind974
- %eh_typeid1331 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp1333 = icmp eq i32 %eh_select977, %eh_typeid1331 ; <i1> [#uses=1]
- br i1 %tmp1333, label %eh_then1334, label %Unwind
-
-eh_then1334: ; preds = %eh_else1330
- invoke void @__gnat_begin_handler( i8* %eh_ptr975 )
- to label %invcont1340 unwind label %unwind1338
-
-unwind1338: ; preds = %invcont1342, %invcont1340, %eh_then1334
- %eh_ptr1339 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr975 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr1339 ) ; <i32>:5 [#uses=0]
- unreachable
-
-invcont1340: ; preds = %eh_then1334
- %tmp1341 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp1341( )
- to label %invcont1342 unwind label %unwind1338
-
-invcont1342: ; preds = %invcont1340
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([24 x i8]* @.str10 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.35.915 to i32) to i64), i64 32)) )
- to label %cleanup1351 unwind label %unwind1338
-
-cleanup1351: ; preds = %invcont1342
- call void @__gnat_end_handler( i8* %eh_ptr975 )
- br label %finally1311
-
-finally1311: ; preds = %cleanup1351, %cleanup1326
- %tmp1356 = call i8* @llvm.stacksave( ) ; <i8*> [#uses=6]
- %tmp13571358 = and i32 %tmp184, 255 ; <i32> [#uses=11]
- %tmp13831384 = and i32 %tmp252, 255 ; <i32> [#uses=5]
- %tmp1387 = add i32 %tmp13571358, -1 ; <i32> [#uses=2]
- %tmp1388 = icmp sge i32 %tmp13831384, %tmp1387 ; <i1> [#uses=1]
- %max1389 = select i1 %tmp1388, i32 %tmp13831384, i32 %tmp1387 ; <i32> [#uses=1]
- %tmp1392 = sub i32 %max1389, %tmp13571358 ; <i32> [#uses=1]
- %tmp1393 = add i32 %tmp1392, 1 ; <i32> [#uses=2]
- %tmp1394 = icmp sgt i32 %tmp1393, -1 ; <i1> [#uses=1]
- %max1395 = select i1 %tmp1394, i32 %tmp1393, i32 0 ; <i32> [#uses=5]
- %tmp1397 = alloca i8, i32 %max1395 ; <i8*> [#uses=2]
- %tmp1401 = icmp ult i8 %tmp238239, %tmp170171 ; <i1> [#uses=2]
- br i1 %tmp1401, label %cond_next1425, label %cond_true1404
-
-cond_true1404: ; preds = %finally1311
- %tmp1407 = icmp ult i8 %tmp170171, %tmp204205 ; <i1> [#uses=1]
- %tmp1411 = icmp ugt i8 %tmp238239, %tmp272273 ; <i1> [#uses=1]
- %tmp1415 = or i1 %tmp1411, %tmp1407 ; <i1> [#uses=1]
- br i1 %tmp1415, label %cond_true1418, label %cond_next1425
-
-cond_true1418: ; preds = %cond_true1404
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 144 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind1419
-
-unwind1419: ; preds = %cleanup1702, %cleanup1686, %unwind1676, %cond_next1548, %cond_true1546, %cond_true1418
- %eh_ptr1420 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select1422 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr1420, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid17215981 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp17235983 = icmp eq i32 %eh_select1422, %eh_typeid17215981 ; <i1> [#uses=1]
- br i1 %tmp17235983, label %eh_then1724, label %eh_else1742
-
-cond_next1425: ; preds = %cond_true1404, %finally1311
- %tmp14281429 = and i32 %tmp150, 255 ; <i32> [#uses=3]
- %tmp14841485 = and i32 %tmp218, 255 ; <i32> [#uses=3]
- %tmp1488 = add i32 %tmp14281429, -1 ; <i32> [#uses=2]
- %tmp1489 = icmp sge i32 %tmp14841485, %tmp1488 ; <i1> [#uses=1]
- %max1490 = select i1 %tmp1489, i32 %tmp14841485, i32 %tmp1488 ; <i32> [#uses=1]
- %tmp1493 = sub i32 %max1490, %tmp14281429 ; <i32> [#uses=1]
- %tmp1494 = add i32 %tmp1493, 1 ; <i32> [#uses=2]
- %tmp1495 = icmp sgt i32 %tmp1494, -1 ; <i1> [#uses=1]
- %max1496 = select i1 %tmp1495, i32 %tmp1494, i32 0 ; <i32> [#uses=1]
- %tmp1497 = alloca i8, i32 %max1496 ; <i8*> [#uses=3]
- %tmp1504 = icmp ugt i8 %tmp170171, %tmp238239 ; <i1> [#uses=1]
- br i1 %tmp1504, label %cond_next1526, label %bb1509
-
-bb1509: ; preds = %cond_next1425
- store i8 %tmp238239, i8* %tmp1497
- %tmp1518 = icmp eq i8 %tmp238239, %tmp170171 ; <i1> [#uses=1]
- br i1 %tmp1518, label %cond_next1526, label %cond_next1522.preheader
-
-cond_next1522.preheader: ; preds = %bb1509
- %J64b.55984.8 = add i8 %tmp170171, 1 ; <i8> [#uses=1]
- br label %cond_next1522
-
-cond_next1522: ; preds = %cond_next1522, %cond_next1522.preheader
- %indvar6241 = phi i8 [ 0, %cond_next1522.preheader ], [ %indvar.next, %cond_next1522 ] ; <i8> [#uses=2]
- %tmp1524 = add i8 %J64b.55984.8, %indvar6241 ; <i8> [#uses=2]
- %tmp151015115988 = zext i8 %tmp1524 to i32 ; <i32> [#uses=1]
- %tmp15135989 = sub i32 %tmp151015115988, %tmp14281429 ; <i32> [#uses=1]
- %tmp15145990 = getelementptr i8* %tmp1497, i32 %tmp15135989 ; <i8*> [#uses=1]
- store i8 %tmp238239, i8* %tmp15145990
- %tmp15185992 = icmp eq i8 %tmp238239, %tmp1524 ; <i1> [#uses=1]
- %indvar.next = add i8 %indvar6241, 1 ; <i8> [#uses=1]
- br i1 %tmp15185992, label %cond_next1526, label %cond_next1522
-
-cond_next1526: ; preds = %cond_next1522, %bb1509, %cond_next1425
- %tmp15271528 = zext i8 %tmp272273 to i64 ; <i64> [#uses=1]
- %tmp15291530 = zext i8 %tmp204205 to i64 ; <i64> [#uses=1]
- %tmp1531 = sub i64 %tmp15271528, %tmp15291530 ; <i64> [#uses=1]
- %tmp1532 = add i64 %tmp1531, 1 ; <i64> [#uses=2]
- %tmp1533 = icmp sgt i64 %tmp1532, -1 ; <i1> [#uses=1]
- %max1534 = select i1 %tmp1533, i64 %tmp1532, i64 0 ; <i64> [#uses=1]
- %tmp15351536 = zext i8 %tmp238239 to i64 ; <i64> [#uses=1]
- %tmp15371538 = zext i8 %tmp170171 to i64 ; <i64> [#uses=1]
- %tmp1539 = sub i64 %tmp15351536, %tmp15371538 ; <i64> [#uses=1]
- %tmp1540 = add i64 %tmp1539, 1 ; <i64> [#uses=2]
- %tmp1541 = icmp sgt i64 %tmp1540, -1 ; <i1> [#uses=1]
- %max1542 = select i1 %tmp1541, i64 %tmp1540, i64 0 ; <i64> [#uses=1]
- %tmp1543 = icmp eq i64 %max1534, %max1542 ; <i1> [#uses=1]
- br i1 %tmp1543, label %cond_next1548, label %cond_true1546
-
-cond_true1546: ; preds = %cond_next1526
- invoke void @__gnat_rcheck_07( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 144 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind1419
-
-cond_next1548: ; preds = %cond_next1526
- call void @llvm.memcpy.i32( i8* %tmp1397, i8* %tmp1497, i32 %max1395, i32 1 )
- invoke void @system__secondary_stack__ss_mark( %struct.system__secondary_stack__mark_id* %tmp31 sret )
- to label %invcont1552 unwind label %unwind1419
-
-invcont1552: ; preds = %cond_next1548
- %tmp1555 = getelementptr %struct.system__secondary_stack__mark_id* %tmp31, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp1556 = load i8** %tmp1555 ; <i8*> [#uses=3]
- %tmp1558 = getelementptr %struct.system__secondary_stack__mark_id* %tmp31, i32 0, i32 1 ; <i32*> [#uses=1]
- %tmp1559 = load i32* %tmp1558 ; <i32> [#uses=3]
- %tmp1562 = icmp ult i8 %tmp238239, %tmp204205 ; <i1> [#uses=1]
- %tmp1566 = icmp ugt i8 %tmp238239, %tmp272273 ; <i1> [#uses=1]
- %tmp1570 = or i1 %tmp1566, %tmp1562 ; <i1> [#uses=1]
- br i1 %tmp1570, label %cond_true1573, label %cond_next1591
-
-cond_true1573: ; preds = %invcont1552
- invoke void @__gnat_rcheck_05( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 148 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind1574
-
-unwind1574: ; preds = %invcont1638, %invcont1621, %bb1607, %bb1605, %cond_true1573
- %eh_ptr1575 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=5]
- %eh_select1577 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr1575, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid1652 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp1654 = icmp eq i32 %eh_select1577, %eh_typeid1652 ; <i1> [#uses=1]
- br i1 %tmp1654, label %eh_then1655, label %cleanup1686
-
-cond_next1591: ; preds = %invcont1552
- %tmp1595 = sub i32 %tmp14841485, %tmp13571358 ; <i32> [#uses=1]
- %tmp1596 = getelementptr i8* %tmp1397, i32 %tmp1595 ; <i8*> [#uses=1]
- %tmp1597 = load i8* %tmp1596 ; <i8> [#uses=2]
- %tmp1599 = icmp ugt i8 %tmp1597, 6 ; <i1> [#uses=1]
- br i1 %tmp1599, label %bb1605, label %bb1607
-
-bb1605: ; preds = %cond_next1591
- invoke void @__gnat_rcheck_06( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 148 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind1574
-
-bb1607: ; preds = %cond_next1591
- %tmp16151616 = zext i8 %tmp1597 to i32 ; <i32> [#uses=1]
- invoke void @system__img_enum__image_enumeration_8( %struct.string___XUP* %tmp34 sret , i32 %tmp16151616, i64 or (i64 zext (i32 ptrtoint ([28 x i8]* @weekS.154 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.32.910 to i32) to i64), i64 32)), i8* getelementptr ([8 x i8]* @weekN.179, i32 0, i32 0) )
- to label %invcont1621 unwind label %unwind1574
-
-invcont1621: ; preds = %bb1607
- %tmp1623 = getelementptr %struct.string___XUP* %tmp34, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp1624 = load i8** %tmp1623 ; <i8*> [#uses=1]
- %tmp16245815 = ptrtoint i8* %tmp1624 to i32 ; <i32> [#uses=1]
- %tmp162458155816 = zext i32 %tmp16245815 to i64 ; <i64> [#uses=1]
- %tmp1626 = getelementptr %struct.string___XUP* %tmp34, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp1627 = load %struct.string___XUB** %tmp1626 ; <%struct.string___XUB*> [#uses=1]
- %tmp16275811 = ptrtoint %struct.string___XUB* %tmp1627 to i32 ; <i32> [#uses=1]
- %tmp162758115812 = zext i32 %tmp16275811 to i64 ; <i64> [#uses=1]
- %tmp1627581158125813 = shl i64 %tmp162758115812, 32 ; <i64> [#uses=1]
- %tmp1627581158125813.ins = or i64 %tmp1627581158125813, %tmp162458155816 ; <i64> [#uses=1]
- invoke void @system__string_ops__str_concat( %struct.string___XUP* %tmp37 sret , i64 or (i64 zext (i32 ptrtoint ([30 x i8]* @.str11 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.30.904 to i32) to i64), i64 32)), i64 %tmp1627581158125813.ins )
- to label %invcont1638 unwind label %unwind1574
-
-invcont1638: ; preds = %invcont1621
- %tmp1640 = getelementptr %struct.string___XUP* %tmp37, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp1641 = load i8** %tmp1640 ; <i8*> [#uses=1]
- %tmp16415803 = ptrtoint i8* %tmp1641 to i32 ; <i32> [#uses=1]
- %tmp164158035804 = zext i32 %tmp16415803 to i64 ; <i64> [#uses=1]
- %tmp1643 = getelementptr %struct.string___XUP* %tmp37, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp1644 = load %struct.string___XUB** %tmp1643 ; <%struct.string___XUB*> [#uses=1]
- %tmp16445799 = ptrtoint %struct.string___XUB* %tmp1644 to i32 ; <i32> [#uses=1]
- %tmp164457995800 = zext i32 %tmp16445799 to i64 ; <i64> [#uses=1]
- %tmp1644579958005801 = shl i64 %tmp164457995800, 32 ; <i64> [#uses=1]
- %tmp1644579958005801.ins = or i64 %tmp1644579958005801, %tmp164158035804 ; <i64> [#uses=1]
- invoke void @report__failed( i64 %tmp1644579958005801.ins )
- to label %cleanup1702 unwind label %unwind1574
-
-eh_then1655: ; preds = %unwind1574
- invoke void @__gnat_begin_handler( i8* %eh_ptr1575 )
- to label %invcont1663 unwind label %unwind1659
-
-unwind1659: ; preds = %invcont1665, %invcont1663, %eh_then1655
- %eh_ptr1660 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=2]
- %eh_select1662 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr1660, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_ptr1575 )
- to label %cleanup1686 unwind label %unwind1676
-
-invcont1663: ; preds = %eh_then1655
- %tmp1664 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp1664( )
- to label %invcont1665 unwind label %unwind1659
-
-invcont1665: ; preds = %invcont1663
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([28 x i8]* @.str12 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.32.910 to i32) to i64), i64 32)) )
- to label %cleanup1674 unwind label %unwind1659
-
-cleanup1674: ; preds = %invcont1665
- invoke void @__gnat_end_handler( i8* %eh_ptr1575 )
- to label %cleanup1702 unwind label %unwind1676
-
-unwind1676: ; preds = %cleanup1674, %unwind1659
- %eh_ptr1677 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=2]
- %eh_select1679 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr1677, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=1]
- %tmp169255575995 = ptrtoint i8* %tmp1556 to i32 ; <i32> [#uses=1]
- %tmp1692555755585996 = zext i32 %tmp169255575995 to i64 ; <i64> [#uses=1]
- %tmp169555545997 = zext i32 %tmp1559 to i64 ; <i64> [#uses=1]
- %tmp1695555455555998 = shl i64 %tmp169555545997, 32 ; <i64> [#uses=1]
- %tmp169555545555.ins5999 = or i64 %tmp1695555455555998, %tmp1692555755585996 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp169555545555.ins5999 )
- to label %cleanup1720 unwind label %unwind1419
-
-cleanup1686: ; preds = %unwind1659, %unwind1574
- %eh_selector.18 = phi i32 [ %eh_select1577, %unwind1574 ], [ %eh_select1662, %unwind1659 ] ; <i32> [#uses=1]
- %eh_exception.18 = phi i8* [ %eh_ptr1575, %unwind1574 ], [ %eh_ptr1660, %unwind1659 ] ; <i8*> [#uses=1]
- %tmp16925557 = ptrtoint i8* %tmp1556 to i32 ; <i32> [#uses=1]
- %tmp169255575558 = zext i32 %tmp16925557 to i64 ; <i64> [#uses=1]
- %tmp16955554 = zext i32 %tmp1559 to i64 ; <i64> [#uses=1]
- %tmp169555545555 = shl i64 %tmp16955554, 32 ; <i64> [#uses=1]
- %tmp169555545555.ins = or i64 %tmp169555545555, %tmp169255575558 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp169555545555.ins )
- to label %cleanup1720 unwind label %unwind1419
-
-cleanup1702: ; preds = %cleanup1674, %invcont1638
- %tmp17095551 = ptrtoint i8* %tmp1556 to i32 ; <i32> [#uses=1]
- %tmp170955515552 = zext i32 %tmp17095551 to i64 ; <i64> [#uses=1]
- %tmp17125548 = zext i32 %tmp1559 to i64 ; <i64> [#uses=1]
- %tmp171255485549 = shl i64 %tmp17125548, 32 ; <i64> [#uses=1]
- %tmp171255485549.ins = or i64 %tmp171255485549, %tmp170955515552 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp171255485549.ins )
- to label %cleanup1773 unwind label %unwind1419
-
-cleanup1720: ; preds = %cleanup1686, %unwind1676
- %eh_selector.185993.1 = phi i32 [ %eh_select1679, %unwind1676 ], [ %eh_selector.18, %cleanup1686 ] ; <i32> [#uses=2]
- %eh_exception.185994.1 = phi i8* [ %eh_ptr1677, %unwind1676 ], [ %eh_exception.18, %cleanup1686 ] ; <i8*> [#uses=2]
- %eh_typeid1721 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp1723 = icmp eq i32 %eh_selector.185993.1, %eh_typeid1721 ; <i1> [#uses=1]
- br i1 %tmp1723, label %eh_then1724, label %eh_else1742
-
-eh_then1724: ; preds = %cleanup1720, %unwind1419
- %eh_exception.135974.0 = phi i8* [ %eh_ptr1420, %unwind1419 ], [ %eh_exception.185994.1, %cleanup1720 ] ; <i8*> [#uses=3]
- invoke void @__gnat_begin_handler( i8* %eh_exception.135974.0 )
- to label %invcont1730 unwind label %unwind1728
-
-unwind1728: ; preds = %invcont1730, %eh_then1724
- %eh_ptr1729 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_exception.135974.0 )
- to label %cleanup1771 unwind label %unwind1736
-
-invcont1730: ; preds = %eh_then1724
- %tmp1731 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp1731( )
- to label %cleanup1734 unwind label %unwind1728
-
-cleanup1734: ; preds = %invcont1730
- invoke void @__gnat_end_handler( i8* %eh_exception.135974.0 )
- to label %cleanup1773 unwind label %unwind1736
-
-unwind1736: ; preds = %cleanup1763, %unwind1750, %cleanup1734, %unwind1728
- %eh_ptr1737 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @llvm.stackrestore( i8* %tmp1356 )
- call void @llvm.stackrestore( i8* %tmp1356 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr1737 ) ; <i32>:6 [#uses=0]
- unreachable
-
-eh_else1742: ; preds = %cleanup1720, %unwind1419
- %eh_selector.135972.1 = phi i32 [ %eh_select1422, %unwind1419 ], [ %eh_selector.185993.1, %cleanup1720 ] ; <i32> [#uses=1]
- %eh_exception.135974.1 = phi i8* [ %eh_ptr1420, %unwind1419 ], [ %eh_exception.185994.1, %cleanup1720 ] ; <i8*> [#uses=4]
- %eh_typeid1743 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp1745 = icmp eq i32 %eh_selector.135972.1, %eh_typeid1743 ; <i1> [#uses=1]
- br i1 %tmp1745, label %eh_then1746, label %cleanup1771
-
-eh_then1746: ; preds = %eh_else1742
- invoke void @__gnat_begin_handler( i8* %eh_exception.135974.1 )
- to label %invcont1752 unwind label %unwind1750
-
-unwind1750: ; preds = %invcont1754, %invcont1752, %eh_then1746
- %eh_ptr1751 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_exception.135974.1 )
- to label %cleanup1771 unwind label %unwind1736
-
-invcont1752: ; preds = %eh_then1746
- %tmp1753 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp1753( )
- to label %invcont1754 unwind label %unwind1750
-
-invcont1754: ; preds = %invcont1752
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([24 x i8]* @.str13 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.35.915 to i32) to i64), i64 32)) )
- to label %cleanup1763 unwind label %unwind1750
-
-cleanup1763: ; preds = %invcont1754
- invoke void @__gnat_end_handler( i8* %eh_exception.135974.1 )
- to label %cleanup1773 unwind label %unwind1736
-
-cleanup1771: ; preds = %unwind1750, %eh_else1742, %unwind1728
- %eh_exception.20 = phi i8* [ %eh_ptr1729, %unwind1728 ], [ %eh_exception.135974.1, %eh_else1742 ], [ %eh_ptr1751, %unwind1750 ] ; <i8*> [#uses=1]
- call void @llvm.stackrestore( i8* %tmp1356 )
- call void @llvm.stackrestore( i8* %tmp1356 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_exception.20 ) ; <i32>:7 [#uses=0]
- unreachable
-
-cleanup1773: ; preds = %cleanup1763, %cleanup1734, %cleanup1702
- call void @llvm.stackrestore( i8* %tmp1356 )
- call void @llvm.stackrestore( i8* %tmp1356 )
- %tmp1780 = call i8* @llvm.stacksave( ) ; <i8*> [#uses=6]
- %tmp17811782 = and i32 %tmp150, 255 ; <i32> [#uses=4]
- %tmp18071808 = and i32 %tmp286, 255 ; <i32> [#uses=2]
- %tmp1811 = add i32 %tmp17811782, -1 ; <i32> [#uses=2]
- %tmp1812 = icmp sge i32 %tmp18071808, %tmp1811 ; <i1> [#uses=1]
- %max1813 = select i1 %tmp1812, i32 %tmp18071808, i32 %tmp1811 ; <i32> [#uses=1]
- %tmp1816 = sub i32 %max1813, %tmp17811782 ; <i32> [#uses=1]
- %tmp1817 = add i32 %tmp1816, 1 ; <i32> [#uses=2]
- %tmp1818 = icmp sgt i32 %tmp1817, -1 ; <i1> [#uses=1]
- %max1819 = select i1 %tmp1818, i32 %tmp1817, i32 0 ; <i32> [#uses=3]
- %tmp1821 = alloca i8, i32 %max1819 ; <i8*> [#uses=2]
- %tmp1863 = alloca i8, i32 %max1819 ; <i8*> [#uses=3]
- %tmp1870 = icmp ugt i8 %tmp170171, %tmp306307 ; <i1> [#uses=1]
- br i1 %tmp1870, label %cond_next1900, label %bb1875
-
-bb1875: ; preds = %cleanup1773
- store i8 %tmp238239, i8* %tmp1863
- %tmp1884 = icmp eq i8 %tmp306307, %tmp170171 ; <i1> [#uses=1]
- br i1 %tmp1884, label %cond_next1900, label %cond_next1888.preheader
-
-cond_next1888.preheader: ; preds = %bb1875
- %J77b.26000.2 = add i8 %tmp170171, 1 ; <i8> [#uses=1]
- br label %cond_next1888
-
-cond_next1888: ; preds = %cond_next1888, %cond_next1888.preheader
- %indvar6245 = phi i8 [ 0, %cond_next1888.preheader ], [ %indvar.next14, %cond_next1888 ] ; <i8> [#uses=2]
- %tmp1890 = add i8 %J77b.26000.2, %indvar6245 ; <i8> [#uses=2]
- %tmp187618776004 = zext i8 %tmp1890 to i32 ; <i32> [#uses=1]
- %tmp18796005 = sub i32 %tmp187618776004, %tmp17811782 ; <i32> [#uses=1]
- %tmp18806006 = getelementptr i8* %tmp1863, i32 %tmp18796005 ; <i8*> [#uses=1]
- store i8 %tmp238239, i8* %tmp18806006
- %tmp18846008 = icmp eq i8 %tmp306307, %tmp1890 ; <i1> [#uses=1]
- %indvar.next14 = add i8 %indvar6245, 1 ; <i8> [#uses=1]
- br i1 %tmp18846008, label %cond_next1900, label %cond_next1888
-
-unwind1895: ; preds = %cleanup2300, %cleanup2284, %unwind2274, %cond_next2149, %cond_true1946
- %eh_ptr1896 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select1898 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr1896, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid23196018 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp23216020 = icmp eq i32 %eh_select1898, %eh_typeid23196018 ; <i1> [#uses=1]
- br i1 %tmp23216020, label %eh_then2322, label %eh_else2340
-
-cond_next1900: ; preds = %cond_next1888, %bb1875, %cleanup1773
- call void @llvm.memcpy.i32( i8* %tmp1821, i8* %tmp1863, i32 %max1819, i32 1 )
- ret void
-
-cond_true1909: ; No predecessors!
- %tmp1912 = icmp ult i8 %tmp170171, %tmp204205 ; <i1> [#uses=1]
- %tmp1916 = icmp ugt i8 %tmp238239, %tmp272273 ; <i1> [#uses=1]
- %tmp1920 = or i1 %tmp1916, %tmp1912 ; <i1> [#uses=0]
- ret void
-
-cond_true1923: ; No predecessors!
- ret void
-
-cond_next1926: ; No predecessors!
- %tmp1929.not = icmp uge i8 %tmp238239, %tmp170171 ; <i1> [#uses=1]
- %tmp1939 = icmp ugt i8 %tmp238239, %tmp306307 ; <i1> [#uses=2]
- %bothcond = and i1 %tmp1939, %tmp1929.not ; <i1> [#uses=0]
- ret void
-
-cond_true1946: ; No predecessors!
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 162 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind1895
-
-cond_next2149: ; No predecessors!
- invoke void @system__secondary_stack__ss_mark( %struct.system__secondary_stack__mark_id* %tmp46 sret )
- to label %invcont2150 unwind label %unwind1895
-
-invcont2150: ; preds = %cond_next2149
- %tmp2153 = getelementptr %struct.system__secondary_stack__mark_id* %tmp46, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp2154 = load i8** %tmp2153 ; <i8*> [#uses=3]
- %tmp2156 = getelementptr %struct.system__secondary_stack__mark_id* %tmp46, i32 0, i32 1 ; <i32*> [#uses=1]
- %tmp2157 = load i32* %tmp2156 ; <i32> [#uses=3]
- %tmp2168 = or i1 %tmp1939, %tmp1401 ; <i1> [#uses=1]
- br i1 %tmp2168, label %cond_true2171, label %cond_next2189
-
-cond_true2171: ; preds = %invcont2150
- invoke void @__gnat_rcheck_05( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 165 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind2172
-
-unwind2172: ; preds = %invcont2236, %invcont2219, %bb2205, %bb2203, %cond_true2171
- %eh_ptr2173 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=5]
- %eh_select2175 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2173, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid2250 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp2252 = icmp eq i32 %eh_select2175, %eh_typeid2250 ; <i1> [#uses=1]
- br i1 %tmp2252, label %eh_then2253, label %cleanup2284
-
-cond_next2189: ; preds = %invcont2150
- %tmp21902191 = and i32 %tmp218, 255 ; <i32> [#uses=1]
- %tmp2193 = sub i32 %tmp21902191, %tmp17811782 ; <i32> [#uses=1]
- %tmp2194 = getelementptr i8* %tmp1821, i32 %tmp2193 ; <i8*> [#uses=1]
- %tmp2195 = load i8* %tmp2194 ; <i8> [#uses=2]
- %tmp2197 = icmp ugt i8 %tmp2195, 6 ; <i1> [#uses=1]
- br i1 %tmp2197, label %bb2203, label %bb2205
-
-bb2203: ; preds = %cond_next2189
- invoke void @__gnat_rcheck_06( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 165 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind2172
-
-bb2205: ; preds = %cond_next2189
- %tmp22132214 = zext i8 %tmp2195 to i32 ; <i32> [#uses=1]
- invoke void @system__img_enum__image_enumeration_8( %struct.string___XUP* %tmp49 sret , i32 %tmp22132214, i64 or (i64 zext (i32 ptrtoint ([28 x i8]* @weekS.154 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.32.910 to i32) to i64), i64 32)), i8* getelementptr ([8 x i8]* @weekN.179, i32 0, i32 0) )
- to label %invcont2219 unwind label %unwind2172
-
-invcont2219: ; preds = %bb2205
- %tmp2221 = getelementptr %struct.string___XUP* %tmp49, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp2222 = load i8** %tmp2221 ; <i8*> [#uses=1]
- %tmp22225781 = ptrtoint i8* %tmp2222 to i32 ; <i32> [#uses=1]
- %tmp222257815782 = zext i32 %tmp22225781 to i64 ; <i64> [#uses=1]
- %tmp2224 = getelementptr %struct.string___XUP* %tmp49, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp2225 = load %struct.string___XUB** %tmp2224 ; <%struct.string___XUB*> [#uses=1]
- %tmp22255777 = ptrtoint %struct.string___XUB* %tmp2225 to i32 ; <i32> [#uses=1]
- %tmp222557775778 = zext i32 %tmp22255777 to i64 ; <i64> [#uses=1]
- %tmp2225577757785779 = shl i64 %tmp222557775778, 32 ; <i64> [#uses=1]
- %tmp2225577757785779.ins = or i64 %tmp2225577757785779, %tmp222257815782 ; <i64> [#uses=1]
- invoke void @system__string_ops__str_concat( %struct.string___XUP* %tmp52 sret , i64 or (i64 zext (i32 ptrtoint ([30 x i8]* @.str14 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.30.904 to i32) to i64), i64 32)), i64 %tmp2225577757785779.ins )
- to label %invcont2236 unwind label %unwind2172
-
-invcont2236: ; preds = %invcont2219
- %tmp2238 = getelementptr %struct.string___XUP* %tmp52, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp2239 = load i8** %tmp2238 ; <i8*> [#uses=1]
- %tmp22395769 = ptrtoint i8* %tmp2239 to i32 ; <i32> [#uses=1]
- %tmp223957695770 = zext i32 %tmp22395769 to i64 ; <i64> [#uses=1]
- %tmp2241 = getelementptr %struct.string___XUP* %tmp52, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp2242 = load %struct.string___XUB** %tmp2241 ; <%struct.string___XUB*> [#uses=1]
- %tmp22425765 = ptrtoint %struct.string___XUB* %tmp2242 to i32 ; <i32> [#uses=1]
- %tmp224257655766 = zext i32 %tmp22425765 to i64 ; <i64> [#uses=1]
- %tmp2242576557665767 = shl i64 %tmp224257655766, 32 ; <i64> [#uses=1]
- %tmp2242576557665767.ins = or i64 %tmp2242576557665767, %tmp223957695770 ; <i64> [#uses=1]
- invoke void @report__failed( i64 %tmp2242576557665767.ins )
- to label %cleanup2300 unwind label %unwind2172
-
-eh_then2253: ; preds = %unwind2172
- invoke void @__gnat_begin_handler( i8* %eh_ptr2173 )
- to label %invcont2261 unwind label %unwind2257
-
-unwind2257: ; preds = %invcont2263, %invcont2261, %eh_then2253
- %eh_ptr2258 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=2]
- %eh_select2260 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2258, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_ptr2173 )
- to label %cleanup2284 unwind label %unwind2274
-
-invcont2261: ; preds = %eh_then2253
- %tmp2262 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp2262( )
- to label %invcont2263 unwind label %unwind2257
-
-invcont2263: ; preds = %invcont2261
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([28 x i8]* @.str15 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.32.910 to i32) to i64), i64 32)) )
- to label %cleanup2272 unwind label %unwind2257
-
-cleanup2272: ; preds = %invcont2263
- invoke void @__gnat_end_handler( i8* %eh_ptr2173 )
- to label %cleanup2300 unwind label %unwind2274
-
-unwind2274: ; preds = %cleanup2272, %unwind2257
- %eh_ptr2275 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=2]
- %eh_select2277 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2275, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=1]
- %tmp229055456023 = ptrtoint i8* %tmp2154 to i32 ; <i32> [#uses=1]
- %tmp2290554555466024 = zext i32 %tmp229055456023 to i64 ; <i64> [#uses=1]
- %tmp229355426025 = zext i32 %tmp2157 to i64 ; <i64> [#uses=1]
- %tmp2293554255436026 = shl i64 %tmp229355426025, 32 ; <i64> [#uses=1]
- %tmp229355425543.ins6027 = or i64 %tmp2293554255436026, %tmp2290554555466024 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp229355425543.ins6027 )
- to label %cleanup2318 unwind label %unwind1895
-
-cleanup2284: ; preds = %unwind2257, %unwind2172
- %eh_selector.24 = phi i32 [ %eh_select2175, %unwind2172 ], [ %eh_select2260, %unwind2257 ] ; <i32> [#uses=1]
- %eh_exception.26 = phi i8* [ %eh_ptr2173, %unwind2172 ], [ %eh_ptr2258, %unwind2257 ] ; <i8*> [#uses=1]
- %tmp22905545 = ptrtoint i8* %tmp2154 to i32 ; <i32> [#uses=1]
- %tmp229055455546 = zext i32 %tmp22905545 to i64 ; <i64> [#uses=1]
- %tmp22935542 = zext i32 %tmp2157 to i64 ; <i64> [#uses=1]
- %tmp229355425543 = shl i64 %tmp22935542, 32 ; <i64> [#uses=1]
- %tmp229355425543.ins = or i64 %tmp229355425543, %tmp229055455546 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp229355425543.ins )
- to label %cleanup2318 unwind label %unwind1895
-
-cleanup2300: ; preds = %cleanup2272, %invcont2236
- %tmp23075539 = ptrtoint i8* %tmp2154 to i32 ; <i32> [#uses=1]
- %tmp230755395540 = zext i32 %tmp23075539 to i64 ; <i64> [#uses=1]
- %tmp23105536 = zext i32 %tmp2157 to i64 ; <i64> [#uses=1]
- %tmp231055365537 = shl i64 %tmp23105536, 32 ; <i64> [#uses=1]
- %tmp231055365537.ins = or i64 %tmp231055365537, %tmp230755395540 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp231055365537.ins )
- to label %cleanup2371 unwind label %unwind1895
-
-cleanup2318: ; preds = %cleanup2284, %unwind2274
- %eh_selector.246021.1 = phi i32 [ %eh_select2277, %unwind2274 ], [ %eh_selector.24, %cleanup2284 ] ; <i32> [#uses=2]
- %eh_exception.266022.1 = phi i8* [ %eh_ptr2275, %unwind2274 ], [ %eh_exception.26, %cleanup2284 ] ; <i8*> [#uses=2]
- %eh_typeid2319 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp2321 = icmp eq i32 %eh_selector.246021.1, %eh_typeid2319 ; <i1> [#uses=1]
- br i1 %tmp2321, label %eh_then2322, label %eh_else2340
-
-eh_then2322: ; preds = %cleanup2318, %unwind1895
- %eh_exception.216011.0 = phi i8* [ %eh_ptr1896, %unwind1895 ], [ %eh_exception.266022.1, %cleanup2318 ] ; <i8*> [#uses=3]
- invoke void @__gnat_begin_handler( i8* %eh_exception.216011.0 )
- to label %invcont2328 unwind label %unwind2326
-
-unwind2326: ; preds = %invcont2328, %eh_then2322
- %eh_ptr2327 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_exception.216011.0 )
- to label %cleanup2369 unwind label %unwind2334
-
-invcont2328: ; preds = %eh_then2322
- %tmp2329 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp2329( )
- to label %cleanup2332 unwind label %unwind2326
-
-cleanup2332: ; preds = %invcont2328
- invoke void @__gnat_end_handler( i8* %eh_exception.216011.0 )
- to label %cleanup2371 unwind label %unwind2334
-
-unwind2334: ; preds = %cleanup2361, %unwind2348, %cleanup2332, %unwind2326
- %eh_ptr2335 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @llvm.stackrestore( i8* %tmp1780 )
- call void @llvm.stackrestore( i8* %tmp1780 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr2335 ) ; <i32>:8 [#uses=0]
- unreachable
-
-eh_else2340: ; preds = %cleanup2318, %unwind1895
- %eh_selector.196009.1 = phi i32 [ %eh_select1898, %unwind1895 ], [ %eh_selector.246021.1, %cleanup2318 ] ; <i32> [#uses=1]
- %eh_exception.216011.1 = phi i8* [ %eh_ptr1896, %unwind1895 ], [ %eh_exception.266022.1, %cleanup2318 ] ; <i8*> [#uses=4]
- %eh_typeid2341 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp2343 = icmp eq i32 %eh_selector.196009.1, %eh_typeid2341 ; <i1> [#uses=1]
- br i1 %tmp2343, label %eh_then2344, label %cleanup2369
-
-eh_then2344: ; preds = %eh_else2340
- invoke void @__gnat_begin_handler( i8* %eh_exception.216011.1 )
- to label %invcont2350 unwind label %unwind2348
-
-unwind2348: ; preds = %invcont2352, %invcont2350, %eh_then2344
- %eh_ptr2349 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_exception.216011.1 )
- to label %cleanup2369 unwind label %unwind2334
-
-invcont2350: ; preds = %eh_then2344
- %tmp2351 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp2351( )
- to label %invcont2352 unwind label %unwind2348
-
-invcont2352: ; preds = %invcont2350
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([24 x i8]* @.str16 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.35.915 to i32) to i64), i64 32)) )
- to label %cleanup2361 unwind label %unwind2348
-
-cleanup2361: ; preds = %invcont2352
- invoke void @__gnat_end_handler( i8* %eh_exception.216011.1 )
- to label %cleanup2371 unwind label %unwind2334
-
-cleanup2369: ; preds = %unwind2348, %eh_else2340, %unwind2326
- %eh_exception.28 = phi i8* [ %eh_ptr2327, %unwind2326 ], [ %eh_exception.216011.1, %eh_else2340 ], [ %eh_ptr2349, %unwind2348 ] ; <i8*> [#uses=1]
- call void @llvm.stackrestore( i8* %tmp1780 )
- call void @llvm.stackrestore( i8* %tmp1780 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_exception.28 ) ; <i32>:9 [#uses=0]
- unreachable
-
-cleanup2371: ; preds = %cleanup2361, %cleanup2332, %cleanup2300
- call void @llvm.stackrestore( i8* %tmp1780 )
- call void @llvm.stackrestore( i8* %tmp1780 )
- invoke void @system__secondary_stack__ss_mark( %struct.system__secondary_stack__mark_id* %tmp55 sret )
- to label %invcont2382 unwind label %unwind2378
-
-unwind2378: ; preds = %cleanup2371
- %eh_ptr2379 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select2381 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2379, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid26496037 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp26516039 = icmp eq i32 %eh_select2381, %eh_typeid26496037 ; <i1> [#uses=1]
- br i1 %tmp26516039, label %eh_then2652, label %eh_else2666
-
-invcont2382: ; preds = %cleanup2371
- %tmp2385 = getelementptr %struct.system__secondary_stack__mark_id* %tmp55, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp2386 = load i8** %tmp2385 ; <i8*> [#uses=2]
- %tmp2388 = getelementptr %struct.system__secondary_stack__mark_id* %tmp55, i32 0, i32 1 ; <i32*> [#uses=1]
- %tmp2389 = load i32* %tmp2388 ; <i32> [#uses=2]
- %tmp2390 = call i8* @llvm.stacksave( ) ; <i8*> [#uses=3]
- %tmp2393 = icmp ult i8 %tmp306307, %tmp170171 ; <i1> [#uses=1]
- br i1 %tmp2393, label %cond_next2417, label %cond_true2396
-
-cond_true2396: ; preds = %invcont2382
- %tmp2399 = icmp ult i8 %tmp170171, %tmp204205 ; <i1> [#uses=1]
- %tmp2403 = icmp ugt i8 %tmp306307, %tmp272273 ; <i1> [#uses=1]
- %tmp2407 = or i1 %tmp2403, %tmp2399 ; <i1> [#uses=1]
- br i1 %tmp2407, label %cond_true2410, label %cond_next2417
-
-cond_true2410: ; preds = %cond_true2396
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 177 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind2411
-
-unwind2411: ; preds = %invcont2591, %invcont2574, %bb2560, %bb2558, %bb2524, %bb2506, %cond_true2410
- %eh_ptr2412 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select2414 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2412, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %tmp26315527 = ptrtoint i8* %tmp2386 to i32 ; <i32> [#uses=1]
- %tmp263155275528 = zext i32 %tmp26315527 to i64 ; <i64> [#uses=1]
- %tmp26345524 = zext i32 %tmp2389 to i64 ; <i64> [#uses=1]
- %tmp263455245525 = shl i64 %tmp26345524, 32 ; <i64> [#uses=1]
- %tmp263455245525.ins = or i64 %tmp263455245525, %tmp263155275528 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp263455245525.ins )
- to label %cleanup2644 unwind label %unwind2618
-
-cond_next2417: ; preds = %cond_true2396, %invcont2382
- %tmp2493 = icmp ugt i8 %tmp170171, %tmp238239 ; <i1> [#uses=1]
- %tmp2500 = icmp ugt i8 %tmp238239, %tmp306307 ; <i1> [#uses=1]
- %bothcond5903 = or i1 %tmp2500, %tmp2493 ; <i1> [#uses=1]
- br i1 %bothcond5903, label %bb2506, label %cond_next2515
-
-bb2506: ; preds = %cond_next2417
- invoke void @__gnat_rcheck_05( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 180 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind2411
-
-cond_next2515: ; preds = %cond_next2417
- br i1 %tmp240, label %bb2524, label %bb2526
-
-bb2524: ; preds = %cond_next2515
- invoke void @__gnat_rcheck_06( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 180 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind2411
-
-bb2526: ; preds = %cond_next2515
- br i1 %tmp274, label %bb2558, label %bb2560
-
-bb2558: ; preds = %bb2526
- invoke void @__gnat_rcheck_06( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 182 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind2411
-
-bb2560: ; preds = %bb2526
- invoke void @system__img_enum__image_enumeration_8( %struct.string___XUP* %tmp58 sret , i32 %tmp13831384, i64 or (i64 zext (i32 ptrtoint ([28 x i8]* @weekS.154 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.32.910 to i32) to i64), i64 32)), i8* getelementptr ([8 x i8]* @weekN.179, i32 0, i32 0) )
- to label %invcont2574 unwind label %unwind2411
-
-invcont2574: ; preds = %bb2560
- %tmp2576 = getelementptr %struct.string___XUP* %tmp58, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp2577 = load i8** %tmp2576 ; <i8*> [#uses=1]
- %tmp25775747 = ptrtoint i8* %tmp2577 to i32 ; <i32> [#uses=1]
- %tmp257757475748 = zext i32 %tmp25775747 to i64 ; <i64> [#uses=1]
- %tmp2579 = getelementptr %struct.string___XUP* %tmp58, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp2580 = load %struct.string___XUB** %tmp2579 ; <%struct.string___XUB*> [#uses=1]
- %tmp25805743 = ptrtoint %struct.string___XUB* %tmp2580 to i32 ; <i32> [#uses=1]
- %tmp258057435744 = zext i32 %tmp25805743 to i64 ; <i64> [#uses=1]
- %tmp2580574357445745 = shl i64 %tmp258057435744, 32 ; <i64> [#uses=1]
- %tmp2580574357445745.ins = or i64 %tmp2580574357445745, %tmp257757475748 ; <i64> [#uses=1]
- invoke void @system__string_ops__str_concat( %struct.string___XUP* %tmp61 sret , i64 or (i64 zext (i32 ptrtoint ([30 x i8]* @.str17 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.30.904 to i32) to i64), i64 32)), i64 %tmp2580574357445745.ins )
- to label %invcont2591 unwind label %unwind2411
-
-invcont2591: ; preds = %invcont2574
- %tmp2593 = getelementptr %struct.string___XUP* %tmp61, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp2594 = load i8** %tmp2593 ; <i8*> [#uses=1]
- %tmp25945735 = ptrtoint i8* %tmp2594 to i32 ; <i32> [#uses=1]
- %tmp259457355736 = zext i32 %tmp25945735 to i64 ; <i64> [#uses=1]
- %tmp2596 = getelementptr %struct.string___XUP* %tmp61, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp2597 = load %struct.string___XUB** %tmp2596 ; <%struct.string___XUB*> [#uses=1]
- %tmp25975731 = ptrtoint %struct.string___XUB* %tmp2597 to i32 ; <i32> [#uses=1]
- %tmp259757315732 = zext i32 %tmp25975731 to i64 ; <i64> [#uses=1]
- %tmp2597573157325733 = shl i64 %tmp259757315732, 32 ; <i64> [#uses=1]
- %tmp2597573157325733.ins = or i64 %tmp2597573157325733, %tmp259457355736 ; <i64> [#uses=1]
- invoke void @report__failed( i64 %tmp2597573157325733.ins )
- to label %cleanup2604 unwind label %unwind2411
-
-cleanup2604: ; preds = %invcont2591
- %tmp26105533 = ptrtoint i8* %tmp2386 to i32 ; <i32> [#uses=1]
- %tmp261055335534 = zext i32 %tmp26105533 to i64 ; <i64> [#uses=1]
- %tmp26135530 = zext i32 %tmp2389 to i64 ; <i64> [#uses=1]
- %tmp261355305531 = shl i64 %tmp26135530, 32 ; <i64> [#uses=1]
- %tmp261355305531.ins = or i64 %tmp261355305531, %tmp261055335534 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp261355305531.ins )
- to label %cleanup2642 unwind label %unwind2618
-
-unwind2618: ; preds = %cleanup2604, %unwind2411
- %eh_ptr2619 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select2621 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2619, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=2]
- call void @llvm.stackrestore( i8* %tmp2390 )
- %eh_typeid26493 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp26514 = icmp eq i32 %eh_select2621, %eh_typeid26493 ; <i1> [#uses=1]
- br i1 %tmp26514, label %eh_then2652, label %eh_else2666
-
-cleanup2642: ; preds = %cleanup2604
- call void @llvm.stackrestore( i8* %tmp2390 )
- %tmp26946042 = icmp ult i8 %tmp238239, %tmp137138 ; <i1> [#uses=1]
- br i1 %tmp26946042, label %cond_next2718, label %cond_true2697
-
-cleanup2644: ; preds = %unwind2411
- call void @llvm.stackrestore( i8* %tmp2390 )
- %eh_typeid2649 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp2651 = icmp eq i32 %eh_select2414, %eh_typeid2649 ; <i1> [#uses=1]
- br i1 %tmp2651, label %eh_then2652, label %eh_else2666
-
-eh_then2652: ; preds = %cleanup2644, %unwind2618, %unwind2378
- %eh_exception.296030.0 = phi i8* [ %eh_ptr2379, %unwind2378 ], [ %eh_ptr2619, %unwind2618 ], [ %eh_ptr2412, %cleanup2644 ] ; <i8*> [#uses=3]
- invoke void @__gnat_begin_handler( i8* %eh_exception.296030.0 )
- to label %invcont2658 unwind label %unwind2656
-
-unwind2656: ; preds = %invcont2658, %eh_then2652
- %eh_ptr2657 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_exception.296030.0 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr2657 ) ; <i32>:10 [#uses=0]
- unreachable
-
-invcont2658: ; preds = %eh_then2652
- %tmp2659 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp2659( )
- to label %cleanup2662 unwind label %unwind2656
-
-cleanup2662: ; preds = %invcont2658
- call void @__gnat_end_handler( i8* %eh_exception.296030.0 )
- %tmp26946043 = icmp ult i8 %tmp238239, %tmp137138 ; <i1> [#uses=1]
- br i1 %tmp26946043, label %cond_next2718, label %cond_true2697
-
-eh_else2666: ; preds = %cleanup2644, %unwind2618, %unwind2378
- %eh_selector.256028.1 = phi i32 [ %eh_select2381, %unwind2378 ], [ %eh_select2621, %unwind2618 ], [ %eh_select2414, %cleanup2644 ] ; <i32> [#uses=1]
- %eh_exception.296030.1 = phi i8* [ %eh_ptr2379, %unwind2378 ], [ %eh_ptr2619, %unwind2618 ], [ %eh_ptr2412, %cleanup2644 ] ; <i8*> [#uses=4]
- %eh_typeid2667 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp2669 = icmp eq i32 %eh_selector.256028.1, %eh_typeid2667 ; <i1> [#uses=1]
- br i1 %tmp2669, label %eh_then2670, label %Unwind
-
-eh_then2670: ; preds = %eh_else2666
- invoke void @__gnat_begin_handler( i8* %eh_exception.296030.1 )
- to label %invcont2676 unwind label %unwind2674
-
-unwind2674: ; preds = %invcont2678, %invcont2676, %eh_then2670
- %eh_ptr2675 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_exception.296030.1 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr2675 ) ; <i32>:11 [#uses=0]
- unreachable
-
-invcont2676: ; preds = %eh_then2670
- %tmp2677 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp2677( )
- to label %invcont2678 unwind label %unwind2674
-
-invcont2678: ; preds = %invcont2676
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([24 x i8]* @.str18 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.35.915 to i32) to i64), i64 32)) )
- to label %cleanup2687 unwind label %unwind2674
-
-cleanup2687: ; preds = %invcont2678
- call void @__gnat_end_handler( i8* %eh_exception.296030.1 )
- %tmp2694 = icmp ult i8 %tmp238239, %tmp137138 ; <i1> [#uses=1]
- br i1 %tmp2694, label %cond_next2718, label %cond_true2697
-
-cond_true2697: ; preds = %cleanup2687, %cleanup2662, %cleanup2642
- %tmp2700 = icmp ult i8 %tmp137138, %tmp204205 ; <i1> [#uses=1]
- %tmp2704 = icmp ugt i8 %tmp238239, %tmp272273 ; <i1> [#uses=1]
- %tmp2708 = or i1 %tmp2704, %tmp2700 ; <i1> [#uses=1]
- br i1 %tmp2708, label %cond_true2711, label %cond_next2718
-
-cond_true2711: ; preds = %cond_true2697
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 192 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind2712
-
-unwind2712: ; preds = %cleanup2990, %unwind2975, %cond_true2711
- %eh_ptr2713 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select2715 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2713, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid29996053 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp30016055 = icmp eq i32 %eh_select2715, %eh_typeid29996053 ; <i1> [#uses=1]
- br i1 %tmp30016055, label %eh_then3002, label %eh_else3016
-
-cond_next2718: ; preds = %cond_true2697, %cleanup2687, %cleanup2662, %cleanup2642
- invoke void @system__secondary_stack__ss_mark( %struct.system__secondary_stack__mark_id* %tmp63 sret )
- to label %invcont2766 unwind label %unwind2762
-
-unwind2762: ; preds = %cond_next2718
- %eh_ptr2763 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select2765 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2763, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid29686060 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp29706061 = icmp eq i32 %eh_select2765, %eh_typeid29686060 ; <i1> [#uses=1]
- br i1 %tmp29706061, label %eh_then2971, label %cleanup2998
-
-invcont2766: ; preds = %cond_next2718
- %tmp2769 = getelementptr %struct.system__secondary_stack__mark_id* %tmp63, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp2770 = load i8** %tmp2769 ; <i8*> [#uses=2]
- %tmp2772 = getelementptr %struct.system__secondary_stack__mark_id* %tmp63, i32 0, i32 1 ; <i32*> [#uses=1]
- %tmp2773 = load i32* %tmp2772 ; <i32> [#uses=2]
- %tmp2774 = call i8* @llvm.stacksave( ) ; <i8*> [#uses=3]
- %tmp2808 = icmp ugt i8 %tmp137138, %tmp204205 ; <i1> [#uses=1]
- %tmp2815 = icmp ult i8 %tmp238239, %tmp204205 ; <i1> [#uses=1]
- %bothcond5904 = or i1 %tmp2815, %tmp2808 ; <i1> [#uses=1]
- br i1 %bothcond5904, label %bb2821, label %cond_next2834
-
-bb2821: ; preds = %invcont2766
- invoke void @__gnat_rcheck_05( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 198 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind2822
-
-unwind2822: ; preds = %invcont2910, %invcont2893, %bb2879, %bb2877, %bb2843, %bb2821
- %eh_ptr2823 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select2825 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2823, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %tmp29295521 = ptrtoint i8* %tmp2770 to i32 ; <i32> [#uses=1]
- %tmp292955215522 = zext i32 %tmp29295521 to i64 ; <i64> [#uses=1]
- %tmp29325518 = zext i32 %tmp2773 to i64 ; <i64> [#uses=1]
- %tmp293255185519 = shl i64 %tmp29325518, 32 ; <i64> [#uses=1]
- %tmp293255185519.ins = or i64 %tmp293255185519, %tmp292955215522 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp293255185519.ins )
- to label %cleanup2963 unwind label %unwind2937
-
-cond_next2834: ; preds = %invcont2766
- br i1 %tmp206, label %bb2843, label %bb2845
-
-bb2843: ; preds = %cond_next2834
- invoke void @__gnat_rcheck_06( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 198 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind2822
-
-bb2845: ; preds = %cond_next2834
- br i1 %tmp274, label %bb2877, label %bb2879
-
-bb2877: ; preds = %bb2845
- invoke void @__gnat_rcheck_06( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 200 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind2822
-
-bb2879: ; preds = %bb2845
- invoke void @system__img_enum__image_enumeration_8( %struct.string___XUP* %tmp66 sret , i32 %tmp13831384, i64 or (i64 zext (i32 ptrtoint ([28 x i8]* @weekS.154 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.32.910 to i32) to i64), i64 32)), i8* getelementptr ([8 x i8]* @weekN.179, i32 0, i32 0) )
- to label %invcont2893 unwind label %unwind2822
-
-invcont2893: ; preds = %bb2879
- %tmp2895 = getelementptr %struct.string___XUP* %tmp66, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp2896 = load i8** %tmp2895 ; <i8*> [#uses=1]
- %tmp28965718 = ptrtoint i8* %tmp2896 to i32 ; <i32> [#uses=1]
- %tmp289657185719 = zext i32 %tmp28965718 to i64 ; <i64> [#uses=1]
- %tmp2898 = getelementptr %struct.string___XUP* %tmp66, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp2899 = load %struct.string___XUB** %tmp2898 ; <%struct.string___XUB*> [#uses=1]
- %tmp28995714 = ptrtoint %struct.string___XUB* %tmp2899 to i32 ; <i32> [#uses=1]
- %tmp289957145715 = zext i32 %tmp28995714 to i64 ; <i64> [#uses=1]
- %tmp2899571457155716 = shl i64 %tmp289957145715, 32 ; <i64> [#uses=1]
- %tmp2899571457155716.ins = or i64 %tmp2899571457155716, %tmp289657185719 ; <i64> [#uses=1]
- invoke void @system__string_ops__str_concat( %struct.string___XUP* %tmp69 sret , i64 or (i64 zext (i32 ptrtoint ([31 x i8]* @.str19 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.98.1466 to i32) to i64), i64 32)), i64 %tmp2899571457155716.ins )
- to label %invcont2910 unwind label %unwind2822
-
-invcont2910: ; preds = %invcont2893
- %tmp2912 = getelementptr %struct.string___XUP* %tmp69, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp2913 = load i8** %tmp2912 ; <i8*> [#uses=1]
- %tmp29135706 = ptrtoint i8* %tmp2913 to i32 ; <i32> [#uses=1]
- %tmp291357065707 = zext i32 %tmp29135706 to i64 ; <i64> [#uses=1]
- %tmp2915 = getelementptr %struct.string___XUP* %tmp69, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp2916 = load %struct.string___XUB** %tmp2915 ; <%struct.string___XUB*> [#uses=1]
- %tmp29165702 = ptrtoint %struct.string___XUB* %tmp2916 to i32 ; <i32> [#uses=1]
- %tmp291657025703 = zext i32 %tmp29165702 to i64 ; <i64> [#uses=1]
- %tmp2916570257035704 = shl i64 %tmp291657025703, 32 ; <i64> [#uses=1]
- %tmp2916570257035704.ins = or i64 %tmp2916570257035704, %tmp291357065707 ; <i64> [#uses=1]
- invoke void @report__failed( i64 %tmp2916570257035704.ins )
- to label %cleanup2943 unwind label %unwind2822
-
-unwind2937: ; preds = %cleanup2943, %unwind2822
- %eh_ptr2938 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select2940 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2938, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=2]
- call void @llvm.stackrestore( i8* %tmp2774 )
- %eh_typeid29685 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp29706 = icmp eq i32 %eh_select2940, %eh_typeid29685 ; <i1> [#uses=1]
- br i1 %tmp29706, label %eh_then2971, label %cleanup2998
-
-cleanup2943: ; preds = %invcont2910
- %tmp29505515 = ptrtoint i8* %tmp2770 to i32 ; <i32> [#uses=1]
- %tmp295055155516 = zext i32 %tmp29505515 to i64 ; <i64> [#uses=1]
- %tmp29535512 = zext i32 %tmp2773 to i64 ; <i64> [#uses=1]
- %tmp295355125513 = shl i64 %tmp29535512, 32 ; <i64> [#uses=1]
- %tmp295355125513.ins = or i64 %tmp295355125513, %tmp295055155516 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp295355125513.ins )
- to label %cleanup2961 unwind label %unwind2937
-
-cleanup2961: ; preds = %cleanup2943
- call void @llvm.stackrestore( i8* %tmp2774 )
- %tmp3044.not6066 = icmp uge i8 %tmp272273, %tmp170171 ; <i1> [#uses=1]
- %tmp30506067 = icmp ult i8 %tmp170171, %tmp204205 ; <i1> [#uses=1]
- %bothcond59056068 = and i1 %tmp3044.not6066, %tmp30506067 ; <i1> [#uses=1]
- br i1 %bothcond59056068, label %cond_true3061, label %cond_next3068
-
-cleanup2963: ; preds = %unwind2822
- call void @llvm.stackrestore( i8* %tmp2774 )
- %eh_typeid2968 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp2970 = icmp eq i32 %eh_select2825, %eh_typeid2968 ; <i1> [#uses=1]
- br i1 %tmp2970, label %eh_then2971, label %cleanup2998
-
-eh_then2971: ; preds = %cleanup2963, %unwind2937, %unwind2762
- %eh_exception.356056.0 = phi i8* [ %eh_ptr2763, %unwind2762 ], [ %eh_ptr2938, %unwind2937 ], [ %eh_ptr2823, %cleanup2963 ] ; <i8*> [#uses=3]
- invoke void @__gnat_begin_handler( i8* %eh_exception.356056.0 )
- to label %invcont2979 unwind label %unwind2975
-
-unwind2975: ; preds = %invcont2981, %invcont2979, %eh_then2971
- %eh_ptr2976 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=2]
- %eh_select2978 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr2976, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_exception.356056.0 )
- to label %cleanup2998 unwind label %unwind2712
-
-invcont2979: ; preds = %eh_then2971
- %tmp2980 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp2980( )
- to label %invcont2981 unwind label %unwind2975
-
-invcont2981: ; preds = %invcont2979
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([46 x i8]* @.str20 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.101.1473 to i32) to i64), i64 32)) )
- to label %cleanup2990 unwind label %unwind2975
-
-cleanup2990: ; preds = %invcont2981
- invoke void @__gnat_end_handler( i8* %eh_exception.356056.0 )
- to label %finally2997 unwind label %unwind2712
-
-cleanup2998: ; preds = %unwind2975, %cleanup2963, %unwind2937, %unwind2762
- %eh_selector.29 = phi i32 [ %eh_select2765, %unwind2762 ], [ %eh_select2940, %unwind2937 ], [ %eh_select2825, %cleanup2963 ], [ %eh_select2978, %unwind2975 ] ; <i32> [#uses=2]
- %eh_exception.33 = phi i8* [ %eh_ptr2763, %unwind2762 ], [ %eh_ptr2938, %unwind2937 ], [ %eh_ptr2823, %cleanup2963 ], [ %eh_ptr2976, %unwind2975 ] ; <i8*> [#uses=2]
- %eh_typeid2999 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp3001 = icmp eq i32 %eh_selector.29, %eh_typeid2999 ; <i1> [#uses=1]
- br i1 %tmp3001, label %eh_then3002, label %eh_else3016
-
-eh_then3002: ; preds = %cleanup2998, %unwind2712
- %eh_exception.336046.0 = phi i8* [ %eh_ptr2713, %unwind2712 ], [ %eh_exception.33, %cleanup2998 ] ; <i8*> [#uses=3]
- invoke void @__gnat_begin_handler( i8* %eh_exception.336046.0 )
- to label %invcont3008 unwind label %unwind3006
-
-unwind3006: ; preds = %invcont3008, %eh_then3002
- %eh_ptr3007 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_exception.336046.0 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr3007 ) ; <i32>:12 [#uses=0]
- unreachable
-
-invcont3008: ; preds = %eh_then3002
- %tmp3009 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp3009( )
- to label %cleanup3012 unwind label %unwind3006
-
-cleanup3012: ; preds = %invcont3008
- call void @__gnat_end_handler( i8* %eh_exception.336046.0 )
- %tmp3044.not6069 = icmp uge i8 %tmp272273, %tmp170171 ; <i1> [#uses=1]
- %tmp30506070 = icmp ult i8 %tmp170171, %tmp204205 ; <i1> [#uses=1]
- %bothcond59056071 = and i1 %tmp3044.not6069, %tmp30506070 ; <i1> [#uses=1]
- br i1 %bothcond59056071, label %cond_true3061, label %cond_next3068
-
-eh_else3016: ; preds = %cleanup2998, %unwind2712
- %eh_selector.296044.1 = phi i32 [ %eh_select2715, %unwind2712 ], [ %eh_selector.29, %cleanup2998 ] ; <i32> [#uses=1]
- %eh_exception.336046.1 = phi i8* [ %eh_ptr2713, %unwind2712 ], [ %eh_exception.33, %cleanup2998 ] ; <i8*> [#uses=4]
- %eh_typeid3017 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp3019 = icmp eq i32 %eh_selector.296044.1, %eh_typeid3017 ; <i1> [#uses=1]
- br i1 %tmp3019, label %eh_then3020, label %Unwind
-
-eh_then3020: ; preds = %eh_else3016
- invoke void @__gnat_begin_handler( i8* %eh_exception.336046.1 )
- to label %invcont3026 unwind label %unwind3024
-
-unwind3024: ; preds = %invcont3028, %invcont3026, %eh_then3020
- %eh_ptr3025 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_exception.336046.1 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr3025 ) ; <i32>:13 [#uses=0]
- unreachable
-
-invcont3026: ; preds = %eh_then3020
- %tmp3027 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp3027( )
- to label %invcont3028 unwind label %unwind3024
-
-invcont3028: ; preds = %invcont3026
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([25 x i8]* @.str21 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.104.1478 to i32) to i64), i64 32)) )
- to label %cleanup3037 unwind label %unwind3024
-
-cleanup3037: ; preds = %invcont3028
- call void @__gnat_end_handler( i8* %eh_exception.336046.1 )
- br label %finally2997
-
-finally2997: ; preds = %cleanup3037, %cleanup2990
- %tmp3044.not = icmp uge i8 %tmp272273, %tmp170171 ; <i1> [#uses=1]
- %tmp3050 = icmp ult i8 %tmp170171, %tmp204205 ; <i1> [#uses=1]
- %bothcond5905 = and i1 %tmp3044.not, %tmp3050 ; <i1> [#uses=1]
- br i1 %bothcond5905, label %cond_true3061, label %cond_next3068
-
-cond_true3061: ; preds = %finally2997, %cleanup3012, %cleanup2961
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 214 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3062
-
-unwind3062: ; preds = %cleanup3340, %unwind3325, %cond_true3061
- %eh_ptr3063 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select3065 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr3063, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid33496081 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp33516083 = icmp eq i32 %eh_select3065, %eh_typeid33496081 ; <i1> [#uses=1]
- br i1 %tmp33516083, label %eh_then3352, label %eh_else3366
-
-cond_next3068: ; preds = %finally2997, %cleanup3012, %cleanup2961
- invoke void @system__secondary_stack__ss_mark( %struct.system__secondary_stack__mark_id* %tmp72 sret )
- to label %invcont3116 unwind label %unwind3112
-
-unwind3112: ; preds = %cond_next3068
- %eh_ptr3113 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select3115 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr3113, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %eh_typeid33186088 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp33206089 = icmp eq i32 %eh_select3115, %eh_typeid33186088 ; <i1> [#uses=1]
- br i1 %tmp33206089, label %eh_then3321, label %cleanup3348
-
-invcont3116: ; preds = %cond_next3068
- %tmp3119 = getelementptr %struct.system__secondary_stack__mark_id* %tmp72, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp3120 = load i8** %tmp3119 ; <i8*> [#uses=2]
- %tmp3122 = getelementptr %struct.system__secondary_stack__mark_id* %tmp72, i32 0, i32 1 ; <i32*> [#uses=1]
- %tmp3123 = load i32* %tmp3122 ; <i32> [#uses=2]
- %tmp3124 = call i8* @llvm.stacksave( ) ; <i8*> [#uses=3]
- %tmp3158 = icmp ugt i8 %tmp170171, %tmp204205 ; <i1> [#uses=1]
- %bothcond5906 = or i1 %tmp364, %tmp3158 ; <i1> [#uses=1]
- br i1 %bothcond5906, label %bb3171, label %cond_next3184
-
-bb3171: ; preds = %invcont3116
- invoke void @__gnat_rcheck_05( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 220 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3172
-
-unwind3172: ; preds = %invcont3260, %invcont3243, %bb3229, %bb3227, %bb3193, %bb3171
- %eh_ptr3173 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select3175 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr3173, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=2]
- %tmp32795509 = ptrtoint i8* %tmp3120 to i32 ; <i32> [#uses=1]
- %tmp327955095510 = zext i32 %tmp32795509 to i64 ; <i64> [#uses=1]
- %tmp32825506 = zext i32 %tmp3123 to i64 ; <i64> [#uses=1]
- %tmp328255065507 = shl i64 %tmp32825506, 32 ; <i64> [#uses=1]
- %tmp328255065507.ins = or i64 %tmp328255065507, %tmp327955095510 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp328255065507.ins )
- to label %cleanup3313 unwind label %unwind3287
-
-cond_next3184: ; preds = %invcont3116
- br i1 %tmp206, label %bb3193, label %bb3195
-
-bb3193: ; preds = %cond_next3184
- invoke void @__gnat_rcheck_06( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 220 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3172
-
-bb3195: ; preds = %cond_next3184
- br i1 %tmp274, label %bb3227, label %bb3229
-
-bb3227: ; preds = %bb3195
- invoke void @__gnat_rcheck_06( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 222 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3172
-
-bb3229: ; preds = %bb3195
- invoke void @system__img_enum__image_enumeration_8( %struct.string___XUP* %tmp75 sret , i32 %tmp13831384, i64 or (i64 zext (i32 ptrtoint ([28 x i8]* @weekS.154 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.32.910 to i32) to i64), i64 32)), i8* getelementptr ([8 x i8]* @weekN.179, i32 0, i32 0) )
- to label %invcont3243 unwind label %unwind3172
-
-invcont3243: ; preds = %bb3229
- %tmp3245 = getelementptr %struct.string___XUP* %tmp75, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp3246 = load i8** %tmp3245 ; <i8*> [#uses=1]
- %tmp32465684 = ptrtoint i8* %tmp3246 to i32 ; <i32> [#uses=1]
- %tmp324656845685 = zext i32 %tmp32465684 to i64 ; <i64> [#uses=1]
- %tmp3248 = getelementptr %struct.string___XUP* %tmp75, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp3249 = load %struct.string___XUB** %tmp3248 ; <%struct.string___XUB*> [#uses=1]
- %tmp32495680 = ptrtoint %struct.string___XUB* %tmp3249 to i32 ; <i32> [#uses=1]
- %tmp324956805681 = zext i32 %tmp32495680 to i64 ; <i64> [#uses=1]
- %tmp3249568056815682 = shl i64 %tmp324956805681, 32 ; <i64> [#uses=1]
- %tmp3249568056815682.ins = or i64 %tmp3249568056815682, %tmp324656845685 ; <i64> [#uses=1]
- invoke void @system__string_ops__str_concat( %struct.string___XUP* %tmp78 sret , i64 or (i64 zext (i32 ptrtoint ([31 x i8]* @.str22 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.98.1466 to i32) to i64), i64 32)), i64 %tmp3249568056815682.ins )
- to label %invcont3260 unwind label %unwind3172
-
-invcont3260: ; preds = %invcont3243
- %tmp3262 = getelementptr %struct.string___XUP* %tmp78, i32 0, i32 0 ; <i8**> [#uses=1]
- %tmp3263 = load i8** %tmp3262 ; <i8*> [#uses=1]
- %tmp32635672 = ptrtoint i8* %tmp3263 to i32 ; <i32> [#uses=1]
- %tmp326356725673 = zext i32 %tmp32635672 to i64 ; <i64> [#uses=1]
- %tmp3265 = getelementptr %struct.string___XUP* %tmp78, i32 0, i32 1 ; <%struct.string___XUB**> [#uses=1]
- %tmp3266 = load %struct.string___XUB** %tmp3265 ; <%struct.string___XUB*> [#uses=1]
- %tmp32665668 = ptrtoint %struct.string___XUB* %tmp3266 to i32 ; <i32> [#uses=1]
- %tmp326656685669 = zext i32 %tmp32665668 to i64 ; <i64> [#uses=1]
- %tmp3266566856695670 = shl i64 %tmp326656685669, 32 ; <i64> [#uses=1]
- %tmp3266566856695670.ins = or i64 %tmp3266566856695670, %tmp326356725673 ; <i64> [#uses=1]
- invoke void @report__failed( i64 %tmp3266566856695670.ins )
- to label %cleanup3293 unwind label %unwind3172
-
-unwind3287: ; preds = %cleanup3293, %unwind3172
- %eh_ptr3288 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=3]
- %eh_select3290 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr3288, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=2]
- call void @llvm.stackrestore( i8* %tmp3124 )
- %eh_typeid33187 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp33208 = icmp eq i32 %eh_select3290, %eh_typeid33187 ; <i1> [#uses=1]
- br i1 %tmp33208, label %eh_then3321, label %cleanup3348
-
-cleanup3293: ; preds = %invcont3260
- %tmp33005503 = ptrtoint i8* %tmp3120 to i32 ; <i32> [#uses=1]
- %tmp330055035504 = zext i32 %tmp33005503 to i64 ; <i64> [#uses=1]
- %tmp33035500 = zext i32 %tmp3123 to i64 ; <i64> [#uses=1]
- %tmp330355005501 = shl i64 %tmp33035500, 32 ; <i64> [#uses=1]
- %tmp330355005501.ins = or i64 %tmp330355005501, %tmp330055035504 ; <i64> [#uses=1]
- invoke void @system__secondary_stack__ss_release( i64 %tmp330355005501.ins )
- to label %cleanup3311 unwind label %unwind3287
-
-cleanup3311: ; preds = %cleanup3293
- call void @llvm.stackrestore( i8* %tmp3124 )
- br label %finally3347
-
-cleanup3313: ; preds = %unwind3172
- call void @llvm.stackrestore( i8* %tmp3124 )
- %eh_typeid3318 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp3320 = icmp eq i32 %eh_select3175, %eh_typeid3318 ; <i1> [#uses=1]
- br i1 %tmp3320, label %eh_then3321, label %cleanup3348
-
-eh_then3321: ; preds = %cleanup3313, %unwind3287, %unwind3112
- %eh_exception.416084.0 = phi i8* [ %eh_ptr3113, %unwind3112 ], [ %eh_ptr3288, %unwind3287 ], [ %eh_ptr3173, %cleanup3313 ] ; <i8*> [#uses=3]
- invoke void @__gnat_begin_handler( i8* %eh_exception.416084.0 )
- to label %invcont3329 unwind label %unwind3325
-
-unwind3325: ; preds = %invcont3331, %invcont3329, %eh_then3321
- %eh_ptr3326 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=2]
- %eh_select3328 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr3326, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), %struct.exception* @constraint_error, i32* @__gnat_others_value ) ; <i32> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_exception.416084.0 )
- to label %cleanup3348 unwind label %unwind3062
-
-invcont3329: ; preds = %eh_then3321
- %tmp3330 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp3330( )
- to label %invcont3331 unwind label %unwind3325
-
-invcont3331: ; preds = %invcont3329
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([46 x i8]* @.str20 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.101.1473 to i32) to i64), i64 32)) )
- to label %cleanup3340 unwind label %unwind3325
-
-cleanup3340: ; preds = %invcont3331
- invoke void @__gnat_end_handler( i8* %eh_exception.416084.0 )
- to label %finally3347 unwind label %unwind3062
-
-cleanup3348: ; preds = %unwind3325, %cleanup3313, %unwind3287, %unwind3112
- %eh_selector.35 = phi i32 [ %eh_select3115, %unwind3112 ], [ %eh_select3290, %unwind3287 ], [ %eh_select3175, %cleanup3313 ], [ %eh_select3328, %unwind3325 ] ; <i32> [#uses=2]
- %eh_exception.39 = phi i8* [ %eh_ptr3113, %unwind3112 ], [ %eh_ptr3288, %unwind3287 ], [ %eh_ptr3173, %cleanup3313 ], [ %eh_ptr3326, %unwind3325 ] ; <i8*> [#uses=2]
- %eh_typeid3349 = call i32 @llvm.eh.typeid.for.i32( i8* getelementptr (%struct.exception* @constraint_error, i32 0, i32 0) ) ; <i32> [#uses=1]
- %tmp3351 = icmp eq i32 %eh_selector.35, %eh_typeid3349 ; <i1> [#uses=1]
- br i1 %tmp3351, label %eh_then3352, label %eh_else3366
-
-eh_then3352: ; preds = %cleanup3348, %unwind3062
- %eh_exception.396074.0 = phi i8* [ %eh_ptr3063, %unwind3062 ], [ %eh_exception.39, %cleanup3348 ] ; <i8*> [#uses=3]
- invoke void @__gnat_begin_handler( i8* %eh_exception.396074.0 )
- to label %invcont3358 unwind label %unwind3356
-
-unwind3356: ; preds = %invcont3358, %eh_then3352
- %eh_ptr3357 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_exception.396074.0 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr3357 ) ; <i32>:14 [#uses=0]
- unreachable
-
-invcont3358: ; preds = %eh_then3352
- %tmp3359 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp3359( )
- to label %cleanup3362 unwind label %unwind3356
-
-cleanup3362: ; preds = %invcont3358
- call void @__gnat_end_handler( i8* %eh_exception.396074.0 )
- br label %finally3347
-
-eh_else3366: ; preds = %cleanup3348, %unwind3062
- %eh_selector.356072.1 = phi i32 [ %eh_select3065, %unwind3062 ], [ %eh_selector.35, %cleanup3348 ] ; <i32> [#uses=1]
- %eh_exception.396074.1 = phi i8* [ %eh_ptr3063, %unwind3062 ], [ %eh_exception.39, %cleanup3348 ] ; <i8*> [#uses=4]
- %eh_typeid3367 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp3369 = icmp eq i32 %eh_selector.356072.1, %eh_typeid3367 ; <i1> [#uses=1]
- br i1 %tmp3369, label %eh_then3370, label %Unwind
-
-eh_then3370: ; preds = %eh_else3366
- invoke void @__gnat_begin_handler( i8* %eh_exception.396074.1 )
- to label %invcont3376 unwind label %unwind3374
-
-unwind3374: ; preds = %invcont3378, %invcont3376, %eh_then3370
- %eh_ptr3375 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_exception.396074.1 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr3375 ) ; <i32>:15 [#uses=0]
- unreachable
-
-invcont3376: ; preds = %eh_then3370
- %tmp3377 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp3377( )
- to label %invcont3378 unwind label %unwind3374
-
-invcont3378: ; preds = %invcont3376
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([25 x i8]* @.str23 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.104.1478 to i32) to i64), i64 32)) )
- to label %cleanup3387 unwind label %unwind3374
-
-cleanup3387: ; preds = %invcont3378
- call void @__gnat_end_handler( i8* %eh_exception.396074.1 )
- br label %finally3347
-
-finally3347: ; preds = %cleanup3387, %cleanup3362, %cleanup3340, %cleanup3311
- %tmp3392 = call i8* @llvm.stacksave( ) ; <i8*> [#uses=2]
- %tmp3398 = invoke i32 @report__ident_int( i32 -5 )
- to label %invcont3397 unwind label %unwind3393 ; <i32> [#uses=4]
-
-unwind3393: ; preds = %cond_true3555, %cond_true3543, %cond_next3451, %cond_true3448, %cond_true3420, %finally3347
- %eh_ptr3394 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=5]
- %eh_select3396 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr3394, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=1]
- call void @llvm.stackrestore( i8* %tmp3392 )
- %eh_typeid3571 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp3573 = icmp eq i32 %eh_select3396, %eh_typeid3571 ; <i1> [#uses=1]
- br i1 %tmp3573, label %eh_then3574, label %Unwind
-
-invcont3397: ; preds = %finally3347
- %tmp3405 = icmp slt i32 %tmp3398, %tmp384 ; <i1> [#uses=2]
- %tmp3413 = icmp sgt i32 %tmp3398, %tmp394 ; <i1> [#uses=1]
- %tmp3417 = or i1 %tmp3405, %tmp3413 ; <i1> [#uses=1]
- br i1 %tmp3417, label %cond_true3420, label %cond_next3422
-
-cond_true3420: ; preds = %invcont3397
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 238 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3393
-
-cond_next3422: ; preds = %invcont3397
- %tmp3426 = icmp slt i32 %tmp3398, -5 ; <i1> [#uses=1]
- br i1 %tmp3426, label %cond_true3429, label %cond_next3451
-
-cond_true3429: ; preds = %cond_next3422
- %tmp3441 = icmp slt i32 %tmp394, -6 ; <i1> [#uses=1]
- %tmp3445 = or i1 %tmp3405, %tmp3441 ; <i1> [#uses=1]
- br i1 %tmp3445, label %cond_true3448, label %cond_next3451
-
-cond_true3448: ; preds = %cond_true3429
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 238 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3393
-
-cond_next3451: ; preds = %cond_true3429, %cond_next3422
- %tmp3521 = invoke i32 @report__ident_int( i32 -5 )
- to label %invcont3520 unwind label %unwind3393 ; <i32> [#uses=3]
-
-invcont3520: ; preds = %cond_next3451
- %tmp3528 = icmp slt i32 %tmp3521, %tmp384 ; <i1> [#uses=1]
- %tmp3536 = icmp sgt i32 %tmp3521, %tmp394 ; <i1> [#uses=1]
- %tmp3540 = or i1 %tmp3528, %tmp3536 ; <i1> [#uses=1]
- br i1 %tmp3540, label %cond_true3543, label %cond_next3545
-
-cond_true3543: ; preds = %invcont3520
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 241 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3393
-
-cond_next3545: ; preds = %invcont3520
- %tmp3552 = icmp eq i32 %tmp3398, %tmp3521 ; <i1> [#uses=1]
- br i1 %tmp3552, label %cleanup3565, label %cond_true3555
-
-cond_true3555: ; preds = %cond_next3545
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([30 x i8]* @.str24 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.30.904 to i32) to i64), i64 32)) )
- to label %cleanup3565 unwind label %unwind3393
-
-cleanup3565: ; preds = %cond_true3555, %cond_next3545
- call void @llvm.stackrestore( i8* %tmp3392 )
- %tmp36006095 = icmp ult i8 %tmp137138, %sat.45934.0 ; <i1> [#uses=1]
- br i1 %tmp36006095, label %cond_next3624, label %cond_true3603
-
-eh_then3574: ; preds = %unwind3393
- invoke void @__gnat_begin_handler( i8* %eh_ptr3394 )
- to label %invcont3580 unwind label %unwind3578
-
-unwind3578: ; preds = %invcont3582, %invcont3580, %eh_then3574
- %eh_ptr3579 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr3394 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr3579 ) ; <i32>:16 [#uses=0]
- unreachable
-
-invcont3580: ; preds = %eh_then3574
- %tmp3581 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp3581( )
- to label %invcont3582 unwind label %unwind3578
-
-invcont3582: ; preds = %invcont3580
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([18 x i8]* @.str25 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.124.1606 to i32) to i64), i64 32)) )
- to label %cleanup3591 unwind label %unwind3578
-
-cleanup3591: ; preds = %invcont3582
- call void @__gnat_end_handler( i8* %eh_ptr3394 )
- %tmp3600 = icmp ult i8 %tmp137138, %sat.45934.0 ; <i1> [#uses=1]
- br i1 %tmp3600, label %cond_next3624, label %cond_true3603
-
-cond_true3603: ; preds = %cleanup3591, %cleanup3565
- %tmp3606 = icmp ult i8 %sat.45934.0, %tmp204205 ; <i1> [#uses=1]
- %tmp3610 = icmp ugt i8 %tmp137138, %tmp272273 ; <i1> [#uses=1]
- %tmp3614 = or i1 %tmp3606, %tmp3610 ; <i1> [#uses=1]
- br i1 %tmp3614, label %cond_true3617, label %cond_next3624
-
-cond_true3617: ; preds = %cond_true3603
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 250 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3618
-
-unwind3618: ; preds = %bb3743, %cond_true3729, %bb3689, %cond_true3675, %bb3635, %cond_true3617
- %wed.3 = phi i8 [ %tmp238239, %cond_true3617 ], [ %wed.1, %bb3743 ], [ %tmp238239, %bb3689 ], [ %tmp238239, %bb3635 ], [ %tmp238239, %cond_true3675 ], [ %tmp238239, %cond_true3729 ] ; <i8> [#uses=1]
- %tue.3 = phi i8 [ %tmp204205, %cond_true3617 ], [ %tue.2, %bb3743 ], [ %tue.2, %bb3689 ], [ %tue.1, %bb3635 ], [ %tue.2, %cond_true3675 ], [ %tue.2, %cond_true3729 ] ; <i8> [#uses=1]
- %mon.3 = phi i8 [ %tmp170171, %cond_true3617 ], [ %mon.2, %bb3743 ], [ %mon.1, %bb3689 ], [ %tmp170171, %bb3635 ], [ %tmp170171, %cond_true3675 ], [ %mon.2, %cond_true3729 ] ; <i8> [#uses=1]
- %eh_ptr3619 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=5]
- %eh_select3621 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr3619, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=1]
- %eh_typeid3854 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp3856 = icmp eq i32 %eh_select3621, %eh_typeid3854 ; <i1> [#uses=1]
- br i1 %tmp3856, label %eh_then3857, label %Unwind
-
-cond_next3624: ; preds = %cond_true3603, %cleanup3591, %cleanup3565
- %tmp3629 = icmp ugt i8 %sat.45934.0, %tmp137138 ; <i1> [#uses=1]
- br i1 %tmp3629, label %cond_next3653, label %bb3635
-
-bb3635: ; preds = %cond_next3649, %cond_next3624
- %indvar6258 = phi i8 [ %indvar.next16, %cond_next3649 ], [ 0, %cond_next3624 ] ; <i8> [#uses=2]
- %tue.1 = phi i8 [ %tue.0, %cond_next3649 ], [ %tmp204205, %cond_next3624 ] ; <i8> [#uses=2]
- %tmp3637 = invoke i8 @report__equal( i32 2, i32 2 )
- to label %invcont3636 unwind label %unwind3618 ; <i8> [#uses=1]
-
-invcont3636: ; preds = %bb3635
- %i3633.4 = add i8 %indvar6258, %sat.45934.0 ; <i8> [#uses=1]
- %tmp3638 = icmp eq i8 %tmp3637, 0 ; <i1> [#uses=1]
- %tue.0 = select i1 %tmp3638, i8 %tue.1, i8 2 ; <i8> [#uses=2]
- %tmp3645 = icmp eq i8 %i3633.4, %tmp137138 ; <i1> [#uses=1]
- br i1 %tmp3645, label %cond_next3653, label %cond_next3649
-
-cond_next3649: ; preds = %invcont3636
- %indvar.next16 = add i8 %indvar6258, 1 ; <i8> [#uses=1]
- br label %bb3635
-
-cond_next3653: ; preds = %invcont3636, %cond_next3624
- %tue.2 = phi i8 [ %tmp204205, %cond_next3624 ], [ %tue.0, %invcont3636 ] ; <i8> [#uses=6]
- %tmp3658 = icmp ult i8 %tmp238239, %tmp306307 ; <i1> [#uses=1]
- br i1 %tmp3658, label %cond_next3678, label %cond_true3661
-
-cond_true3661: ; preds = %cond_next3653
- %tmp3664 = icmp ult i8 %tmp306307, %tmp204205 ; <i1> [#uses=1]
- %tmp3668 = icmp ugt i8 %tmp238239, %tmp272273 ; <i1> [#uses=1]
- %tmp3672 = or i1 %tmp3664, %tmp3668 ; <i1> [#uses=1]
- br i1 %tmp3672, label %cond_true3675, label %cond_next3678
-
-cond_true3675: ; preds = %cond_true3661
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 257 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3618
-
-cond_next3678: ; preds = %cond_true3661, %cond_next3653
- %tmp3683 = icmp ugt i8 %tmp306307, %tmp238239 ; <i1> [#uses=1]
- br i1 %tmp3683, label %cond_next3707, label %bb3689
-
-bb3689: ; preds = %cond_next3703, %cond_next3678
- %indvar6261 = phi i8 [ %indvar.next18, %cond_next3703 ], [ 0, %cond_next3678 ] ; <i8> [#uses=2]
- %mon.1 = phi i8 [ %mon.0, %cond_next3703 ], [ %tmp170171, %cond_next3678 ] ; <i8> [#uses=2]
- %tmp3691 = invoke i8 @report__equal( i32 2, i32 2 )
- to label %invcont3690 unwind label %unwind3618 ; <i8> [#uses=1]
-
-invcont3690: ; preds = %bb3689
- %i3687.4 = add i8 %indvar6261, %tmp306307 ; <i8> [#uses=1]
- %tmp3692 = icmp eq i8 %tmp3691, 0 ; <i1> [#uses=1]
- %mon.0 = select i1 %tmp3692, i8 %mon.1, i8 1 ; <i8> [#uses=2]
- %tmp3699 = icmp eq i8 %i3687.4, %tmp238239 ; <i1> [#uses=1]
- br i1 %tmp3699, label %cond_next3707, label %cond_next3703
-
-cond_next3703: ; preds = %invcont3690
- %indvar.next18 = add i8 %indvar6261, 1 ; <i8> [#uses=1]
- br label %bb3689
-
-cond_next3707: ; preds = %invcont3690, %cond_next3678
- %mon.2 = phi i8 [ %tmp170171, %cond_next3678 ], [ %mon.0, %invcont3690 ] ; <i8> [#uses=8]
- %tmp3712 = icmp ult i8 %tmp137138, %mon.2 ; <i1> [#uses=1]
- br i1 %tmp3712, label %cond_next3732, label %cond_true3715
-
-cond_true3715: ; preds = %cond_next3707
- %tmp3718 = icmp ult i8 %mon.2, %tmp204205 ; <i1> [#uses=1]
- %tmp3722 = icmp ugt i8 %tmp137138, %tmp272273 ; <i1> [#uses=1]
- %tmp3726 = or i1 %tmp3718, %tmp3722 ; <i1> [#uses=1]
- br i1 %tmp3726, label %cond_true3729, label %cond_next3732
-
-cond_true3729: ; preds = %cond_true3715
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 264 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3618
-
-cond_next3732: ; preds = %cond_true3715, %cond_next3707
- %tmp3737 = icmp ugt i8 %mon.2, %tmp137138 ; <i1> [#uses=1]
- br i1 %tmp3737, label %finally3852, label %bb3743
-
-bb3743: ; preds = %cond_next3757, %cond_next3732
- %indvar6265 = phi i8 [ %indvar.next20, %cond_next3757 ], [ 0, %cond_next3732 ] ; <i8> [#uses=2]
- %wed.1 = phi i8 [ %wed.0, %cond_next3757 ], [ %tmp238239, %cond_next3732 ] ; <i8> [#uses=2]
- %tmp3745 = invoke i8 @report__equal( i32 3, i32 3 )
- to label %invcont3744 unwind label %unwind3618 ; <i8> [#uses=1]
-
-invcont3744: ; preds = %bb3743
- %i3741.4 = add i8 %indvar6265, %mon.2 ; <i8> [#uses=1]
- %tmp3746 = icmp eq i8 %tmp3745, 0 ; <i1> [#uses=1]
- %wed.0 = select i1 %tmp3746, i8 %wed.1, i8 3 ; <i8> [#uses=2]
- %tmp3753 = icmp eq i8 %i3741.4, %tmp137138 ; <i1> [#uses=1]
- br i1 %tmp3753, label %finally3852, label %cond_next3757
-
-cond_next3757: ; preds = %invcont3744
- %indvar.next20 = add i8 %indvar6265, 1 ; <i8> [#uses=1]
- br label %bb3743
-
-eh_then3857: ; preds = %unwind3618
- invoke void @__gnat_begin_handler( i8* %eh_ptr3619 )
- to label %invcont3863 unwind label %unwind3861
-
-unwind3861: ; preds = %invcont3865, %invcont3863, %eh_then3857
- %eh_ptr3862 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr3619 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr3862 ) ; <i32>:17 [#uses=0]
- unreachable
-
-invcont3863: ; preds = %eh_then3857
- %tmp3864 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp3864( )
- to label %invcont3865 unwind label %unwind3861
-
-invcont3865: ; preds = %invcont3863
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([18 x i8]* @.str26 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.124.1606 to i32) to i64), i64 32)) )
- to label %cleanup3874 unwind label %unwind3861
-
-cleanup3874: ; preds = %invcont3865
- call void @__gnat_end_handler( i8* %eh_ptr3619 )
- br label %finally3852
-
-finally3852: ; preds = %cleanup3874, %invcont3744, %cond_next3732
- %wed.4 = phi i8 [ %wed.3, %cleanup3874 ], [ %tmp238239, %cond_next3732 ], [ %wed.0, %invcont3744 ] ; <i8> [#uses=4]
- %tue.4 = phi i8 [ %tue.3, %cleanup3874 ], [ %tue.2, %cond_next3732 ], [ %tue.2, %invcont3744 ] ; <i8> [#uses=13]
- %mon.4 = phi i8 [ %mon.3, %cleanup3874 ], [ %mon.2, %cond_next3732 ], [ %mon.2, %invcont3744 ] ; <i8> [#uses=18]
- %tmp3885 = invoke i32 @report__ident_int( i32 -5 )
- to label %invcont3884 unwind label %unwind3880 ; <i32> [#uses=4]
-
-unwind3880: ; preds = %cond_true4138, %invcont4122, %cond_next4120, %cond_true4117, %cond_true4027, %cond_next3938, %cond_true3935, %cond_true3907, %finally3852
- %eh_ptr3881 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=5]
- %eh_select3883 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr3881, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=1]
- %eh_typeid4149 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp4151 = icmp eq i32 %eh_select3883, %eh_typeid4149 ; <i1> [#uses=1]
- br i1 %tmp4151, label %eh_then4152, label %Unwind
-
-invcont3884: ; preds = %finally3852
- %tmp3892 = icmp slt i32 %tmp3885, %tmp384 ; <i1> [#uses=2]
- %tmp3900 = icmp sgt i32 %tmp3885, %tmp394 ; <i1> [#uses=1]
- %tmp3904 = or i1 %tmp3892, %tmp3900 ; <i1> [#uses=1]
- br i1 %tmp3904, label %cond_true3907, label %cond_next3909
-
-cond_true3907: ; preds = %invcont3884
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 312 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3880
-
-cond_next3909: ; preds = %invcont3884
- %tmp3913 = icmp slt i32 %tmp3885, -5 ; <i1> [#uses=1]
- br i1 %tmp3913, label %cond_true3916, label %cond_next3938
-
-cond_true3916: ; preds = %cond_next3909
- %tmp3928 = icmp slt i32 %tmp394, -6 ; <i1> [#uses=1]
- %tmp3932 = or i1 %tmp3892, %tmp3928 ; <i1> [#uses=1]
- br i1 %tmp3932, label %cond_true3935, label %cond_next3938
-
-cond_true3935: ; preds = %cond_true3916
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 312 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3880
-
-cond_next3938: ; preds = %cond_true3916, %cond_next3909
- %tmp4005 = invoke i32 @report__ident_int( i32 -5 )
- to label %invcont4004 unwind label %unwind3880 ; <i32> [#uses=6]
-
-invcont4004: ; preds = %cond_next3938
- %tmp4012 = icmp slt i32 %tmp4005, %tmp384 ; <i1> [#uses=2]
- %tmp4020 = icmp sgt i32 %tmp4005, %tmp394 ; <i1> [#uses=1]
- %tmp4024 = or i1 %tmp4012, %tmp4020 ; <i1> [#uses=1]
- br i1 %tmp4024, label %cond_true4027, label %cond_next4029
-
-cond_true4027: ; preds = %invcont4004
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 313 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3880
-
-cond_next4029: ; preds = %invcont4004
- %tmp4071 = icmp sgt i32 %tmp4005, -6 ; <i1> [#uses=1]
- %tmp4078 = add i32 %tmp4005, 1073741823 ; <i32> [#uses=1]
- %iftmp.132.0 = select i1 %tmp4071, i32 %tmp4078, i32 1073741818 ; <i32> [#uses=1]
- %tmp4085 = sub i32 %iftmp.132.0, %tmp4005 ; <i32> [#uses=1]
- %tmp4086 = shl i32 %tmp4085, 2 ; <i32> [#uses=2]
- %tmp4087 = add i32 %tmp4086, 4 ; <i32> [#uses=1]
- %tmp4088 = icmp sgt i32 %tmp4087, -1 ; <i1> [#uses=1]
- %tmp4087.op = add i32 %tmp4086, 7 ; <i32> [#uses=1]
- %tmp4087.op.op = and i32 %tmp4087.op, -4 ; <i32> [#uses=1]
- %tmp4091 = select i1 %tmp4088, i32 %tmp4087.op.op, i32 0 ; <i32> [#uses=1]
- %tmp4095 = icmp slt i32 %tmp4005, -5 ; <i1> [#uses=1]
- br i1 %tmp4095, label %cond_true4098, label %cond_next4120
-
-cond_true4098: ; preds = %cond_next4029
- %tmp4110 = icmp slt i32 %tmp394, -6 ; <i1> [#uses=1]
- %tmp4114 = or i1 %tmp4012, %tmp4110 ; <i1> [#uses=1]
- br i1 %tmp4114, label %cond_true4117, label %cond_next4120
-
-cond_true4117: ; preds = %cond_true4098
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 313 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind3880
-
-cond_next4120: ; preds = %cond_true4098, %cond_next4029
- %tmp4123 = invoke i8* @__gnat_malloc( i32 %tmp4091 )
- to label %invcont4122 unwind label %unwind3880 ; <i8*> [#uses=0]
-
-invcont4122: ; preds = %cond_next4120
- %tmp41254128 = sext i32 %tmp3885 to i64 ; <i64> [#uses=1]
- %tmp4129 = sub i64 -5, %tmp41254128 ; <i64> [#uses=2]
- %tmp4134 = invoke i32 @report__ident_int( i32 0 )
- to label %invcont4133 unwind label %unwind3880 ; <i32> [#uses=1]
-
-invcont4133: ; preds = %invcont4122
- %tmp4130 = icmp sgt i64 %tmp4129, -1 ; <i1> [#uses=1]
- %tmp4129.cast = trunc i64 %tmp4129 to i32 ; <i32> [#uses=1]
- %max41314132 = select i1 %tmp4130, i32 %tmp4129.cast, i32 0 ; <i32> [#uses=1]
- %tmp4135 = icmp eq i32 %max41314132, %tmp4134 ; <i1> [#uses=1]
- br i1 %tmp4135, label %finally4147, label %cond_true4138
-
-cond_true4138: ; preds = %invcont4133
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([31 x i8]* @.str27 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.98.1466 to i32) to i64), i64 32)) )
- to label %finally4147 unwind label %unwind3880
-
-eh_then4152: ; preds = %unwind3880
- invoke void @__gnat_begin_handler( i8* %eh_ptr3881 )
- to label %invcont4158 unwind label %unwind4156
-
-unwind4156: ; preds = %invcont4160, %invcont4158, %eh_then4152
- %eh_ptr4157 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr3881 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr4157 ) ; <i32>:18 [#uses=0]
- unreachable
-
-invcont4158: ; preds = %eh_then4152
- %tmp4159 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp4159( )
- to label %invcont4160 unwind label %unwind4156
-
-invcont4160: ; preds = %invcont4158
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([18 x i8]* @.str28 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.124.1606 to i32) to i64), i64 32)) )
- to label %cleanup4169 unwind label %unwind4156
-
-cleanup4169: ; preds = %invcont4160
- call void @__gnat_end_handler( i8* %eh_ptr3881 )
- br label %finally4147
-
-finally4147: ; preds = %cleanup4169, %cond_true4138, %invcont4133
- %tmp4174 = call i8* @llvm.stacksave( ) ; <i8*> [#uses=3]
- %tmp4180 = invoke i32 @report__ident_int( i32 4 )
- to label %invcont4179 unwind label %unwind4175 ; <i32> [#uses=6]
-
-unwind4175: ; preds = %cond_true4292, %cond_true4187, %finally4147
- %eh_ptr4176 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=5]
- %eh_select4178 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr4176, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=1]
- %eh_typeid4304 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp4306 = icmp eq i32 %eh_select4178, %eh_typeid4304 ; <i1> [#uses=1]
- br i1 %tmp4306, label %eh_then4307, label %cleanup4334
-
-invcont4179: ; preds = %finally4147
- %tmp4184 = icmp slt i32 %tmp4180, 1 ; <i1> [#uses=1]
- br i1 %tmp4184, label %cond_true4187, label %cond_next4189
-
-cond_true4187: ; preds = %invcont4179
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 329 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind4175
-
-cond_next4189: ; preds = %invcont4179
- %tmp4231 = icmp sgt i32 %tmp4180, 2 ; <i1> [#uses=2]
- %tmp4238 = add i32 %tmp4180, 1073741823 ; <i32> [#uses=1]
- %iftmp.138.0 = select i1 %tmp4231, i32 %tmp4238, i32 2 ; <i32> [#uses=1]
- %tmp4245 = sub i32 %iftmp.138.0, %tmp4180 ; <i32> [#uses=1]
- %tmp4246 = shl i32 %tmp4245, 2 ; <i32> [#uses=2]
- %tmp4247 = add i32 %tmp4246, 4 ; <i32> [#uses=1]
- %tmp4248 = icmp sgt i32 %tmp4247, -1 ; <i1> [#uses=1]
- %tmp4247.op = add i32 %tmp4246, 7 ; <i32> [#uses=1]
- %tmp4247.op.op = and i32 %tmp4247.op, -4 ; <i32> [#uses=1]
- %tmp4251 = select i1 %tmp4248, i32 %tmp4247.op.op, i32 0 ; <i32> [#uses=1]
- %tmp4253 = alloca i8, i32 %tmp4251 ; <i8*> [#uses=2]
- %tmp42534254 = bitcast i8* %tmp4253 to i32* ; <i32*> [#uses=1]
- br i1 %tmp4231, label %bb4276, label %cond_next4266.preheader
-
-cond_next4266.preheader: ; preds = %cond_next4189
- %J152b.36147.3 = add i32 %tmp4180, 1 ; <i32> [#uses=1]
- br label %cond_next4266
-
-cond_next4266: ; preds = %cond_next4266, %cond_next4266.preheader
- %indvar6268 = phi i32 [ 0, %cond_next4266.preheader ], [ %indvar.next22, %cond_next4266 ] ; <i32> [#uses=3]
- %tmp4273 = getelementptr i32* %tmp42534254, i32 %indvar6268 ; <i32*> [#uses=1]
- store i32 5, i32* %tmp4273
- %tmp4275 = add i32 %J152b.36147.3, %indvar6268 ; <i32> [#uses=1]
- %tmp42626151 = icmp sgt i32 %tmp4275, 2 ; <i1> [#uses=1]
- %indvar.next22 = add i32 %indvar6268, 1 ; <i32> [#uses=1]
- br i1 %tmp42626151, label %bb4276, label %cond_next4266
-
-bb4276: ; preds = %cond_next4266, %cond_next4189
- %tmp4280 = sub i32 2, %tmp4180 ; <i32> [#uses=1]
- %tmp4281 = icmp eq i32 %tmp4280, 1 ; <i1> [#uses=1]
- br i1 %tmp4281, label %cond_true4284, label %cleanup4336
-
-cond_true4284: ; preds = %bb4276
- %tmp4288 = call i32 (i8*, i8*, i32, ...)* @memcmp( i8* %tmp4253, i8* bitcast ([2 x i32]* @C.143.1720 to i8*), i32 8 ) ; <i32> [#uses=1]
- %tmp4289 = icmp eq i32 %tmp4288, 0 ; <i1> [#uses=1]
- br i1 %tmp4289, label %cond_true4292, label %cleanup4336
-
-cond_true4292: ; preds = %cond_true4284
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([37 x i8]* @.str29 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.146.1725 to i32) to i64), i64 32)) )
- to label %cleanup4336 unwind label %unwind4175
-
-eh_then4307: ; preds = %unwind4175
- invoke void @__gnat_begin_handler( i8* %eh_ptr4176 )
- to label %invcont4313 unwind label %unwind4311
-
-unwind4311: ; preds = %invcont4315, %invcont4313, %eh_then4307
- %eh_ptr4312 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_ptr4176 )
- to label %cleanup4334 unwind label %unwind4326
-
-invcont4313: ; preds = %eh_then4307
- %tmp4314 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp4314( )
- to label %invcont4315 unwind label %unwind4311
-
-invcont4315: ; preds = %invcont4313
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([18 x i8]* @.str30 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.124.1606 to i32) to i64), i64 32)) )
- to label %cleanup4324 unwind label %unwind4311
-
-cleanup4324: ; preds = %invcont4315
- invoke void @__gnat_end_handler( i8* %eh_ptr4176 )
- to label %cleanup4336 unwind label %unwind4326
-
-unwind4326: ; preds = %cleanup4324, %unwind4311
- %eh_ptr4327 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @llvm.stackrestore( i8* %tmp4174 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr4327 ) ; <i32>:19 [#uses=0]
- unreachable
-
-cleanup4334: ; preds = %unwind4311, %unwind4175
- %eh_exception.50 = phi i8* [ %eh_ptr4176, %unwind4175 ], [ %eh_ptr4312, %unwind4311 ] ; <i8*> [#uses=1]
- call void @llvm.stackrestore( i8* %tmp4174 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_exception.50 ) ; <i32>:20 [#uses=0]
- unreachable
-
-cleanup4336: ; preds = %cleanup4324, %cond_true4292, %cond_true4284, %bb4276
- call void @llvm.stackrestore( i8* %tmp4174 )
- %tmp4338 = call i8* @llvm.stacksave( ) ; <i8*> [#uses=6]
- %tmp4379 = alloca i8, i32 %max1395 ; <i8*> [#uses=9]
- %tmp4421 = alloca i8, i32 %max1395 ; <i8*> [#uses=3]
- %tmp4428 = icmp ugt i8 %tmp204205, %tmp272273 ; <i1> [#uses=1]
- br i1 %tmp4428, label %cond_next4458, label %bb4433
-
-bb4433: ; preds = %cleanup4336
- store i8 %wed.4, i8* %tmp4421
- %tmp4442 = icmp eq i8 %tmp272273, %tmp204205 ; <i1> [#uses=1]
- br i1 %tmp4442, label %cond_next4458, label %cond_next4446.preheader
-
-cond_next4446.preheader: ; preds = %bb4433
- %J161b.26152.2 = add i8 %tmp204205, 1 ; <i8> [#uses=1]
- br label %cond_next4446
-
-cond_next4446: ; preds = %cond_next4446, %cond_next4446.preheader
- %indvar6271 = phi i8 [ 0, %cond_next4446.preheader ], [ %indvar.next24, %cond_next4446 ] ; <i8> [#uses=2]
- %tmp4448 = add i8 %J161b.26152.2, %indvar6271 ; <i8> [#uses=2]
- %tmp443444356156 = zext i8 %tmp4448 to i32 ; <i32> [#uses=1]
- %tmp44376157 = sub i32 %tmp443444356156, %tmp13571358 ; <i32> [#uses=1]
- %tmp44386158 = getelementptr i8* %tmp4421, i32 %tmp44376157 ; <i8*> [#uses=1]
- store i8 %wed.4, i8* %tmp44386158
- %tmp44426160 = icmp eq i8 %tmp272273, %tmp4448 ; <i1> [#uses=1]
- %indvar.next24 = add i8 %indvar6271, 1 ; <i8> [#uses=1]
- br i1 %tmp44426160, label %cond_next4458, label %cond_next4446
-
-unwind4453: ; preds = %cond_true4609, %cond_true4504, %cond_true4481
- %eh_ptr4454 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=4]
- %eh_select4456 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr4454, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=1]
- %eh_typeid4710 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp4712 = icmp eq i32 %eh_select4456, %eh_typeid4710 ; <i1> [#uses=1]
- br i1 %tmp4712, label %eh_then4713, label %cleanup4740
-
-cond_next4458: ; preds = %cond_next4446, %bb4433, %cleanup4336
- call void @llvm.memcpy.i32( i8* %tmp4379, i8* %tmp4421, i32 %max1395, i32 1 )
- %tmp4464 = icmp ult i8 %tmp137138, %mon.4 ; <i1> [#uses=2]
- br i1 %tmp4464, label %cond_next4484, label %cond_true4467
-
-cond_true4467: ; preds = %cond_next4458
- %tmp4470 = icmp ult i8 %mon.4, %tmp204205 ; <i1> [#uses=1]
- %tmp4474 = icmp ugt i8 %tmp137138, %tmp272273 ; <i1> [#uses=1]
- %tmp4478 = or i1 %tmp4470, %tmp4474 ; <i1> [#uses=1]
- br i1 %tmp4478, label %cond_true4481, label %cond_next4484
-
-cond_true4481: ; preds = %cond_true4467
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 340 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind4453
-
-cond_next4484: ; preds = %cond_true4467, %cond_next4458
- %tmp4487 = icmp ult i8 %mon.4, %tue.4 ; <i1> [#uses=2]
- br i1 %tmp4487, label %cond_next4507, label %cond_true4490
-
-cond_true4490: ; preds = %cond_next4484
- %tmp4493 = icmp ult i8 %tue.4, %tmp204205 ; <i1> [#uses=1]
- %tmp4497 = icmp ugt i8 %mon.4, %tmp272273 ; <i1> [#uses=1]
- %tmp4501 = or i1 %tmp4497, %tmp4493 ; <i1> [#uses=1]
- br i1 %tmp4501, label %cond_true4504, label %cond_next4507
-
-cond_true4504: ; preds = %cond_true4490
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 340 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind4453
-
-cond_next4507: ; preds = %cond_true4490, %cond_next4484
- %tmp45904591 = zext i8 %mon.4 to i64 ; <i64> [#uses=3]
- %tmp45924593 = zext i8 %tue.4 to i64 ; <i64> [#uses=1]
- %tmp4594 = sub i64 %tmp45904591, %tmp45924593 ; <i64> [#uses=1]
- %tmp4595 = add i64 %tmp4594, 1 ; <i64> [#uses=2]
- %tmp4596 = icmp sgt i64 %tmp4595, -1 ; <i1> [#uses=1]
- %max4597 = select i1 %tmp4596, i64 %tmp4595, i64 0 ; <i64> [#uses=1]
- %tmp45984599 = zext i8 %tmp137138 to i64 ; <i64> [#uses=1]
- %tmp4602 = sub i64 %tmp45984599, %tmp45904591 ; <i64> [#uses=1]
- %tmp4603 = add i64 %tmp4602, 1 ; <i64> [#uses=3]
- %tmp4604 = icmp sgt i64 %tmp4603, -1 ; <i1> [#uses=2]
- %max4605 = select i1 %tmp4604, i64 %tmp4603, i64 0 ; <i64> [#uses=1]
- %tmp4606 = icmp eq i64 %max4597, %max4605 ; <i1> [#uses=1]
- br i1 %tmp4606, label %cond_next4611, label %cond_true4609
-
-cond_true4609: ; preds = %cond_next4507
- invoke void @__gnat_rcheck_07( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 340 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind4453
-
-cond_next4611: ; preds = %cond_next4507
- %tmp46124613 = zext i8 %tue.4 to i32 ; <i32> [#uses=1]
- %tmp4616 = sub i32 %tmp46124613, %tmp13571358 ; <i32> [#uses=2]
- %tmp46244625 = zext i8 %mon.4 to i32 ; <i32> [#uses=1]
- %tmp4628 = sub i32 %tmp46244625, %tmp13571358 ; <i32> [#uses=3]
- %tmp4636 = icmp slt i32 %tmp4628, %tmp4616 ; <i1> [#uses=1]
- %tmp4677 = icmp ugt i8 %tue.4, %mon.4 ; <i1> [#uses=2]
- br i1 %tmp4636, label %cond_false4673, label %cond_true4639
-
-cond_true4639: ; preds = %cond_next4611
- br i1 %tmp4677, label %cleanup4742, label %bb4648.preheader
-
-bb4648.preheader: ; preds = %cond_true4639
- %tmp46556217 = getelementptr i8* %tmp4379, i32 %tmp4628 ; <i8*> [#uses=1]
- %tmp46566218 = load i8* %tmp46556217 ; <i8> [#uses=1]
- %tmp46596220 = getelementptr i8* %tmp4379, i32 %tmp4616 ; <i8*> [#uses=1]
- store i8 %tmp46566218, i8* %tmp46596220
- %tmp46646223 = icmp eq i8 %tue.4, %mon.4 ; <i1> [#uses=1]
- br i1 %tmp46646223, label %cleanup4742, label %cond_next4668.preheader
-
-cond_next4668.preheader: ; preds = %bb4648.preheader
- %tmp46616222.in = add i8 %mon.4, 1 ; <i8> [#uses=1]
- %L174b.26213 = add i8 %tue.4, 1 ; <i8> [#uses=1]
- %tmp.27 = sub i8 %mon.4, %tue.4 ; <i8> [#uses=1]
- br label %cond_next4668
-
-cond_next4668: ; preds = %cond_next4668, %cond_next4668.preheader
- %indvar6275 = phi i8 [ 0, %cond_next4668.preheader ], [ %indvar.next26, %cond_next4668 ] ; <i8> [#uses=3]
- %tmp46616222 = add i8 %tmp46616222.in, %indvar6275 ; <i8> [#uses=1]
- %tmp4670 = add i8 %L174b.26213, %indvar6275 ; <i8> [#uses=1]
- %tmp46494650 = zext i8 %tmp4670 to i32 ; <i32> [#uses=1]
- %tmp46514652 = zext i8 %tmp46616222 to i32 ; <i32> [#uses=1]
- %tmp4654 = sub i32 %tmp46514652, %tmp13571358 ; <i32> [#uses=1]
- %tmp4655 = getelementptr i8* %tmp4379, i32 %tmp4654 ; <i8*> [#uses=1]
- %tmp4656 = load i8* %tmp4655 ; <i8> [#uses=1]
- %tmp4658 = sub i32 %tmp46494650, %tmp13571358 ; <i32> [#uses=1]
- %tmp4659 = getelementptr i8* %tmp4379, i32 %tmp4658 ; <i8*> [#uses=1]
- store i8 %tmp4656, i8* %tmp4659
- %indvar.next26 = add i8 %indvar6275, 1 ; <i8> [#uses=2]
- %exitcond28 = icmp eq i8 %indvar.next26, %tmp.27 ; <i1> [#uses=1]
- br i1 %exitcond28, label %cleanup4742, label %cond_next4668
-
-cond_false4673: ; preds = %cond_next4611
- br i1 %tmp4677, label %cleanup4742, label %bb4682.preheader
-
-bb4682.preheader: ; preds = %cond_false4673
- %tmp468546866228 = and i32 %tmp123, 255 ; <i32> [#uses=1]
- %tmp46886229 = sub i32 %tmp468546866228, %tmp13571358 ; <i32> [#uses=1]
- %tmp46896230 = getelementptr i8* %tmp4379, i32 %tmp46886229 ; <i8*> [#uses=1]
- %tmp46906231 = load i8* %tmp46896230 ; <i8> [#uses=1]
- %tmp46936233 = getelementptr i8* %tmp4379, i32 %tmp4628 ; <i8*> [#uses=1]
- store i8 %tmp46906231, i8* %tmp46936233
- %tmp46986236 = icmp eq i8 %mon.4, %tue.4 ; <i1> [#uses=1]
- br i1 %tmp46986236, label %cleanup4742, label %cond_next4702.preheader
-
-cond_next4702.preheader: ; preds = %bb4682.preheader
- %tmp46956235.in = add i8 %tmp137138, -1 ; <i8> [#uses=1]
- %L172b.26226 = add i8 %mon.4, -1 ; <i8> [#uses=1]
- %tmp.32 = sub i8 %mon.4, %tue.4 ; <i8> [#uses=1]
- br label %cond_next4702
-
-cond_next4702: ; preds = %cond_next4702, %cond_next4702.preheader
- %indvar6278 = phi i8 [ 0, %cond_next4702.preheader ], [ %indvar.next30, %cond_next4702 ] ; <i8> [#uses=3]
- %tmp46956235 = sub i8 %tmp46956235.in, %indvar6278 ; <i8> [#uses=1]
- %tmp4704 = sub i8 %L172b.26226, %indvar6278 ; <i8> [#uses=1]
- %tmp46834684 = zext i8 %tmp4704 to i32 ; <i32> [#uses=1]
- %tmp46854686 = zext i8 %tmp46956235 to i32 ; <i32> [#uses=1]
- %tmp4688 = sub i32 %tmp46854686, %tmp13571358 ; <i32> [#uses=1]
- %tmp4689 = getelementptr i8* %tmp4379, i32 %tmp4688 ; <i8*> [#uses=1]
- %tmp4690 = load i8* %tmp4689 ; <i8> [#uses=1]
- %tmp4692 = sub i32 %tmp46834684, %tmp13571358 ; <i32> [#uses=1]
- %tmp4693 = getelementptr i8* %tmp4379, i32 %tmp4692 ; <i8*> [#uses=1]
- store i8 %tmp4690, i8* %tmp4693
- %indvar.next30 = add i8 %indvar6278, 1 ; <i8> [#uses=2]
- %exitcond33 = icmp eq i8 %indvar.next30, %tmp.32 ; <i1> [#uses=1]
- br i1 %exitcond33, label %cleanup4742, label %cond_next4702
-
-eh_then4713: ; preds = %unwind4453
- invoke void @__gnat_begin_handler( i8* %eh_ptr4454 )
- to label %invcont4719 unwind label %unwind4717
-
-unwind4717: ; preds = %invcont4719, %eh_then4713
- %eh_ptr4718 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- invoke void @__gnat_end_handler( i8* %eh_ptr4454 )
- to label %cleanup4740 unwind label %unwind4732
-
-invcont4719: ; preds = %eh_then4713
- %tmp4720 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp4720( )
- to label %UnifiedReturnBlock35 unwind label %unwind4717
-
-unwind4732: ; preds = %unwind4717
- %eh_ptr4733 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @llvm.stackrestore( i8* %tmp4338 )
- call void @llvm.stackrestore( i8* %tmp4338 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr4733 ) ; <i32>:21 [#uses=0]
- unreachable
-
-cleanup4740: ; preds = %unwind4717, %unwind4453
- %eh_exception.53 = phi i8* [ %eh_ptr4454, %unwind4453 ], [ %eh_ptr4718, %unwind4717 ] ; <i8*> [#uses=1]
- call void @llvm.stackrestore( i8* %tmp4338 )
- call void @llvm.stackrestore( i8* %tmp4338 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_exception.53 ) ; <i32>:22 [#uses=0]
- unreachable
-
-cleanup4742: ; preds = %cond_next4702, %bb4682.preheader, %cond_false4673, %cond_next4668, %bb4648.preheader, %cond_true4639
- call void @llvm.stackrestore( i8* %tmp4338 )
- call void @llvm.stackrestore( i8* %tmp4338 )
- %tmp4749 = call i8* @llvm.stacksave( ) ; <i8*> [#uses=2]
- br i1 %tmp4464, label %cond_next4776, label %UnifiedReturnBlock35
-
-unwind4770: ; preds = %cond_next4776
- %eh_ptr4771 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=5]
- %eh_select4773 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr4771, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=1]
- call void @llvm.stackrestore( i8* %tmp4749 )
- %eh_typeid4874 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp4876 = icmp eq i32 %eh_select4773, %eh_typeid4874 ; <i1> [#uses=1]
- br i1 %tmp4876, label %eh_then4877, label %Unwind
-
-cond_next4776: ; preds = %cleanup4742
- %tmp4856.cast = trunc i64 %tmp4603 to i32 ; <i32> [#uses=1]
- %max48584859 = select i1 %tmp4604, i32 %tmp4856.cast, i32 0 ; <i32> [#uses=1]
- %tmp4861 = invoke i8 @report__equal( i32 %max48584859, i32 0 )
- to label %invcont4860 unwind label %unwind4770 ; <i8> [#uses=1]
-
-invcont4860: ; preds = %cond_next4776
- %tmp4862 = icmp eq i8 %tmp4861, 0 ; <i1> [#uses=1]
- %tue.8 = select i1 %tmp4862, i8 %tue.4, i8 2 ; <i8> [#uses=3]
- call void @llvm.stackrestore( i8* %tmp4749 )
- %tmp49016170 = icmp ult i8 %mon.4, %tue.8 ; <i1> [#uses=1]
- br i1 %tmp49016170, label %cond_next4925, label %cond_true4904
-
-eh_then4877: ; preds = %unwind4770
- invoke void @__gnat_begin_handler( i8* %eh_ptr4771 )
- to label %invcont4883 unwind label %unwind4881
-
-unwind4881: ; preds = %invcont4885, %invcont4883, %eh_then4877
- %eh_ptr4882 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr4771 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr4882 ) ; <i32>:23 [#uses=0]
- unreachable
-
-invcont4883: ; preds = %eh_then4877
- %tmp4884 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp4884( )
- to label %invcont4885 unwind label %unwind4881
-
-invcont4885: ; preds = %invcont4883
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([18 x i8]* @.str32 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.124.1606 to i32) to i64), i64 32)) )
- to label %cleanup4894 unwind label %unwind4881
-
-cleanup4894: ; preds = %invcont4885
- call void @__gnat_end_handler( i8* %eh_ptr4771 )
- br i1 %tmp4487, label %cond_next4925, label %cond_true4904
-
-cond_true4904: ; preds = %cleanup4894, %invcont4860
- %tue.96161.0 = phi i8 [ %tue.8, %invcont4860 ], [ %tue.4, %cleanup4894 ] ; <i8> [#uses=3]
- %tmp4907 = icmp ult i8 %tue.96161.0, %tmp204205 ; <i1> [#uses=1]
- %tmp4911 = icmp ugt i8 %mon.4, %tmp272273 ; <i1> [#uses=1]
- %tmp4915 = or i1 %tmp4907, %tmp4911 ; <i1> [#uses=1]
- br i1 %tmp4915, label %cond_true4918, label %cond_next4925
-
-cond_true4918: ; preds = %cond_true4904
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 361 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind4919
-
-unwind4919: ; preds = %cond_next4925, %cond_true4918
- %tue.96161.2 = phi i8 [ %tue.96161.0, %cond_true4918 ], [ %tue.96161.1, %cond_next4925 ] ; <i8> [#uses=1]
- %eh_ptr4920 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=5]
- %eh_select4922 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr4920, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=1]
- %eh_typeid4987 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp4989 = icmp eq i32 %eh_select4922, %eh_typeid4987 ; <i1> [#uses=1]
- br i1 %tmp4989, label %eh_then4990, label %Unwind
-
-cond_next4925: ; preds = %cond_true4904, %cleanup4894, %invcont4860
- %tue.96161.1 = phi i8 [ %tue.8, %invcont4860 ], [ %tue.4, %cleanup4894 ], [ %tue.96161.0, %cond_true4904 ] ; <i8> [#uses=6]
- %tmp49714972 = zext i8 %tue.96161.1 to i64 ; <i64> [#uses=1]
- %tmp4973 = sub i64 %tmp45904591, %tmp49714972 ; <i64> [#uses=1]
- %tmp4974 = add i64 %tmp4973, 1 ; <i64> [#uses=2]
- %tmp4975 = icmp sgt i64 %tmp4974, -1 ; <i1> [#uses=1]
- %tmp4974.cast = trunc i64 %tmp4974 to i32 ; <i32> [#uses=1]
- %max49764977 = select i1 %tmp4975, i32 %tmp4974.cast, i32 0 ; <i32> [#uses=1]
- %tmp4979 = invoke i8 @report__equal( i32 %max49764977, i32 0 )
- to label %invcont4978 unwind label %unwind4919 ; <i8> [#uses=1]
-
-invcont4978: ; preds = %cond_next4925
- %tmp4980 = icmp eq i8 %tmp4979, 0 ; <i1> [#uses=1]
- br i1 %tmp4980, label %finally4985, label %cond_true4983
-
-cond_true4983: ; preds = %invcont4978
- %tmp50146178 = icmp ugt i8 %tue.96161.1, 1 ; <i1> [#uses=1]
- br i1 %tmp50146178, label %cond_next5038, label %cond_true5017
-
-eh_then4990: ; preds = %unwind4919
- invoke void @__gnat_begin_handler( i8* %eh_ptr4920 )
- to label %invcont4996 unwind label %unwind4994
-
-unwind4994: ; preds = %invcont4998, %invcont4996, %eh_then4990
- %eh_ptr4995 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr4920 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr4995 ) ; <i32>:24 [#uses=0]
- unreachable
-
-invcont4996: ; preds = %eh_then4990
- %tmp4997 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp4997( )
- to label %invcont4998 unwind label %unwind4994
-
-invcont4998: ; preds = %invcont4996
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([19 x i8]* @.str33 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.170.1990 to i32) to i64), i64 32)) )
- to label %cleanup5007 unwind label %unwind4994
-
-cleanup5007: ; preds = %invcont4998
- call void @__gnat_end_handler( i8* %eh_ptr4920 )
- br label %finally4985
-
-finally4985: ; preds = %cleanup5007, %invcont4978
- %tue.96161.3 = phi i8 [ %tue.96161.2, %cleanup5007 ], [ %tue.96161.1, %invcont4978 ] ; <i8> [#uses=3]
- %tmp5014 = icmp ult i8 %mon.4, %tue.96161.3 ; <i1> [#uses=1]
- br i1 %tmp5014, label %cond_next5038, label %cond_true5017
-
-cond_true5017: ; preds = %finally4985, %cond_true4983
- %tue.96161.4 = phi i8 [ %tue.96161.1, %cond_true4983 ], [ %tue.96161.3, %finally4985 ] ; <i8> [#uses=3]
- %mon.86171.0 = phi i8 [ 1, %cond_true4983 ], [ %mon.4, %finally4985 ] ; <i8> [#uses=3]
- %tmp5020 = icmp ult i8 %tue.96161.4, %tmp204205 ; <i1> [#uses=1]
- %tmp5024 = icmp ugt i8 %mon.86171.0, %tmp272273 ; <i1> [#uses=1]
- %tmp5028 = or i1 %tmp5024, %tmp5020 ; <i1> [#uses=1]
- br i1 %tmp5028, label %cond_true5031, label %cond_next5038
-
-cond_true5031: ; preds = %cond_true5017
- invoke void @__gnat_rcheck_12( i8* getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 375 )
- to label %UnifiedUnreachableBlock34 unwind label %unwind5032
-
-unwind5032: ; preds = %cond_next5038, %cond_true5031
- %tue.96161.6 = phi i8 [ %tue.96161.4, %cond_true5031 ], [ %tue.96161.5, %cond_next5038 ] ; <i8> [#uses=1]
- %mon.86171.2 = phi i8 [ %mon.86171.0, %cond_true5031 ], [ %mon.86171.1, %cond_next5038 ] ; <i8> [#uses=1]
- %eh_ptr5033 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=5]
- %eh_select5035 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr5033, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=1]
- %eh_typeid5100 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp5102 = icmp eq i32 %eh_select5035, %eh_typeid5100 ; <i1> [#uses=1]
- br i1 %tmp5102, label %eh_then5103, label %Unwind
-
-cond_next5038: ; preds = %cond_true5017, %finally4985, %cond_true4983
- %tue.96161.5 = phi i8 [ %tue.96161.1, %cond_true4983 ], [ %tue.96161.3, %finally4985 ], [ %tue.96161.4, %cond_true5017 ] ; <i8> [#uses=4]
- %mon.86171.1 = phi i8 [ 1, %cond_true4983 ], [ %mon.4, %finally4985 ], [ %mon.86171.0, %cond_true5017 ] ; <i8> [#uses=4]
- %tmp50825083 = zext i8 %mon.86171.1 to i64 ; <i64> [#uses=1]
- %tmp50845085 = zext i8 %tue.96161.5 to i64 ; <i64> [#uses=1]
- %tmp5086 = sub i64 %tmp50825083, %tmp50845085 ; <i64> [#uses=1]
- %tmp5087 = add i64 %tmp5086, 1 ; <i64> [#uses=2]
- %tmp5088 = icmp sgt i64 %tmp5087, -1 ; <i1> [#uses=1]
- %tmp5087.cast = trunc i64 %tmp5087 to i32 ; <i32> [#uses=1]
- %max50895090 = select i1 %tmp5088, i32 %tmp5087.cast, i32 0 ; <i32> [#uses=1]
- %tmp5092 = invoke i8 @report__equal( i32 %max50895090, i32 0 )
- to label %invcont5091 unwind label %unwind5032 ; <i8> [#uses=1]
-
-invcont5091: ; preds = %cond_next5038
- %tmp5093 = icmp eq i8 %tmp5092, 0 ; <i1> [#uses=1]
- br i1 %tmp5093, label %finally5098, label %cond_true5096
-
-cond_true5096: ; preds = %invcont5091
- br label %finally5098
-
-eh_then5103: ; preds = %unwind5032
- invoke void @__gnat_begin_handler( i8* %eh_ptr5033 )
- to label %invcont5109 unwind label %unwind5107
-
-unwind5107: ; preds = %invcont5111, %invcont5109, %eh_then5103
- %eh_ptr5108 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr5033 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr5108 ) ; <i32>:25 [#uses=0]
- unreachable
-
-invcont5109: ; preds = %eh_then5103
- %tmp5110 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp5110( )
- to label %invcont5111 unwind label %unwind5107
-
-invcont5111: ; preds = %invcont5109
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([19 x i8]* @.str34 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.170.1990 to i32) to i64), i64 32)) )
- to label %cleanup5120 unwind label %unwind5107
-
-cleanup5120: ; preds = %invcont5111
- call void @__gnat_end_handler( i8* %eh_ptr5033 )
- br label %finally5098
-
-finally5098: ; preds = %cleanup5120, %cond_true5096, %invcont5091
- %tue.96161.7 = phi i8 [ %tue.96161.6, %cleanup5120 ], [ %tue.96161.5, %cond_true5096 ], [ %tue.96161.5, %invcont5091 ] ; <i8> [#uses=1]
- %mon.86171.3 = phi i8 [ %mon.86171.2, %cleanup5120 ], [ %mon.86171.1, %cond_true5096 ], [ %mon.86171.1, %invcont5091 ] ; <i8> [#uses=2]
- %wed.6 = phi i8 [ %wed.4, %cleanup5120 ], [ 3, %cond_true5096 ], [ %wed.4, %invcont5091 ] ; <i8> [#uses=5]
- %not.tmp5135 = icmp uge i8 %tmp137138, %sat.45934.0 ; <i1> [#uses=1]
- %tmp5151 = icmp uge i8 %sat.45934.0, %tmp306307 ; <i1> [#uses=1]
- %tmp5155 = icmp ule i8 %sat.45934.0, %wed.6 ; <i1> [#uses=1]
- %tmp5159 = and i1 %tmp5155, %tmp5151 ; <i1> [#uses=1]
- %tmp5177 = icmp ult i8 %wed.6, %tmp272273 ; <i1> [#uses=1]
- %tmp5184 = icmp ugt i8 %wed.6, %tue.96161.7 ; <i1> [#uses=1]
- %bothcond5907 = or i1 %tmp5177, %tmp5184 ; <i1> [#uses=2]
- %not.bothcond5907 = xor i1 %bothcond5907, true ; <i1> [#uses=1]
- %tmp5198 = icmp uge i8 %tmp272273, %mon.86171.3 ; <i1> [#uses=1]
- %tmp5202 = icmp ule i8 %tmp272273, %tmp137138 ; <i1> [#uses=1]
- %tmp5206 = and i1 %tmp5198, %tmp5202 ; <i1> [#uses=1]
- %not.bothcond5908 = icmp uge i8 %tmp306307, %sat.45934.0 ; <i1> [#uses=1]
- %tmp5244 = icmp uge i8 %wed.6, %tmp306307 ; <i1> [#uses=1]
- %tmp5248 = icmp ule i8 %wed.6, %mon.86171.3 ; <i1> [#uses=1]
- %tmp5252 = and i1 %tmp5244, %tmp5248 ; <i1> [#uses=1]
- %tmp5164 = or i1 %not.tmp5135, %not.bothcond5908 ; <i1> [#uses=1]
- %tmp5194 = or i1 %tmp5164, %tmp5206 ; <i1> [#uses=1]
- %tmp5210 = or i1 %tmp5194, %tmp5159 ; <i1> [#uses=1]
- %tmp5240 = or i1 %tmp5210, %not.bothcond5907 ; <i1> [#uses=1]
- %tmp5256 = or i1 %tmp5240, %tmp5252 ; <i1> [#uses=1]
- br i1 %tmp5256, label %cond_true5259, label %cond_next5271
-
-cond_true5259: ; preds = %finally5098
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([27 x i8]* @.str35 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.178.2066 to i32) to i64), i64 32)) )
- to label %cond_next5271 unwind label %unwind5266
-
-unwind5266: ; preds = %cond_true5462, %invcont5429, %cond_next5401, %cond_true5393, %cond_next5374, %bb5359, %cond_next5347, %invcont5330, %invcont5305, %invcont5303, %invcont5294, %bb5293, %cond_next5281, %cond_next5271, %cond_true5259
- %eh_ptr5267 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=5]
- %eh_select5269 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32( i8* %eh_ptr5267, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i32* @__gnat_others_value ) ; <i32> [#uses=1]
- %eh_typeid5473 = call i32 @llvm.eh.typeid.for.i32( i8* bitcast (i32* @__gnat_others_value to i8*) ) ; <i32> [#uses=1]
- %tmp5475 = icmp eq i32 %eh_select5269, %eh_typeid5473 ; <i1> [#uses=1]
- br i1 %tmp5475, label %eh_then5476, label %Unwind
-
-cond_next5271: ; preds = %cond_true5259, %finally5098
- %tmp5273 = invoke i32 @report__ident_int( i32 0 )
- to label %invcont5272 unwind label %unwind5266 ; <i32> [#uses=2]
-
-invcont5272: ; preds = %cond_next5271
- %tmp5277 = icmp slt i32 %tmp5273, 10 ; <i1> [#uses=1]
- br i1 %tmp5277, label %bb5292, label %cond_next5281
-
-cond_next5281: ; preds = %invcont5272
- %tmp5283 = invoke i32 @report__ident_int( i32 -10 )
- to label %invcont5282 unwind label %unwind5266 ; <i32> [#uses=1]
-
-invcont5282: ; preds = %cond_next5281
- %tmp5287 = icmp sgt i32 %tmp5273, %tmp5283 ; <i1> [#uses=1]
- br i1 %tmp5287, label %bb5292, label %bb5293
-
-bb5292: ; preds = %invcont5282, %invcont5272
- br label %bb5293
-
-bb5293: ; preds = %bb5292, %invcont5282
- %iftmp.179.0 = phi i1 [ false, %bb5292 ], [ true, %invcont5282 ] ; <i1> [#uses=1]
- %tmp5295 = invoke i32 @report__ident_int( i32 10 )
- to label %invcont5294 unwind label %unwind5266 ; <i32> [#uses=1]
-
-invcont5294: ; preds = %bb5293
- %tmp5296 = icmp slt i32 %tmp5295, 1 ; <i1> [#uses=1]
- %tmp5304 = invoke i32 @report__ident_int( i32 0 )
- to label %invcont5303 unwind label %unwind5266 ; <i32> [#uses=2]
-
-invcont5303: ; preds = %invcont5294
- %tmp5306 = invoke i32 @report__ident_int( i32 -10 )
- to label %invcont5305 unwind label %unwind5266 ; <i32> [#uses=1]
-
-invcont5305: ; preds = %invcont5303
- %tmp5331 = invoke i32 @report__ident_int( i32 -20 )
- to label %invcont5330 unwind label %unwind5266 ; <i32> [#uses=1]
-
-invcont5330: ; preds = %invcont5305
- %tmp5310 = icmp slt i32 %tmp5304, %tmp5306 ; <i1> [#uses=1]
- %tmp5318 = icmp sgt i32 %tmp5304, -11 ; <i1> [#uses=1]
- %bothcond5909 = or i1 %tmp5310, %tmp5318 ; <i1> [#uses=1]
- %not.bothcond5909 = xor i1 %bothcond5909, true ; <i1> [#uses=1]
- %tmp5332 = icmp sgt i32 %tmp5331, -1 ; <i1> [#uses=1]
- %tmp5339 = invoke i32 @report__ident_int( i32 0 )
- to label %invcont5338 unwind label %unwind5266 ; <i32> [#uses=2]
-
-invcont5338: ; preds = %invcont5330
- %tmp5343 = icmp slt i32 %tmp5339, 6 ; <i1> [#uses=1]
- br i1 %tmp5343, label %bb5358, label %cond_next5347
-
-cond_next5347: ; preds = %invcont5338
- %tmp5349 = invoke i32 @report__ident_int( i32 5 )
- to label %invcont5348 unwind label %unwind5266 ; <i32> [#uses=1]
-
-invcont5348: ; preds = %cond_next5347
- %tmp5353 = icmp sgt i32 %tmp5339, %tmp5349 ; <i1> [#uses=1]
- br i1 %tmp5353, label %bb5358, label %bb5359
-
-bb5358: ; preds = %invcont5348, %invcont5338
- br label %bb5359
-
-bb5359: ; preds = %bb5358, %invcont5348
- %iftmp.181.0 = phi i1 [ false, %bb5358 ], [ true, %invcont5348 ] ; <i1> [#uses=1]
- %tmp5366 = invoke i32 @report__ident_int( i32 0 )
- to label %invcont5365 unwind label %unwind5266 ; <i32> [#uses=2]
-
-invcont5365: ; preds = %bb5359
- %tmp5370 = icmp slt i32 %tmp5366, 7 ; <i1> [#uses=1]
- br i1 %tmp5370, label %bb5385, label %cond_next5374
-
-cond_next5374: ; preds = %invcont5365
- %tmp5376 = invoke i32 @report__ident_int( i32 3 )
- to label %invcont5375 unwind label %unwind5266 ; <i32> [#uses=1]
-
-invcont5375: ; preds = %cond_next5374
- %tmp5380 = icmp sgt i32 %tmp5366, %tmp5376 ; <i1> [#uses=1]
- br i1 %tmp5380, label %bb5385, label %bb5386
-
-bb5385: ; preds = %invcont5375, %invcont5365
- br label %bb5386
-
-bb5386: ; preds = %bb5385, %invcont5375
- %iftmp.182.0 = phi i1 [ false, %bb5385 ], [ true, %invcont5375 ] ; <i1> [#uses=1]
- %tmp5301 = or i1 %tmp5296, %iftmp.179.0 ; <i1> [#uses=1]
- %tmp5328 = or i1 %tmp5301, %not.bothcond5909 ; <i1> [#uses=1]
- %tmp5336 = or i1 %tmp5328, %tmp5332 ; <i1> [#uses=1]
- %tmp5363 = or i1 %tmp5336, %iftmp.181.0 ; <i1> [#uses=1]
- %tmp5390 = or i1 %tmp5363, %iftmp.182.0 ; <i1> [#uses=1]
- br i1 %tmp5390, label %cond_true5393, label %cond_next5401
-
-cond_true5393: ; preds = %bb5386
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([27 x i8]* @.str36 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.178.2066 to i32) to i64), i64 32)) )
- to label %cond_next5401 unwind label %unwind5266
-
-cond_next5401: ; preds = %cond_true5393, %bb5386
- %tmp5430 = invoke i32 @report__ident_int( i32 0 )
- to label %invcont5429 unwind label %unwind5266 ; <i32> [#uses=2]
-
-invcont5429: ; preds = %cond_next5401
- %tmp5432 = invoke i32 @report__ident_int( i32 4 )
- to label %invcont5431 unwind label %unwind5266 ; <i32> [#uses=1]
-
-invcont5431: ; preds = %invcont5429
- %tmp5436 = icmp slt i32 %tmp5430, %tmp5432 ; <i1> [#uses=1]
- %tmp5444 = icmp sgt i32 %tmp5430, -4 ; <i1> [#uses=1]
- %bothcond5911 = or i1 %tmp5436, %tmp5444 ; <i1> [#uses=1]
- %tmp5457 = and i1 %bothcond5911, %bothcond5907 ; <i1> [#uses=1]
- br i1 %tmp5457, label %finally5471, label %cond_true5462
-
-cond_true5462: ; preds = %invcont5431
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([29 x i8]* @.str37 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.36.923 to i32) to i64), i64 32)) )
- to label %finally5471 unwind label %unwind5266
-
-eh_then5476: ; preds = %unwind5266
- invoke void @__gnat_begin_handler( i8* %eh_ptr5267 )
- to label %invcont5482 unwind label %unwind5480
-
-unwind5480: ; preds = %invcont5484, %invcont5482, %eh_then5476
- %eh_ptr5481 = call i8* @llvm.eh.exception( ) ; <i8*> [#uses=1]
- call void @__gnat_end_handler( i8* %eh_ptr5267 )
- call i32 (...)* @_Unwind_Resume( i8* %eh_ptr5481 ) ; <i32>:26 [#uses=0]
- unreachable
-
-invcont5482: ; preds = %eh_then5476
- %tmp5483 = load void ()** @system__soft_links__abort_undefer ; <void ()*> [#uses=1]
- invoke void %tmp5483( )
- to label %invcont5484 unwind label %unwind5480
-
-invcont5484: ; preds = %invcont5482
- invoke void @report__failed( i64 or (i64 zext (i32 ptrtoint ([19 x i8]* @.str38 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.string___XUB* @C.170.1990 to i32) to i64), i64 32)) )
- to label %cleanup5493 unwind label %unwind5480
-
-cleanup5493: ; preds = %invcont5484
- call void @__gnat_end_handler( i8* %eh_ptr5267 )
- call void @report__result( )
- ret void
-
-finally5471: ; preds = %cond_true5462, %invcont5431
- call void @report__result( )
- ret void
-
-Unwind: ; preds = %unwind5266, %unwind5032, %unwind4919, %unwind4770, %unwind3880, %unwind3618, %unwind3393, %eh_else3366, %eh_else3016, %eh_else2666, %eh_else1330, %eh_else932, %eh_else823
- %eh_exception.2 = phi i8* [ %eh_exception.05914.1, %eh_else823 ], [ %eh_ptr872, %eh_else932 ], [ %eh_ptr975, %eh_else1330 ], [ %eh_exception.296030.1, %eh_else2666 ], [ %eh_exception.336046.1, %eh_else3016 ], [ %eh_exception.396074.1, %eh_else3366 ], [ %eh_ptr3394, %unwind3393 ], [ %eh_ptr3619, %unwind3618 ], [ %eh_ptr3881, %unwind3880 ], [ %eh_ptr4771, %unwind4770 ], [ %eh_ptr4920, %unwind4919 ], [ %eh_ptr5033, %unwind5032 ], [ %eh_ptr5267, %unwind5266 ] ; <i8*> [#uses=1]
- call i32 (...)* @_Unwind_Resume( i8* %eh_exception.2 ) ; <i32>:27 [#uses=0]
- unreachable
-
-UnifiedUnreachableBlock34: ; preds = %cond_true5031, %cond_true4918, %cond_true4609, %cond_true4504, %cond_true4481, %cond_true4187, %cond_true4117, %cond_true4027, %cond_true3935, %cond_true3907, %cond_true3729, %cond_true3675, %cond_true3617, %cond_true3543, %cond_true3448, %cond_true3420, %bb3227, %bb3193, %bb3171, %cond_true3061, %bb2877, %bb2843, %bb2821, %cond_true2711, %bb2558, %bb2524, %bb2506, %cond_true2410, %bb2203, %cond_true2171, %cond_true1946, %bb1605, %cond_true1573, %cond_true1546, %cond_true1418, %cond_true973, %cond_true870, %cond_true663, %cond_true637, %cond_true611, %cond_true585, %cond_true559, %cond_true533, %cond_true507, %cond_true465
- unreachable
-
-UnifiedReturnBlock35: ; preds = %cleanup4742, %invcont4719, %finally913, %cleanup928
- ret void
-}
-
-declare i32 @report__ident_int(i32)
-
-declare void @__gnat_rcheck_10(i8*, i32)
-
-declare void @__gnat_rcheck_12(i8*, i32)
-
-declare void @report__test(i64, i64)
-
-declare i8* @llvm.eh.exception()
-
-declare i32 @llvm.eh.selector.i32(i8*, i8*, ...)
-
-declare i32 @llvm.eh.typeid.for.i32(i8*)
-
-declare i32 @__gnat_eh_personality(...)
-
-declare i32 @_Unwind_Resume(...)
-
-declare void @system__secondary_stack__ss_mark(%struct.system__secondary_stack__mark_id* sret )
-
-declare void @system__img_int__image_integer(%struct.string___XUP* sret , i32)
-
-declare void @system__string_ops__str_concat(%struct.string___XUP* sret , i64, i64)
-
-declare void @report__failed(i64)
-
-declare void @system__secondary_stack__ss_release(i64)
-
-declare void @__gnat_begin_handler(i8*)
-
-declare void @__gnat_end_handler(i8*)
-
-declare i8 @report__equal(i32, i32)
-
-declare i8* @llvm.stacksave()
-
-declare void @__gnat_rcheck_07(i8*, i32)
-
-declare i8* @__gnat_malloc(i32)
-
-declare void @llvm.stackrestore(i8*)
-
-declare void @llvm.memcpy.i32(i8*, i8*, i32, i32)
-
-declare void @__gnat_rcheck_05(i8*, i32)
-
-declare void @__gnat_rcheck_06(i8*, i32)
-
-declare void @system__img_enum__image_enumeration_8(%struct.string___XUP* sret , i32, i64, i8*)
-
-declare i32 @memcmp(i8*, i8*, i32, ...)
-
-declare void @report__result()
-
-; CHECK: {{Llabel138.*Region start}}
-; CHECK-NEXT: Region length
-; CHECK-NEXT: Landing pad
-; CHECK-NEXT: {{3.*Action}}
diff --git a/test/CodeGen/Generic/addc-fold2.ll b/test/CodeGen/Generic/addc-fold2.ll
deleted file mode 100644
index 34f5ac1..0000000
--- a/test/CodeGen/Generic/addc-fold2.ll
+++ /dev/null
@@ -1,10 +0,0 @@
-; RUN: llc < %s -march=x86 | grep add
-; RUN: llc < %s -march=x86 | not grep adc
-
-define i64 @test(i64 %A, i32 %B) {
- %tmp12 = zext i32 %B to i64 ; <i64> [#uses=1]
- %tmp3 = shl i64 %tmp12, 32 ; <i64> [#uses=1]
- %tmp5 = add i64 %tmp3, %A ; <i64> [#uses=1]
- ret i64 %tmp5
-}
-
diff --git a/test/CodeGen/Generic/fpowi-promote.ll b/test/CodeGen/Generic/fpowi-promote.ll
index 82628ef..8dacebe 100644
--- a/test/CodeGen/Generic/fpowi-promote.ll
+++ b/test/CodeGen/Generic/fpowi-promote.ll
@@ -1,5 +1,4 @@
; RUN: llc < %s
-; RUN: llc < %s -march=x86 -mcpu=i386
; PR1239
diff --git a/test/CodeGen/Generic/switch-lower-feature-2.ll b/test/CodeGen/Generic/switch-lower-feature-2.ll
deleted file mode 100644
index 80e0618..0000000
--- a/test/CodeGen/Generic/switch-lower-feature-2.ll
+++ /dev/null
@@ -1,50 +0,0 @@
-; RUN: llc < %s -march=x86 -o %t
-; RUN: grep jb %t | count 1
-; RUN: grep \\\$6 %t | count 2
-; RUN: grep 1024 %t | count 1
-; RUN: grep 1023 %t | count 1
-; RUN: grep 119 %t | count 1
-; RUN: grep JTI %t | count 2
-; RUN: grep jg %t | count 3
-; RUN: grep ja %t | count 1
-; RUN: grep jns %t | count 1
-
-target triple = "i686-pc-linux-gnu"
-
-define i32 @main(i32 %tmp158) {
-entry:
- switch i32 %tmp158, label %bb336 [
- i32 -2147483648, label %bb338
- i32 -2147483647, label %bb338
- i32 -2147483646, label %bb338
- i32 120, label %bb338
- i32 121, label %bb339
- i32 122, label %bb340
- i32 123, label %bb341
- i32 124, label %bb342
- i32 125, label %bb343
- i32 126, label %bb336
- i32 1024, label %bb338
- i32 0, label %bb338
- i32 1, label %bb338
- i32 2, label %bb338
- i32 3, label %bb338
- i32 4, label %bb338
- i32 5, label %bb338
- ]
-bb336:
- ret i32 10
-bb338:
- ret i32 11
-bb339:
- ret i32 12
-bb340:
- ret i32 13
-bb341:
- ret i32 14
-bb342:
- ret i32 15
-bb343:
- ret i32 18
-
-}
diff --git a/test/CodeGen/Generic/switch-lower-feature.ll b/test/CodeGen/Generic/switch-lower-feature.ll
index 65fdf5a..1e9dbee 100644
--- a/test/CodeGen/Generic/switch-lower-feature.ll
+++ b/test/CodeGen/Generic/switch-lower-feature.ll
@@ -1,10 +1,6 @@
-; RUN: llc < %s -march=x86 -o - | grep {\$7} | count 1
-; RUN: llc < %s -march=x86 -o - | grep {\$6} | count 1
-; RUN: llc < %s -march=x86 -o - | grep 1024 | count 1
-; RUN: llc < %s -march=x86 -o - | grep jb | count 2
-; RUN: llc < %s -march=x86 -o - | grep je | count 1
+; RUN: llc < %s
-define i32 @main(i32 %tmp158) {
+define i32 @test(i32 %tmp158) {
entry:
switch i32 %tmp158, label %bb336 [
i32 120, label %bb338
@@ -27,3 +23,41 @@ bb336:
bb338:
ret i32 11
}
+
+define i32 @test2(i32 %tmp158) {
+entry:
+ switch i32 %tmp158, label %bb336 [
+ i32 -2147483648, label %bb338
+ i32 -2147483647, label %bb338
+ i32 -2147483646, label %bb338
+ i32 120, label %bb338
+ i32 121, label %bb339
+ i32 122, label %bb340
+ i32 123, label %bb341
+ i32 124, label %bb342
+ i32 125, label %bb343
+ i32 126, label %bb336
+ i32 1024, label %bb338
+ i32 0, label %bb338
+ i32 1, label %bb338
+ i32 2, label %bb338
+ i32 3, label %bb338
+ i32 4, label %bb338
+ i32 5, label %bb338
+ ]
+bb336:
+ ret i32 10
+bb338:
+ ret i32 11
+bb339:
+ ret i32 12
+bb340:
+ ret i32 13
+bb341:
+ ret i32 14
+bb342:
+ ret i32 15
+bb343:
+ ret i32 18
+
+}
diff --git a/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll b/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
index c4ed166..d1d28ae 100644
--- a/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
+++ b/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
@@ -1,7 +1,7 @@
; RUN: llc < %s | grep {subfc r3,r5,r4}
; RUN: llc < %s | grep {subfze r4,r2}
-; RUN: llc < %s -regalloc=local | grep {subfc r5,r4,r3}
-; RUN: llc < %s -regalloc=local | grep {subfze r2,r2}
+; RUN: llc < %s -regalloc=local | grep {subfc r2,r5,r4}
+; RUN: llc < %s -regalloc=local | grep {subfze r3,r3}
; The first argument of subfc must not be the same as any other register.
; PR1357
diff --git a/test/CodeGen/PowerPC/2008-01-25-EmptyFunction.ll b/test/CodeGen/PowerPC/2008-01-25-EmptyFunction.ll
index db2ab87..a05245d 100644
--- a/test/CodeGen/PowerPC/2008-01-25-EmptyFunction.ll
+++ b/test/CodeGen/PowerPC/2008-01-25-EmptyFunction.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=ppc32 | grep nop
+; RUN: llc < %s -march=ppc32 | grep .byte
target triple = "powerpc-apple-darwin8"
diff --git a/test/CodeGen/PowerPC/2010-02-04-EmptyGlobal.ll b/test/CodeGen/PowerPC/2010-02-04-EmptyGlobal.ll
new file mode 100644
index 0000000..32ddb34
--- /dev/null
+++ b/test/CodeGen/PowerPC/2010-02-04-EmptyGlobal.ll
@@ -0,0 +1,11 @@
+; RUN: llc < %s -mtriple=powerpc-apple-darwin10 -relocation-model=pic -disable-fp-elim | FileCheck %s
+; <rdar://problem/7604010>
+
+%cmd.type = type { }
+
+@_cmd = constant %cmd.type zeroinitializer
+
+; CHECK: .globl __cmd
+; CHECK-NEXT: .align 3
+; CHECK-NEXT: __cmd:
+; CHECK-NEXT: .space 1
diff --git a/test/CodeGen/PowerPC/2010-02-12-saveCR.ll b/test/CodeGen/PowerPC/2010-02-12-saveCR.ll
new file mode 100644
index 0000000..b73382e
--- /dev/null
+++ b/test/CodeGen/PowerPC/2010-02-12-saveCR.ll
@@ -0,0 +1,30 @@
+; RUN: llc < %s -mtriple=powerpc-apple-darwin | FileCheck %s
+; ModuleID = 'hh.c'
+target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128-n32"
+target triple = "powerpc-apple-darwin9.6"
+; This formerly used R0 for both the stack address and CR.
+
+define void @foo() nounwind {
+entry:
+;CHECK: mfcr r2
+;CHECK: rlwinm r2, r2, 8, 0, 31
+;CHECK: lis r0, 1
+;CHECK: ori r0, r0, 34540
+;CHECK: stwx r2, r1, r0
+ %x = alloca [100000 x i8] ; <[100000 x i8]*> [#uses=1]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ %x1 = bitcast [100000 x i8]* %x to i8* ; <i8*> [#uses=1]
+ call void @bar(i8* %x1) nounwind
+ call void asm sideeffect "", "~{cr2}"() nounwind
+ br label %return
+
+return: ; preds = %entry
+;CHECK: lis r0, 1
+;CHECK: ori r0, r0, 34540
+;CHECK: lwzx r2, r1, r0
+;CHECK: rlwinm r2, r2, 24, 0, 31
+;CHECK: mtcrf 32, r2
+ ret void
+}
+
+declare void @bar(i8*)
diff --git a/test/CodeGen/PowerPC/align.ll b/test/CodeGen/PowerPC/align.ll
index e619faa..109a837 100644
--- a/test/CodeGen/PowerPC/align.ll
+++ b/test/CodeGen/PowerPC/align.ll
@@ -1,11 +1,42 @@
-; RUN: llc < %s -march=ppc32 | \
-; RUN: grep align.4 | count 1
-; RUN: llc < %s -march=ppc32 | \
-; RUN: grep align.2 | count 1
-; RUN: llc < %s -march=ppc32 | \
-; RUN: grep align.3 | count 1
+; RUN: llc < %s -mtriple=powerpc-linux-gnu | FileCheck %s -check-prefix=ELF
+; RUN: llc < %s -mtriple=powerpc-apple-darwin9 | FileCheck %s -check-prefix=DARWIN
-@A = global <4 x i32> < i32 10, i32 20, i32 30, i32 40 > ; <<4 x i32>*> [#uses=0]
-@B = global float 1.000000e+02 ; <float*> [#uses=0]
-@C = global double 2.000000e+03 ; <double*> [#uses=0]
+@a = global i1 true
+; no alignment
+@b = global i8 1
+; no alignment
+
+@c = global i16 2
+;ELF: .align 1
+;ELF: c:
+;DARWIN: .align 1
+;DARWIN: _c:
+
+@d = global i32 3
+;ELF: .align 2
+;ELF: d:
+;DARWIN: .align 2
+;DARWIN: _d:
+
+@e = global i64 4
+;ELF: .align 3
+;ELF: e
+;DARWIN: .align 3
+;DARWIN: _e:
+
+@f = global float 5.0
+;ELF: .align 2
+;ELF: f:
+;DARWIN: .align 2
+;DARWIN: _f:
+
+@g = global double 6.0
+;ELF: .align 3
+;ELF: g:
+;DARWIN: .align 3
+;DARWIN: _g:
+
+@bar = common global [75 x i8] zeroinitializer, align 128
+;ELF: .comm bar,75,128
+;DARWIN: .comm _bar,75,7
diff --git a/test/CodeGen/SPARC/ctpop.ll b/test/CodeGen/SPARC/ctpop.ll
index 37d1c5a..e56f494 100644
--- a/test/CodeGen/SPARC/ctpop.ll
+++ b/test/CodeGen/SPARC/ctpop.ll
@@ -1,7 +1,5 @@
-; RUN: llc < %s -march=sparc -mattr=v9 -enable-sparc-v9-insts
-; RUN: llc < %s -march=sparc -mattr=-v9 | \
-; RUN: not grep popc
-; RUN: llc < %s -march=sparc -mattr=v9 -enable-sparc-v9-insts | grep popc
+; RUN: llc < %s -march=sparc -mattr=-v9 | not grep popc
+; RUN: llc < %s -march=sparcv9 -mattr=v9 | grep popc
declare i32 @llvm.ctpop.i32(i32)
diff --git a/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll b/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll
new file mode 100644
index 0000000..363f571
--- /dev/null
+++ b/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll
@@ -0,0 +1,76 @@
+; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
+
+define arm_apcscc i32 @test(i32 %n) nounwind {
+; CHECK: test:
+; CHECK-NOT: mov
+; CHECK: return
+entry:
+ %0 = icmp eq i32 %n, 1 ; <i1> [#uses=1]
+ br i1 %0, label %return, label %bb.nph
+
+bb.nph: ; preds = %entry
+ %tmp = add i32 %n, -1 ; <i32> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb.nph, %bb
+ %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=1]
+ %u.05 = phi i64 [ undef, %bb.nph ], [ %ins, %bb ] ; <i64> [#uses=1]
+ %1 = tail call arm_apcscc i32 @f() nounwind ; <i32> [#uses=1]
+ %tmp4 = zext i32 %1 to i64 ; <i64> [#uses=1]
+ %mask = and i64 %u.05, -4294967296 ; <i64> [#uses=1]
+ %ins = or i64 %tmp4, %mask ; <i64> [#uses=2]
+ tail call arm_apcscc void @g(i64 %ins) nounwind
+ %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %indvar.next, %tmp ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb, %entry
+ ret i32 undef
+}
+
+define arm_apcscc i32 @test_dead_cycle(i32 %n) nounwind {
+; CHECK: test_dead_cycle:
+; CHECK: blx
+; CHECK-NOT: mov
+; CHECK: blx
+entry:
+ %0 = icmp eq i32 %n, 1 ; <i1> [#uses=1]
+ br i1 %0, label %return, label %bb.nph
+
+bb.nph: ; preds = %entry
+ %tmp = add i32 %n, -1 ; <i32> [#uses=2]
+ br label %bb
+
+bb: ; preds = %bb.nph, %bb2
+ %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb2 ] ; <i32> [#uses=2]
+ %u.17 = phi i64 [ undef, %bb.nph ], [ %u.0, %bb2 ] ; <i64> [#uses=2]
+ %tmp9 = sub i32 %tmp, %indvar ; <i32> [#uses=1]
+ %1 = icmp sgt i32 %tmp9, 1 ; <i1> [#uses=1]
+ br i1 %1, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ %2 = tail call arm_apcscc i32 @f() nounwind ; <i32> [#uses=1]
+ %tmp6 = zext i32 %2 to i64 ; <i64> [#uses=1]
+ %mask = and i64 %u.17, -4294967296 ; <i64> [#uses=1]
+ %ins = or i64 %tmp6, %mask ; <i64> [#uses=1]
+ tail call arm_apcscc void @g(i64 %ins) nounwind
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+; also check for duplicate induction variables (radar 7645034)
+; CHECK: subs r{{.*}}, #1
+; CHECK-NOT: subs r{{.*}}, #1
+; CHECK: pop
+ %u.0 = phi i64 [ %ins, %bb1 ], [ %u.17, %bb ] ; <i64> [#uses=2]
+ %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %indvar.next, %tmp ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb2, %entry
+ ret i32 undef
+}
+
+declare arm_apcscc i32 @f()
+
+declare arm_apcscc void @g(i64)
diff --git a/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll b/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll
index 8f6449e..2b20931 100644
--- a/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll
+++ b/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 | grep vmov.f32 | count 7
+; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 | grep vmov.f32 | count 3
define arm_apcscc void @fht(float* nocapture %fz, i16 signext %n) nounwind {
entry:
diff --git a/test/CodeGen/Thumb2/lsr-deficiency.ll b/test/CodeGen/Thumb2/lsr-deficiency.ll
index 7b1b57a..ac2cd34 100644
--- a/test/CodeGen/Thumb2/lsr-deficiency.ll
+++ b/test/CodeGen/Thumb2/lsr-deficiency.ll
@@ -1,25 +1,29 @@
; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -relocation-model=pic | FileCheck %s
; rdar://7387640
-; FIXME: We still need to rewrite array reference iv of stride -4 with loop
-; count iv of stride -1.
+; This now reduces to a single induction variable.
+
+; TODO: It still gets a GPR shuffle at the end of the loop
+; This is because something in instruction selection has decided
+; that comparing the pre-incremented value with zero is better
+; than comparing the post-incremented value with -4.
@G = external global i32 ; <i32*> [#uses=2]
@array = external global i32* ; <i32**> [#uses=1]
define arm_apcscc void @t() nounwind optsize {
; CHECK: t:
-; CHECK: mov.w r2, #4000
-; CHECK: movw r3, #1001
+; CHECK: mov.w r2, #1000
entry:
%.pre = load i32* @G, align 4 ; <i32> [#uses=1]
br label %bb
bb: ; preds = %bb, %entry
; CHECK: LBB1_1:
-; CHECK: subs r3, #1
-; CHECK: cmp r3, #0
-; CHECK: sub.w r2, r2, #4
+; CHECK: cmp r2, #0
+; CHECK: sub.w r9, r2, #1
+; CHECK: mov r2, r9
+
%0 = phi i32 [ %.pre, %entry ], [ %3, %bb ] ; <i32> [#uses=1]
%indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=2]
%tmp5 = sub i32 1000, %indvar ; <i32> [#uses=1]
diff --git a/test/CodeGen/Thumb2/thumb2-ifcvt1.ll b/test/CodeGen/Thumb2/thumb2-ifcvt1.ll
index 71199ab..1d26756 100644
--- a/test/CodeGen/Thumb2/thumb2-ifcvt1.ll
+++ b/test/CodeGen/Thumb2/thumb2-ifcvt1.ll
@@ -1,6 +1,6 @@
; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s
-define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) {
+define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
; CHECK: t1:
; CHECK: it ne
; CHECK: cmpne
@@ -20,12 +20,12 @@ cond_next:
}
; FIXME: Check for # of unconditional branch after adding branch folding post ifcvt.
-define i32 @t2(i32 %a, i32 %b) {
+define i32 @t2(i32 %a, i32 %b) nounwind {
entry:
; CHECK: t2:
-; CHECK: ite le
-; CHECK: suble
+; CHECK: ite gt
; CHECK: subgt
+; CHECK: suble
%tmp1434 = icmp eq i32 %a, %b ; <i1> [#uses=1]
br i1 %tmp1434, label %bb17, label %bb.outer
@@ -60,14 +60,14 @@ bb17: ; preds = %cond_false, %cond_true, %entry
@x = external global i32* ; <i32**> [#uses=1]
-define void @foo(i32 %a) {
+define void @foo(i32 %a) nounwind {
entry:
%tmp = load i32** @x ; <i32*> [#uses=1]
store i32 %a, i32* %tmp
ret void
}
-define void @t3(i32 %a, i32 %b) {
+define void @t3(i32 %a, i32 %b) nounwind {
entry:
; CHECK: t3:
; CHECK: it lt
diff --git a/test/CodeGen/Thumb2/thumb2-spill-q.ll b/test/CodeGen/Thumb2/thumb2-spill-q.ll
index 2b08789..ff178b4 100644
--- a/test/CodeGen/Thumb2/thumb2-spill-q.ll
+++ b/test/CodeGen/Thumb2/thumb2-spill-q.ll
@@ -12,8 +12,8 @@ declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*) nounwind readonly
define arm_apcscc void @aaa(%quuz* %this, i8* %block) {
; CHECK: aaa:
; CHECK: bic r4, r4, #15
-; CHECK: vst1.64 {{.*}}sp, :128
-; CHECK: vld1.64 {{.*}}sp, :128
+; CHECK: vst1.64 {{.*}}[{{.*}}, :128]
+; CHECK: vld1.64 {{.*}}[{{.*}}, :128]
entry:
%0 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef) nounwind ; <<4 x float>> [#uses=1]
store float 6.300000e+01, float* undef, align 4
diff --git a/test/CodeGen/X86/2006-05-11-InstrSched.ll b/test/CodeGen/X86/2006-05-11-InstrSched.ll
index bdbe713..56d6aa9 100644
--- a/test/CodeGen/X86/2006-05-11-InstrSched.ll
+++ b/test/CodeGen/X86/2006-05-11-InstrSched.ll
@@ -1,5 +1,5 @@
; RUN: llc < %s -march=x86 -mattr=+sse2 -stats -realign-stack=0 |&\
-; RUN: grep {asm-printer} | grep 31
+; RUN: grep {asm-printer} | grep 34
target datalayout = "e-p:32:32"
define void @foo(i32* %mc, i32* %bp, i32* %ms, i32* %xmb, i32* %mpp, i32* %tpmm, i32* %ip, i32* %tpim, i32* %dpp, i32* %tpdm, i32* %bpi, i32 %M) nounwind {
@@ -40,7 +40,7 @@ cond_true: ; preds = %cond_true, %entry
%tmp137.upgrd.7 = bitcast i32* %tmp137 to <2 x i64>* ; <<2 x i64>*> [#uses=1]
store <2 x i64> %tmp131, <2 x i64>* %tmp137.upgrd.7
%tmp147 = add nsw i32 %tmp.10, 8 ; <i32> [#uses=1]
- %tmp.upgrd.8 = icmp slt i32 %tmp147, %M ; <i1> [#uses=1]
+ %tmp.upgrd.8 = icmp ne i32 %tmp147, %M ; <i1> [#uses=1]
%indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
br i1 %tmp.upgrd.8, label %cond_true, label %return
diff --git a/test/CodeGen/Generic/2006-12-16-InlineAsmCrash.ll b/test/CodeGen/X86/2006-12-16-InlineAsmCrash.ll
index 50a244b..50a244b 100644
--- a/test/CodeGen/Generic/2006-12-16-InlineAsmCrash.ll
+++ b/test/CodeGen/X86/2006-12-16-InlineAsmCrash.ll
diff --git a/test/CodeGen/Generic/2007-02-23-DAGCombine-Miscompile.ll b/test/CodeGen/X86/2007-02-23-DAGCombine-Miscompile.ll
index a8f0e57..a8f0e57 100644
--- a/test/CodeGen/Generic/2007-02-23-DAGCombine-Miscompile.ll
+++ b/test/CodeGen/X86/2007-02-23-DAGCombine-Miscompile.ll
diff --git a/test/CodeGen/X86/2007-03-15-GEP-Idx-Sink.ll b/test/CodeGen/X86/2007-03-15-GEP-Idx-Sink.ll
index 4cac9b4..e1f8901 100644
--- a/test/CodeGen/X86/2007-03-15-GEP-Idx-Sink.ll
+++ b/test/CodeGen/X86/2007-03-15-GEP-Idx-Sink.ll
@@ -1,7 +1,7 @@
; RUN: llc < %s -march=x86 -mtriple=i686-darwin | \
; RUN: grep push | count 3
-define void @foo(i8** %buf, i32 %size, i32 %col, i8* %p) {
+define void @foo(i8** %buf, i32 %size, i32 %col, i8* %p) nounwind {
entry:
icmp sgt i32 %size, 0 ; <i1>:0 [#uses=1]
br i1 %0, label %bb.preheader, label %return
diff --git a/test/CodeGen/X86/2007-10-05-3AddrConvert.ll b/test/CodeGen/X86/2007-10-05-3AddrConvert.ll
index 67323e8..2c2706d 100644
--- a/test/CodeGen/X86/2007-10-05-3AddrConvert.ll
+++ b/test/CodeGen/X86/2007-10-05-3AddrConvert.ll
@@ -36,7 +36,9 @@ bb.i6.i: ; preds = %bb.i6.i, %stepsystem.exit.i
bb107.i.i: ; preds = %bb107.i.i, %bb.i6.i
%q_addr.0.i.i.in = phi %struct.bnode** [ null, %bb107.i.i ], [ %4, %bb.i6.i ] ; <%struct.bnode**> [#uses=1]
- %q_addr.0.i.i = load %struct.bnode** %q_addr.0.i.i.in ; <%struct.bnode*> [#uses=0]
+ %q_addr.0.i.i = load %struct.bnode** %q_addr.0.i.i.in ; <%struct.bnode*> [#uses=1]
+ %q_addr.1 = getelementptr %struct.anon* %0, i32 0, i32 4, i32 1
+ store %struct.bnode* %q_addr.0.i.i, %struct.bnode** %q_addr.1, align 4
br label %bb107.i.i
bb47.loopexit.i: ; preds = %bb32.i
diff --git a/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll b/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll
index 721d4c9..8e315f4 100644
--- a/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll
+++ b/test/CodeGen/X86/2007-11-30-LoadFolding-Bug.ll
@@ -35,7 +35,7 @@ cond_next36.i: ; preds = %cond_next.i
bb.i28.i: ; preds = %bb.i28.i, %cond_next36.i
; CHECK: %bb.i28.i
; CHECK: addl $2
-; CHECK: addl $2
+; CHECK: addl $-2
%j.0.reg2mem.0.i16.i = phi i32 [ 0, %cond_next36.i ], [ %indvar.next39.i, %bb.i28.i ] ; <i32> [#uses=2]
%din_addr.1.reg2mem.0.i17.i = phi double [ 0.000000e+00, %cond_next36.i ], [ %tmp16.i25.i, %bb.i28.i ] ; <double> [#uses=1]
%tmp1.i18.i = fptosi double %din_addr.1.reg2mem.0.i17.i to i32 ; <i32> [#uses=2]
diff --git a/test/CodeGen/X86/2007-11-30-TestLoadFolding.ll b/test/CodeGen/X86/2007-11-30-TestLoadFolding.ll
deleted file mode 100644
index debb461..0000000
--- a/test/CodeGen/X86/2007-11-30-TestLoadFolding.ll
+++ /dev/null
@@ -1,58 +0,0 @@
-; RUN: llc < %s -march=x86 -stats |& \
-; RUN: grep {1 .*folded into instructions}
-; RUN: llc < %s -march=x86 | grep cmp | count 4
-
- %struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* }
-
-define fastcc i32 @perimeter(%struct.quad_struct* %tree, i32 %size) {
-entry:
- %tree.idx7.val = load %struct.quad_struct** null ; <%struct.quad_struct*> [#uses=1]
- %tmp8.i51 = icmp eq %struct.quad_struct* %tree.idx7.val, null ; <i1> [#uses=2]
- br i1 %tmp8.i51, label %cond_next, label %cond_next.i52
-
-cond_next.i52: ; preds = %entry
- ret i32 0
-
-cond_next: ; preds = %entry
- %tmp59 = load i32* null, align 4 ; <i32> [#uses=1]
- %tmp70 = icmp eq i32 %tmp59, 2 ; <i1> [#uses=1]
- br i1 %tmp70, label %cond_true.i35, label %bb80
-
-cond_true.i35: ; preds = %cond_next
- %tmp14.i.i37 = load %struct.quad_struct** null, align 4 ; <%struct.quad_struct*> [#uses=1]
- %tmp3.i160 = load i32* null, align 4 ; <i32> [#uses=1]
- %tmp4.i161 = icmp eq i32 %tmp3.i160, 2 ; <i1> [#uses=1]
- br i1 %tmp4.i161, label %cond_true.i163, label %cond_false.i178
-
-cond_true.i163: ; preds = %cond_true.i35
- %tmp7.i162 = sdiv i32 %size, 4 ; <i32> [#uses=2]
- %tmp13.i168 = tail call fastcc i32 @sum_adjacent( %struct.quad_struct* null, i32 3, i32 2, i32 %tmp7.i162 ) ; <i32> [#uses=1]
- %tmp18.i11.i170 = getelementptr %struct.quad_struct* %tmp14.i.i37, i32 0, i32 4 ; <%struct.quad_struct**> [#uses=1]
- %tmp19.i12.i171 = load %struct.quad_struct** %tmp18.i11.i170, align 4 ; <%struct.quad_struct*> [#uses=1]
- %tmp21.i173 = tail call fastcc i32 @sum_adjacent( %struct.quad_struct* %tmp19.i12.i171, i32 3, i32 2, i32 %tmp7.i162 ) ; <i32> [#uses=1]
- %tmp22.i174 = add i32 %tmp21.i173, %tmp13.i168 ; <i32> [#uses=1]
- br i1 %tmp4.i161, label %cond_true.i141, label %cond_false.i156
-
-cond_false.i178: ; preds = %cond_true.i35
- ret i32 0
-
-cond_true.i141: ; preds = %cond_true.i163
- %tmp7.i140 = sdiv i32 %size, 4 ; <i32> [#uses=1]
- %tmp21.i151 = tail call fastcc i32 @sum_adjacent( %struct.quad_struct* null, i32 3, i32 2, i32 %tmp7.i140 ) ; <i32> [#uses=0]
- ret i32 0
-
-cond_false.i156: ; preds = %cond_true.i163
- %tmp22.i44 = add i32 0, %tmp22.i174 ; <i32> [#uses=0]
- br i1 %tmp8.i51, label %bb22.i, label %cond_next.i
-
-bb80: ; preds = %cond_next
- ret i32 0
-
-cond_next.i: ; preds = %cond_false.i156
- ret i32 0
-
-bb22.i: ; preds = %cond_false.i156
- ret i32 0
-}
-
-declare fastcc i32 @sum_adjacent(%struct.quad_struct*, i32, i32, i32)
diff --git a/test/CodeGen/X86/2008-01-25-EmptyFunction.ll b/test/CodeGen/X86/2008-01-25-EmptyFunction.ll
index b936686..387645f 100644
--- a/test/CodeGen/X86/2008-01-25-EmptyFunction.ll
+++ b/test/CodeGen/X86/2008-01-25-EmptyFunction.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=x86 | grep nop
+; RUN: llc < %s -march=x86 | grep {.byte 0}
target triple = "i686-apple-darwin8"
diff --git a/test/CodeGen/X86/2008-07-11-SpillerBug.ll b/test/CodeGen/X86/2008-07-11-SpillerBug.ll
index 88a5fde..548b44d 100644
--- a/test/CodeGen/X86/2008-07-11-SpillerBug.ll
+++ b/test/CodeGen/X86/2008-07-11-SpillerBug.ll
@@ -1,9 +1,7 @@
-; RUN: llc < %s -march=x86 -relocation-model=static -disable-fp-elim -post-RA-scheduler=false | FileCheck %s
+; RUN: llc < %s -march=x86 -relocation-model=static -disable-fp-elim -post-RA-scheduler=false -asm-verbose=0 | FileCheck %s
; PR2536
-
-; CHECK: movw %cx
-; CHECK-NEXT: andl $65534, %
+; CHECK: andl $65534, %
; CHECK-NEXT: movl %
; CHECK-NEXT: movl $17
diff --git a/test/CodeGen/X86/2009-02-07-CoalescerBug.ll b/test/CodeGen/X86/2009-02-07-CoalescerBug.ll
deleted file mode 100644
index 2d0bbe6..0000000
--- a/test/CodeGen/X86/2009-02-07-CoalescerBug.ll
+++ /dev/null
@@ -1,491 +0,0 @@
-; RUN: llc < %s -march=x86 -relocation-model=pic -stats |& grep {Number of valno def marked dead} | grep 1
-; rdar://6566708
-
-target triple = "i386-apple-darwin9.6"
- %"struct..0$_58" = type { i32, %"struct.llvm::MachineOperand"**, %"struct.llvm::MachineOperand"* }
- %"struct..1$_60" = type { i32 }
- %"struct..3$_53" = type { i64 }
- %struct.__false_type = type <{ i8 }>
- %"struct.llvm::APFloat" = type { %"struct.llvm::fltSemantics"*, %"struct..3$_53", i16, i16 }
- %"struct.llvm::AbstractTypeUser" = type { i32 (...)** }
- %"struct.llvm::AnalysisResolver" = type { %"struct.std::vector<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >", %"struct.llvm::PMDataManager"* }
- %"struct.llvm::Annotable" = type { %"struct.llvm::Annotation"* }
- %"struct.llvm::Annotation" = type { i32 (...)**, %"struct..1$_60", %"struct.llvm::Annotation"* }
- %"struct.llvm::Argument" = type { %"struct.llvm::Value", %"struct.llvm::ilist_node<llvm::Argument>", %"struct.llvm::Function"* }
- %"struct.llvm::AttrListPtr" = type { %"struct.llvm::AttributeListImpl"* }
- %"struct.llvm::AttributeListImpl" = type opaque
- %"struct.llvm::BasicBlock" = type { %"struct.llvm::Value", %"struct.llvm::ilist_node<llvm::BasicBlock>", %"struct.llvm::iplist<llvm::Instruction,llvm::ilist_traits<llvm::Instruction> >", %"struct.llvm::Function"* }
- %"struct.llvm::BitVector" = type { i32*, i32, i32 }
- %"struct.llvm::BumpPtrAllocator" = type { i8* }
- %"struct.llvm::CalleeSavedInfo" = type { i32, %"struct.llvm::TargetRegisterClass"*, i32 }
- %"struct.llvm::CondCodeSDNode" = type { %"struct.llvm::SDNode", i32 }
- %"struct.llvm::Constant" = type { %"struct.llvm::User" }
- %"struct.llvm::DebugLocTracker" = type { %"struct.std::vector<llvm::DebugLocTuple,std::allocator<llvm::DebugLocTuple> >", %"struct.llvm::DenseMap<llvm::DebugLocTuple,unsigned int,llvm::DenseMapInfo<llvm::DebugLocTuple>,llvm::DenseMapInfo<unsigned int> >" }
- %"struct.llvm::DebugLocTuple" = type { i32, i32, i32 }
- %"struct.llvm::DenseMap<llvm::DebugLocTuple,unsigned int,llvm::DenseMapInfo<llvm::DebugLocTuple>,llvm::DenseMapInfo<unsigned int> >" = type { i32, %"struct.std::pair<llvm::DebugLocTuple,unsigned int>"*, i32, i32 }
- %"struct.llvm::DwarfWriter" = type opaque
- %"struct.llvm::FoldingSet<llvm::SDNode>" = type { %"struct.llvm::FoldingSetImpl" }
- %"struct.llvm::FoldingSetImpl" = type { i32 (...)**, i8**, i32, i32 }
- %"struct.llvm::Function" = type { %"struct.llvm::GlobalValue", %"struct.llvm::Annotable", %"struct.llvm::ilist_node<llvm::Function>", %"struct.llvm::iplist<llvm::BasicBlock,llvm::ilist_traits<llvm::BasicBlock> >", %"struct.llvm::iplist<llvm::Argument,llvm::ilist_traits<llvm::Argument> >", %"struct.llvm::ValueSymbolTable"*, %"struct.llvm::AttrListPtr" }
- %"struct.llvm::FunctionLoweringInfo" = type opaque
- %"struct.llvm::GlobalAddressSDNode" = type { %"struct.llvm::SDNode", %"struct.llvm::GlobalValue"*, i64 }
- %"struct.llvm::GlobalValue" = type { %"struct.llvm::Constant", %"struct.llvm::Module"*, i32, %"struct.std::string" }
- %"struct.llvm::GlobalVariable" = type { %"struct.llvm::GlobalValue", %"struct.llvm::ilist_node<llvm::GlobalVariable>", i8 }
- %"struct.llvm::ImmutablePass" = type { %"struct.llvm::ModulePass" }
- %"struct.llvm::Instruction" = type { %"struct.llvm::User", %"struct.llvm::ilist_node<llvm::Instruction>", %"struct.llvm::BasicBlock"* }
- %"struct.llvm::LandingPadInfo" = type <{ %"struct.llvm::MachineBasicBlock"*, [12 x i8], %"struct.llvm::SmallVector<unsigned int,1u>", %"struct.llvm::SmallVector<unsigned int,1u>", i32, %"struct.llvm::Function"*, %"struct.std::vector<int,std::allocator<int> >", [3 x i32] }>
- %"struct.llvm::MVT" = type { %"struct..1$_60" }
- %"struct.llvm::MachineBasicBlock" = type { %"struct.llvm::ilist_node<llvm::MachineBasicBlock>", %"struct.llvm::ilist<llvm::MachineInstr>", %"struct.llvm::BasicBlock"*, i32, %"struct.llvm::MachineFunction"*, %"struct.std::vector<llvm::MachineBasicBlock*,std::allocator<llvm::MachineBasicBlock*> >", %"struct.std::vector<llvm::MachineBasicBlock*,std::allocator<llvm::MachineBasicBlock*> >", %"struct.std::vector<int,std::allocator<int> >", i32, i8 }
- %"struct.llvm::MachineConstantPool" = type opaque
- %"struct.llvm::MachineFrameInfo" = type { %"struct.std::vector<llvm::MachineFrameInfo::StackObject,std::allocator<llvm::MachineFrameInfo::StackObject> >", i32, i8, i8, i64, i32, i32, i8, i32, i32, %"struct.std::vector<llvm::CalleeSavedInfo,std::allocator<llvm::CalleeSavedInfo> >", %"struct.llvm::MachineModuleInfo"*, %"struct.llvm::TargetFrameInfo"* }
- %"struct.llvm::MachineFrameInfo::StackObject" = type { i64, i32, i8, i64 }
- %"struct.llvm::MachineFunction" = type { %"struct.llvm::Annotation", %"struct.llvm::Function"*, %"struct.llvm::TargetMachine"*, %"struct.llvm::MachineRegisterInfo"*, %"struct.llvm::AbstractTypeUser"*, %"struct.llvm::MachineFrameInfo"*, %"struct.llvm::MachineConstantPool"*, %"struct.llvm::MachineJumpTableInfo"*, %"struct.std::vector<llvm::MachineBasicBlock*,std::allocator<llvm::MachineBasicBlock*> >", %"struct.llvm::BumpPtrAllocator", %"struct.llvm::Recycler<llvm::MachineBasicBlock,116ul,4ul>", %"struct.llvm::Recycler<llvm::MachineBasicBlock,116ul,4ul>", %"struct.llvm::ilist<llvm::MachineBasicBlock>", %"struct.llvm::DebugLocTracker" }
- %"struct.llvm::MachineInstr" = type { %"struct.llvm::ilist_node<llvm::MachineInstr>", %"struct.llvm::TargetInstrDesc"*, i16, %"struct.std::vector<llvm::MachineOperand,std::allocator<llvm::MachineOperand> >", %"struct.std::list<llvm::MachineMemOperand,std::allocator<llvm::MachineMemOperand> >", %"struct.llvm::MachineBasicBlock"*, %"struct..1$_60" }
- %"struct.llvm::MachineJumpTableInfo" = type opaque
- %"struct.llvm::MachineLocation" = type { i8, i32, i32 }
- %"struct.llvm::MachineModuleInfo" = type { %"struct.llvm::ImmutablePass", %"struct.std::vector<int,std::allocator<int> >", %"struct.std::vector<llvm::MachineMove,std::allocator<llvm::MachineMove> >", %"struct.std::vector<llvm::LandingPadInfo,std::allocator<llvm::LandingPadInfo> >", %"struct.std::vector<llvm::GlobalVariable*,std::allocator<llvm::GlobalVariable*> >", %"struct.std::vector<int,std::allocator<int> >", %"struct.std::vector<int,std::allocator<int> >", %"struct.std::vector<llvm::Function*,std::allocator<llvm::Function*> >", %"struct.llvm::SmallPtrSet<const llvm::Function*,32u>", i8, i8, i8 }
- %"struct.llvm::MachineMove" = type { i32, %"struct.llvm::MachineLocation", %"struct.llvm::MachineLocation" }
- %"struct.llvm::MachineOperand" = type { i8, i8, i8, %"struct.llvm::MachineInstr"*, %"struct.llvm::MachineOperand::$_57" }
- %"struct.llvm::MachineOperand::$_57" = type { %"struct..0$_58" }
- %"struct.llvm::MachineRegisterInfo" = type { %"struct.std::vector<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*>,std::allocator<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*> > >", %"struct.std::vector<std::vector<unsigned int, std::allocator<unsigned int> >,std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >", %"struct.llvm::MachineOperand"**, %"struct.llvm::BitVector", %"struct.std::vector<std::pair<unsigned int, unsigned int>,std::allocator<std::pair<unsigned int, unsigned int> > >", %"struct.std::vector<int,std::allocator<int> >" }
- %"struct.llvm::Module" = type opaque
- %"struct.llvm::ModulePass" = type { %"struct.llvm::Pass" }
- %"struct.llvm::PATypeHandle" = type { %"struct.llvm::Type"*, %"struct.llvm::AbstractTypeUser"* }
- %"struct.llvm::PATypeHolder" = type { %"struct.llvm::Type"* }
- %"struct.llvm::PMDataManager" = type opaque
- %"struct.llvm::Pass" = type { i32 (...)**, %"struct.llvm::AnalysisResolver"*, i32, %"struct.std::vector<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >" }
- %"struct.llvm::PassInfo" = type { i8*, i8*, i32, i8, i8, i8, %"struct.std::vector<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*> >", %"struct.llvm::Pass"* ()* }
- %"struct.llvm::Recycler<llvm::MachineBasicBlock,116ul,4ul>" = type { %"struct.llvm::iplist<llvm::RecyclerStruct,llvm::ilist_traits<llvm::RecyclerStruct> >" }
- %"struct.llvm::RecyclerStruct" = type { %"struct.llvm::RecyclerStruct"*, %"struct.llvm::RecyclerStruct"* }
- %"struct.llvm::RecyclingAllocator<llvm::BumpPtrAllocator,llvm::SDNode,132ul,4ul>" = type { %"struct.llvm::Recycler<llvm::MachineBasicBlock,116ul,4ul>", %"struct.llvm::BumpPtrAllocator" }
- %"struct.llvm::SDNode" = type { %"struct.llvm::BumpPtrAllocator", %"struct.llvm::ilist_node<llvm::SDNode>", i16, i16, i32, %"struct.llvm::SDUse"*, %"struct.llvm::MVT"*, %"struct.llvm::SDUse"*, i16, i16, %"struct..1$_60" }
- %"struct.llvm::SDUse" = type { %"struct.llvm::SDValue", %"struct.llvm::SDNode"*, %"struct.llvm::SDUse"**, %"struct.llvm::SDUse"* }
- %"struct.llvm::SDVTList" = type { %"struct.llvm::MVT"*, i16 }
- %"struct.llvm::SDValue" = type { %"struct.llvm::SDNode"*, i32 }
- %"struct.llvm::SelectionDAG" = type { %"struct.llvm::TargetLowering"*, %"struct.llvm::MachineFunction"*, %"struct.llvm::FunctionLoweringInfo"*, %"struct.llvm::MachineModuleInfo"*, %"struct.llvm::DwarfWriter"*, %"struct.llvm::SDNode", %"struct.llvm::SDValue", %"struct.llvm::ilist<llvm::SDNode>", %"struct.llvm::RecyclingAllocator<llvm::BumpPtrAllocator,llvm::SDNode,132ul,4ul>", %"struct.llvm::FoldingSet<llvm::SDNode>", %"struct.llvm::BumpPtrAllocator", %"struct.llvm::BumpPtrAllocator", %"struct.std::map<const llvm::SDNode*,std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::less<const llvm::SDNode*>,std::allocator<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >", %"struct.std::vector<llvm::SDVTList,std::allocator<llvm::SDVTList> >", %"struct.std::vector<llvm::CondCodeSDNode*,std::allocator<llvm::CondCodeSDNode*> >", %"struct.std::vector<llvm::SDNode*,std::allocator<llvm::SDNode*> >", %"struct.std::map<const llvm::SDNode*,std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::less<const llvm::SDNode*>,std::allocator<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >", %"struct.llvm::StringMap<llvm::SDNode*,llvm::MallocAllocator>", %"struct.llvm::StringMap<llvm::SDNode*,llvm::MallocAllocator>" }
- %"struct.llvm::SmallPtrSet<const llvm::Function*,32u>" = type { %"struct.llvm::SmallPtrSetImpl", [32 x i8*] }
- %"struct.llvm::SmallPtrSetImpl" = type { i8**, i32, i32, i32, [1 x i8*] }
- %"struct.llvm::SmallVector<llvm::SDValue,16u>" = type <{ [17 x i8], [127 x i8] }>
- %"struct.llvm::SmallVector<unsigned int,1u>" = type <{ [17 x i8], [3 x i8], [3 x i32] }>
- %"struct.llvm::StringMap<llvm::SDNode*,llvm::MallocAllocator>" = type { %"struct.llvm::StringMapImpl", %struct.__false_type }
- %"struct.llvm::StringMapImpl" = type { %"struct.llvm::StringMapImpl::ItemBucket"*, i32, i32, i32, i32 }
- %"struct.llvm::StringMapImpl::ItemBucket" = type { i32, %"struct..1$_60"* }
- %"struct.llvm::TargetAsmInfo" = type opaque
- %"struct.llvm::TargetData" = type <{ %"struct.llvm::ImmutablePass", i8, i8, i8, i8, [4 x i8], %"struct.llvm::SmallVector<llvm::SDValue,16u>" }>
- %"struct.llvm::TargetFrameInfo" = type { i32 (...)**, i32, i32, i32 }
- %"struct.llvm::TargetInstrDesc" = type { i16, i16, i16, i16, i8*, i32, i32, i32*, i32*, %"struct.llvm::TargetRegisterClass"**, %"struct.llvm::TargetOperandInfo"* }
- %"struct.llvm::TargetLowering" = type { i32 (...)**, %"struct.llvm::TargetMachine"*, %"struct.llvm::TargetData"*, %"struct.llvm::MVT", i8, i8, i8, i8, i8, i8, i8, %"struct.llvm::MVT", i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [30 x %"struct.llvm::TargetRegisterClass"*], [30 x i8], [30 x %"struct.llvm::MVT"], [30 x %"struct.llvm::MVT"], [179 x i64], [4 x i64], [30 x i64], [2 x [5 x i64]], [30 x i64], [24 x i64], %"struct.llvm::TargetLowering::ValueTypeActionImpl", %"struct.std::vector<llvm::APFloat,std::allocator<llvm::APFloat> >", %"struct.std::vector<std::pair<llvm::MVT, llvm::TargetRegisterClass*>,std::allocator<std::pair<llvm::MVT, llvm::TargetRegisterClass*> > >", [23 x i8], %"struct.std::map<const llvm::SDNode*,std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::less<const llvm::SDNode*>,std::allocator<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >", [180 x i8*], [180 x i32], i32, i32, i32, i8 }
- %"struct.llvm::TargetLowering::ValueTypeActionImpl" = type { [2 x i32] }
- %"struct.llvm::TargetMachine" = type { i32 (...)**, %"struct.llvm::TargetAsmInfo"* }
- %"struct.llvm::TargetOperandInfo" = type { i16, i16, i32 }
- %"struct.llvm::TargetRegisterClass" = type { i32 (...)**, i32, i8, %"struct.llvm::MVT"*, %"struct.llvm::TargetRegisterClass"**, %"struct.llvm::TargetRegisterClass"**, i32, i32, i32, i32*, i32* }
- %"struct.llvm::Type" = type { %"struct.llvm::AbstractTypeUser", i8, [3 x i8], i32, %"struct.llvm::Type"*, %"struct.std::vector<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*> >", i32, %"struct.llvm::PATypeHandle"* }
- %"struct.llvm::Use" = type { %"struct.llvm::Value"*, %"struct.llvm::Use"*, %"struct..1$_60" }
- %"struct.llvm::User" = type { %"struct.llvm::Value", %"struct.llvm::Use"*, i32 }
- %"struct.llvm::Value" = type { i32 (...)**, i16, i16, %"struct.llvm::PATypeHolder", %"struct.llvm::Use"*, %"struct.llvm::ValueName"* }
- %"struct.llvm::ValueName" = type opaque
- %"struct.llvm::ValueSymbolTable" = type opaque
- %"struct.llvm::fltSemantics" = type opaque
- %"struct.llvm::ilist<llvm::MachineBasicBlock>" = type { %"struct.llvm::iplist<llvm::MachineBasicBlock,llvm::ilist_traits<llvm::MachineBasicBlock> >" }
- %"struct.llvm::ilist<llvm::MachineInstr>" = type { %"struct.llvm::iplist<llvm::MachineInstr,llvm::ilist_traits<llvm::MachineInstr> >" }
- %"struct.llvm::ilist<llvm::SDNode>" = type { %"struct.llvm::iplist<llvm::SDNode,llvm::ilist_traits<llvm::SDNode> >" }
- %"struct.llvm::ilist_node<llvm::Argument>" = type { %"struct.llvm::Argument"*, %"struct.llvm::Argument"* }
- %"struct.llvm::ilist_node<llvm::BasicBlock>" = type { %"struct.llvm::BasicBlock"*, %"struct.llvm::BasicBlock"* }
- %"struct.llvm::ilist_node<llvm::Function>" = type { %"struct.llvm::Function"*, %"struct.llvm::Function"* }
- %"struct.llvm::ilist_node<llvm::GlobalVariable>" = type { %"struct.llvm::GlobalVariable"*, %"struct.llvm::GlobalVariable"* }
- %"struct.llvm::ilist_node<llvm::Instruction>" = type { %"struct.llvm::Instruction"*, %"struct.llvm::Instruction"* }
- %"struct.llvm::ilist_node<llvm::MachineBasicBlock>" = type { %"struct.llvm::MachineBasicBlock"*, %"struct.llvm::MachineBasicBlock"* }
- %"struct.llvm::ilist_node<llvm::MachineInstr>" = type { %"struct.llvm::MachineInstr"*, %"struct.llvm::MachineInstr"* }
- %"struct.llvm::ilist_node<llvm::SDNode>" = type { %"struct.llvm::SDNode"*, %"struct.llvm::SDNode"* }
- %"struct.llvm::ilist_traits<llvm::MachineBasicBlock>" = type { %"struct.llvm::MachineBasicBlock" }
- %"struct.llvm::ilist_traits<llvm::MachineInstr>" = type { %"struct.llvm::MachineInstr", %"struct.llvm::MachineBasicBlock"* }
- %"struct.llvm::ilist_traits<llvm::RecyclerStruct>" = type { %"struct.llvm::RecyclerStruct" }
- %"struct.llvm::ilist_traits<llvm::SDNode>" = type { %"struct.llvm::SDNode" }
- %"struct.llvm::iplist<llvm::Argument,llvm::ilist_traits<llvm::Argument> >" = type { %"struct.llvm::Argument"* }
- %"struct.llvm::iplist<llvm::BasicBlock,llvm::ilist_traits<llvm::BasicBlock> >" = type { %"struct.llvm::BasicBlock"* }
- %"struct.llvm::iplist<llvm::Instruction,llvm::ilist_traits<llvm::Instruction> >" = type { %"struct.llvm::Instruction"* }
- %"struct.llvm::iplist<llvm::MachineBasicBlock,llvm::ilist_traits<llvm::MachineBasicBlock> >" = type { %"struct.llvm::ilist_traits<llvm::MachineBasicBlock>", %"struct.llvm::MachineBasicBlock"* }
- %"struct.llvm::iplist<llvm::MachineInstr,llvm::ilist_traits<llvm::MachineInstr> >" = type { %"struct.llvm::ilist_traits<llvm::MachineInstr>", %"struct.llvm::MachineInstr"* }
- %"struct.llvm::iplist<llvm::RecyclerStruct,llvm::ilist_traits<llvm::RecyclerStruct> >" = type { %"struct.llvm::ilist_traits<llvm::RecyclerStruct>", %"struct.llvm::RecyclerStruct"* }
- %"struct.llvm::iplist<llvm::SDNode,llvm::ilist_traits<llvm::SDNode> >" = type { %"struct.llvm::ilist_traits<llvm::SDNode>", %"struct.llvm::SDNode"* }
- %"struct.std::_List_base<llvm::MachineMemOperand,std::allocator<llvm::MachineMemOperand> >" = type { %"struct.llvm::ilist_traits<llvm::RecyclerStruct>" }
- %"struct.std::_Rb_tree<const llvm::SDNode*,std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,std::_Select1st<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >,std::less<const llvm::SDNode*>,std::allocator<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >" = type { %"struct.std::_Rb_tree<const llvm::SDNode*,std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,std::_Select1st<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >,std::less<const llvm::SDNode*>,std::allocator<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_Rb_tree_impl<std::less<const llvm::SDNode*>,false>" }
- %"struct.std::_Rb_tree<const llvm::SDNode*,std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,std::_Select1st<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >,std::less<const llvm::SDNode*>,std::allocator<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_Rb_tree_impl<std::less<const llvm::SDNode*>,false>" = type { %struct.__false_type, %"struct.std::_Rb_tree_node_base", i32 }
- %"struct.std::_Rb_tree_node_base" = type { i32, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"* }
- %"struct.std::_Vector_base<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*> >" = type { %"struct.std::_Vector_base<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*> >::_Vector_impl" }
- %"struct.std::_Vector_base<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*> >::_Vector_impl" = type { %"struct.llvm::PassInfo"**, %"struct.llvm::PassInfo"**, %"struct.llvm::PassInfo"** }
- %"struct.std::_Vector_base<int,std::allocator<int> >" = type { %"struct.std::_Vector_base<int,std::allocator<int> >::_Vector_impl" }
- %"struct.std::_Vector_base<int,std::allocator<int> >::_Vector_impl" = type { i32*, i32*, i32* }
- %"struct.std::_Vector_base<llvm::APFloat,std::allocator<llvm::APFloat> >" = type { %"struct.std::_Vector_base<llvm::APFloat,std::allocator<llvm::APFloat> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::APFloat,std::allocator<llvm::APFloat> >::_Vector_impl" = type { %"struct.llvm::APFloat"*, %"struct.llvm::APFloat"*, %"struct.llvm::APFloat"* }
- %"struct.std::_Vector_base<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*> >" = type { %"struct.std::_Vector_base<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*> >::_Vector_impl" = type { %"struct.llvm::AbstractTypeUser"**, %"struct.llvm::AbstractTypeUser"**, %"struct.llvm::AbstractTypeUser"** }
- %"struct.std::_Vector_base<llvm::CalleeSavedInfo,std::allocator<llvm::CalleeSavedInfo> >" = type { %"struct.std::_Vector_base<llvm::CalleeSavedInfo,std::allocator<llvm::CalleeSavedInfo> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::CalleeSavedInfo,std::allocator<llvm::CalleeSavedInfo> >::_Vector_impl" = type { %"struct.llvm::CalleeSavedInfo"*, %"struct.llvm::CalleeSavedInfo"*, %"struct.llvm::CalleeSavedInfo"* }
- %"struct.std::_Vector_base<llvm::CondCodeSDNode*,std::allocator<llvm::CondCodeSDNode*> >" = type { %"struct.std::_Vector_base<llvm::CondCodeSDNode*,std::allocator<llvm::CondCodeSDNode*> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::CondCodeSDNode*,std::allocator<llvm::CondCodeSDNode*> >::_Vector_impl" = type { %"struct.llvm::CondCodeSDNode"**, %"struct.llvm::CondCodeSDNode"**, %"struct.llvm::CondCodeSDNode"** }
- %"struct.std::_Vector_base<llvm::DebugLocTuple,std::allocator<llvm::DebugLocTuple> >" = type { %"struct.std::_Vector_base<llvm::DebugLocTuple,std::allocator<llvm::DebugLocTuple> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::DebugLocTuple,std::allocator<llvm::DebugLocTuple> >::_Vector_impl" = type { %"struct.llvm::DebugLocTuple"*, %"struct.llvm::DebugLocTuple"*, %"struct.llvm::DebugLocTuple"* }
- %"struct.std::_Vector_base<llvm::Function*,std::allocator<llvm::Function*> >" = type { %"struct.std::_Vector_base<llvm::Function*,std::allocator<llvm::Function*> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::Function*,std::allocator<llvm::Function*> >::_Vector_impl" = type { %"struct.llvm::Function"**, %"struct.llvm::Function"**, %"struct.llvm::Function"** }
- %"struct.std::_Vector_base<llvm::GlobalVariable*,std::allocator<llvm::GlobalVariable*> >" = type { %"struct.std::_Vector_base<llvm::GlobalVariable*,std::allocator<llvm::GlobalVariable*> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::GlobalVariable*,std::allocator<llvm::GlobalVariable*> >::_Vector_impl" = type { %"struct.llvm::GlobalVariable"**, %"struct.llvm::GlobalVariable"**, %"struct.llvm::GlobalVariable"** }
- %"struct.std::_Vector_base<llvm::LandingPadInfo,std::allocator<llvm::LandingPadInfo> >" = type { %"struct.std::_Vector_base<llvm::LandingPadInfo,std::allocator<llvm::LandingPadInfo> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::LandingPadInfo,std::allocator<llvm::LandingPadInfo> >::_Vector_impl" = type { %"struct.llvm::LandingPadInfo"*, %"struct.llvm::LandingPadInfo"*, %"struct.llvm::LandingPadInfo"* }
- %"struct.std::_Vector_base<llvm::MachineBasicBlock*,std::allocator<llvm::MachineBasicBlock*> >" = type { %"struct.std::_Vector_base<llvm::MachineBasicBlock*,std::allocator<llvm::MachineBasicBlock*> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::MachineBasicBlock*,std::allocator<llvm::MachineBasicBlock*> >::_Vector_impl" = type { %"struct.llvm::MachineBasicBlock"**, %"struct.llvm::MachineBasicBlock"**, %"struct.llvm::MachineBasicBlock"** }
- %"struct.std::_Vector_base<llvm::MachineFrameInfo::StackObject,std::allocator<llvm::MachineFrameInfo::StackObject> >" = type { %"struct.std::_Vector_base<llvm::MachineFrameInfo::StackObject,std::allocator<llvm::MachineFrameInfo::StackObject> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::MachineFrameInfo::StackObject,std::allocator<llvm::MachineFrameInfo::StackObject> >::_Vector_impl" = type { %"struct.llvm::MachineFrameInfo::StackObject"*, %"struct.llvm::MachineFrameInfo::StackObject"*, %"struct.llvm::MachineFrameInfo::StackObject"* }
- %"struct.std::_Vector_base<llvm::MachineMove,std::allocator<llvm::MachineMove> >" = type { %"struct.std::_Vector_base<llvm::MachineMove,std::allocator<llvm::MachineMove> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::MachineMove,std::allocator<llvm::MachineMove> >::_Vector_impl" = type { %"struct.llvm::MachineMove"*, %"struct.llvm::MachineMove"*, %"struct.llvm::MachineMove"* }
- %"struct.std::_Vector_base<llvm::MachineOperand,std::allocator<llvm::MachineOperand> >" = type { %"struct.std::_Vector_base<llvm::MachineOperand,std::allocator<llvm::MachineOperand> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::MachineOperand,std::allocator<llvm::MachineOperand> >::_Vector_impl" = type { %"struct.llvm::MachineOperand"*, %"struct.llvm::MachineOperand"*, %"struct.llvm::MachineOperand"* }
- %"struct.std::_Vector_base<llvm::SDNode*,std::allocator<llvm::SDNode*> >" = type { %"struct.std::_Vector_base<llvm::SDNode*,std::allocator<llvm::SDNode*> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::SDNode*,std::allocator<llvm::SDNode*> >::_Vector_impl" = type { %"struct.llvm::SDNode"**, %"struct.llvm::SDNode"**, %"struct.llvm::SDNode"** }
- %"struct.std::_Vector_base<llvm::SDVTList,std::allocator<llvm::SDVTList> >" = type { %"struct.std::_Vector_base<llvm::SDVTList,std::allocator<llvm::SDVTList> >::_Vector_impl" }
- %"struct.std::_Vector_base<llvm::SDVTList,std::allocator<llvm::SDVTList> >::_Vector_impl" = type { %"struct.llvm::SDVTList"*, %"struct.llvm::SDVTList"*, %"struct.llvm::SDVTList"* }
- %"struct.std::_Vector_base<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >" = type { %"struct.std::_Vector_base<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >::_Vector_impl" }
- %"struct.std::_Vector_base<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >::_Vector_impl" = type { %"struct.std::pair<const llvm::PassInfo*,llvm::Pass*>"*, %"struct.std::pair<const llvm::PassInfo*,llvm::Pass*>"*, %"struct.std::pair<const llvm::PassInfo*,llvm::Pass*>"* }
- %"struct.std::_Vector_base<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*>,std::allocator<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*> > >" = type { %"struct.std::_Vector_base<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*>,std::allocator<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*> > >::_Vector_impl" }
- %"struct.std::_Vector_base<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*>,std::allocator<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*> > >::_Vector_impl" = type { %"struct.std::pair<const llvm::TargetRegisterClass*,llvm::MachineOperand*>"*, %"struct.std::pair<const llvm::TargetRegisterClass*,llvm::MachineOperand*>"*, %"struct.std::pair<const llvm::TargetRegisterClass*,llvm::MachineOperand*>"* }
- %"struct.std::_Vector_base<std::pair<llvm::MVT, llvm::TargetRegisterClass*>,std::allocator<std::pair<llvm::MVT, llvm::TargetRegisterClass*> > >" = type { %"struct.std::_Vector_base<std::pair<llvm::MVT, llvm::TargetRegisterClass*>,std::allocator<std::pair<llvm::MVT, llvm::TargetRegisterClass*> > >::_Vector_impl" }
- %"struct.std::_Vector_base<std::pair<llvm::MVT, llvm::TargetRegisterClass*>,std::allocator<std::pair<llvm::MVT, llvm::TargetRegisterClass*> > >::_Vector_impl" = type { %"struct.std::pair<llvm::MVT,llvm::TargetRegisterClass*>"*, %"struct.std::pair<llvm::MVT,llvm::TargetRegisterClass*>"*, %"struct.std::pair<llvm::MVT,llvm::TargetRegisterClass*>"* }
- %"struct.std::_Vector_base<std::pair<unsigned int, unsigned int>,std::allocator<std::pair<unsigned int, unsigned int> > >" = type { %"struct.std::_Vector_base<std::pair<unsigned int, unsigned int>,std::allocator<std::pair<unsigned int, unsigned int> > >::_Vector_impl" }
- %"struct.std::_Vector_base<std::pair<unsigned int, unsigned int>,std::allocator<std::pair<unsigned int, unsigned int> > >::_Vector_impl" = type { %"struct.std::pair<int,int>"*, %"struct.std::pair<int,int>"*, %"struct.std::pair<int,int>"* }
- %"struct.std::_Vector_base<std::vector<unsigned int, std::allocator<unsigned int> >,std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >" = type { %"struct.std::_Vector_base<std::vector<unsigned int, std::allocator<unsigned int> >,std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >::_Vector_impl" }
- %"struct.std::_Vector_base<std::vector<unsigned int, std::allocator<unsigned int> >,std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >::_Vector_impl" = type { %"struct.std::vector<int,std::allocator<int> >"*, %"struct.std::vector<int,std::allocator<int> >"*, %"struct.std::vector<int,std::allocator<int> >"* }
- %"struct.std::list<llvm::MachineMemOperand,std::allocator<llvm::MachineMemOperand> >" = type { %"struct.std::_List_base<llvm::MachineMemOperand,std::allocator<llvm::MachineMemOperand> >" }
- %"struct.std::map<const llvm::SDNode*,std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::less<const llvm::SDNode*>,std::allocator<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >" = type { %"struct.std::_Rb_tree<const llvm::SDNode*,std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,std::_Select1st<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >,std::less<const llvm::SDNode*>,std::allocator<std::pair<const llvm::SDNode* const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >" }
- %"struct.std::pair<const llvm::PassInfo*,llvm::Pass*>" = type { %"struct.llvm::PassInfo"*, %"struct.llvm::Pass"* }
- %"struct.std::pair<const llvm::TargetRegisterClass*,llvm::MachineOperand*>" = type { %"struct.llvm::TargetRegisterClass"*, %"struct.llvm::MachineOperand"* }
- %"struct.std::pair<int,int>" = type { i32, i32 }
- %"struct.std::pair<llvm::DebugLocTuple,unsigned int>" = type { %"struct.llvm::DebugLocTuple", i32 }
- %"struct.std::pair<llvm::MVT,llvm::TargetRegisterClass*>" = type { %"struct.llvm::MVT", %"struct.llvm::TargetRegisterClass"* }
- %"struct.std::string" = type { %"struct.llvm::BumpPtrAllocator" }
- %"struct.std::vector<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*> >" = type { %"struct.std::_Vector_base<const llvm::PassInfo*,std::allocator<const llvm::PassInfo*> >" }
- %"struct.std::vector<int,std::allocator<int> >" = type { %"struct.std::_Vector_base<int,std::allocator<int> >" }
- %"struct.std::vector<llvm::APFloat,std::allocator<llvm::APFloat> >" = type { %"struct.std::_Vector_base<llvm::APFloat,std::allocator<llvm::APFloat> >" }
- %"struct.std::vector<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*> >" = type { %"struct.std::_Vector_base<llvm::AbstractTypeUser*,std::allocator<llvm::AbstractTypeUser*> >" }
- %"struct.std::vector<llvm::CalleeSavedInfo,std::allocator<llvm::CalleeSavedInfo> >" = type { %"struct.std::_Vector_base<llvm::CalleeSavedInfo,std::allocator<llvm::CalleeSavedInfo> >" }
- %"struct.std::vector<llvm::CondCodeSDNode*,std::allocator<llvm::CondCodeSDNode*> >" = type { %"struct.std::_Vector_base<llvm::CondCodeSDNode*,std::allocator<llvm::CondCodeSDNode*> >" }
- %"struct.std::vector<llvm::DebugLocTuple,std::allocator<llvm::DebugLocTuple> >" = type { %"struct.std::_Vector_base<llvm::DebugLocTuple,std::allocator<llvm::DebugLocTuple> >" }
- %"struct.std::vector<llvm::Function*,std::allocator<llvm::Function*> >" = type { %"struct.std::_Vector_base<llvm::Function*,std::allocator<llvm::Function*> >" }
- %"struct.std::vector<llvm::GlobalVariable*,std::allocator<llvm::GlobalVariable*> >" = type { %"struct.std::_Vector_base<llvm::GlobalVariable*,std::allocator<llvm::GlobalVariable*> >" }
- %"struct.std::vector<llvm::LandingPadInfo,std::allocator<llvm::LandingPadInfo> >" = type { %"struct.std::_Vector_base<llvm::LandingPadInfo,std::allocator<llvm::LandingPadInfo> >" }
- %"struct.std::vector<llvm::MachineBasicBlock*,std::allocator<llvm::MachineBasicBlock*> >" = type { %"struct.std::_Vector_base<llvm::MachineBasicBlock*,std::allocator<llvm::MachineBasicBlock*> >" }
- %"struct.std::vector<llvm::MachineFrameInfo::StackObject,std::allocator<llvm::MachineFrameInfo::StackObject> >" = type { %"struct.std::_Vector_base<llvm::MachineFrameInfo::StackObject,std::allocator<llvm::MachineFrameInfo::StackObject> >" }
- %"struct.std::vector<llvm::MachineMove,std::allocator<llvm::MachineMove> >" = type { %"struct.std::_Vector_base<llvm::MachineMove,std::allocator<llvm::MachineMove> >" }
- %"struct.std::vector<llvm::MachineOperand,std::allocator<llvm::MachineOperand> >" = type { %"struct.std::_Vector_base<llvm::MachineOperand,std::allocator<llvm::MachineOperand> >" }
- %"struct.std::vector<llvm::SDNode*,std::allocator<llvm::SDNode*> >" = type { %"struct.std::_Vector_base<llvm::SDNode*,std::allocator<llvm::SDNode*> >" }
- %"struct.std::vector<llvm::SDVTList,std::allocator<llvm::SDVTList> >" = type { %"struct.std::_Vector_base<llvm::SDVTList,std::allocator<llvm::SDVTList> >" }
- %"struct.std::vector<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >" = type { %"struct.std::_Vector_base<std::pair<const llvm::PassInfo*, llvm::Pass*>,std::allocator<std::pair<const llvm::PassInfo*, llvm::Pass*> > >" }
- %"struct.std::vector<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*>,std::allocator<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*> > >" = type { %"struct.std::_Vector_base<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*>,std::allocator<std::pair<const llvm::TargetRegisterClass*, llvm::MachineOperand*> > >" }
- %"struct.std::vector<std::pair<llvm::MVT, llvm::TargetRegisterClass*>,std::allocator<std::pair<llvm::MVT, llvm::TargetRegisterClass*> > >" = type { %"struct.std::_Vector_base<std::pair<llvm::MVT, llvm::TargetRegisterClass*>,std::allocator<std::pair<llvm::MVT, llvm::TargetRegisterClass*> > >" }
- %"struct.std::vector<std::pair<unsigned int, unsigned int>,std::allocator<std::pair<unsigned int, unsigned int> > >" = type { %"struct.std::_Vector_base<std::pair<unsigned int, unsigned int>,std::allocator<std::pair<unsigned int, unsigned int> > >" }
- %"struct.std::vector<std::vector<unsigned int, std::allocator<unsigned int> >,std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >" = type { %"struct.std::_Vector_base<std::vector<unsigned int, std::allocator<unsigned int> >,std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >" }
-@"\01LC81" = internal constant [65 x i8] c"/Users/echeng/LLVM/llvm/include/llvm/CodeGen/SelectionDAGNodes.h\00" ; <[65 x i8]*> [#uses=1]
-@_ZZNK4llvm6SDNode12getValueTypeEjE8__func__ = internal constant [13 x i8] c"getValueType\00" ; <[13 x i8]*> [#uses=1]
-@"\01LC83" = internal constant [46 x i8] c"ResNo < NumValues && \22Illegal result number!\22\00" ; <[46 x i8]*> [#uses=1]
-@"\01LC197" = internal constant [16 x i8] c"___tls_get_addr\00" ; <[16 x i8]*> [#uses=1]
-@llvm.used1 = appending global [1 x i8*] [ i8* bitcast (i64 (%"struct.llvm::GlobalAddressSDNode"*, %"struct.llvm::SelectionDAG"*, %"struct.llvm::MVT"*)* @_ZL31LowerToTLSGeneralDynamicModel32PN4llvm19GlobalAddressSDNodeERNS_12SelectionDAGENS_3MVTE to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0]
-
-define fastcc i64 @_ZL31LowerToTLSGeneralDynamicModel32PN4llvm19GlobalAddressSDNodeERNS_12SelectionDAGENS_3MVTE(%"struct.llvm::GlobalAddressSDNode"* %GA, %"struct.llvm::SelectionDAG"* %DAG, %"struct.llvm::MVT"* byval align 4 %PtrVT) nounwind noinline {
-entry:
- %VT2.i185 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %VT1.i186 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %Ops.i187 = alloca [4 x %"struct.llvm::SDValue"], align 8 ; <[4 x %"struct.llvm::SDValue"]*> [#uses=9]
- %0 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %VT182 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %VT2.i173 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %VT1.i174 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %Ops.i175 = alloca [4 x %"struct.llvm::SDValue"], align 8 ; <[4 x %"struct.llvm::SDValue"]*> [#uses=9]
- %1 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %VT3.i = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %VT2.i = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %VT1.i = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %Ops.i = alloca [3 x %"struct.llvm::SDValue"], align 8 ; <[3 x %"struct.llvm::SDValue"]*> [#uses=7]
- %VT = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %Ops1 = alloca [5 x %"struct.llvm::SDValue"], align 8 ; <[5 x %"struct.llvm::SDValue"]*> [#uses=11]
- %Ops = alloca [3 x %"struct.llvm::SDValue"], align 8 ; <[3 x %"struct.llvm::SDValue"]*> [#uses=7]
- %NodeTys = alloca %"struct.llvm::SDVTList", align 8 ; <%"struct.llvm::SDVTList"*> [#uses=4]
- %2 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %3 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %4 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %5 = alloca %"struct.llvm::MVT", align 8 ; <%"struct.llvm::MVT"*> [#uses=2]
- %6 = getelementptr %"struct.llvm::GlobalAddressSDNode"* %GA, i32 0, i32 0, i32 10, i32 0 ; <i32*> [#uses=1]
- %7 = load i32* %6, align 4 ; <i32> [#uses=5]
- %8 = call i64 @_ZN4llvm12SelectionDAG7getNodeEjNS_8DebugLocENS_3MVTE(%"struct.llvm::SelectionDAG"* %DAG, i32 208, i32 0, %"struct.llvm::MVT"* byval align 4 %PtrVT) nounwind ; <i64> [#uses=2]
- %9 = trunc i64 %8 to i32 ; <i32> [#uses=1]
- %sroa.store.elt = lshr i64 %8, 32 ; <i64> [#uses=1]
- %10 = trunc i64 %sroa.store.elt to i32 ; <i32> [#uses=3]
- %tmp52 = inttoptr i32 %9 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=3]
- %11 = getelementptr %"struct.llvm::SelectionDAG"* %DAG, i32 0, i32 5 ; <%"struct.llvm::SDNode"*> [#uses=1]
- %12 = getelementptr %"struct.llvm::MVT"* %VT1.i186, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 0, i32* %12, align 8
- %13 = getelementptr %"struct.llvm::MVT"* %VT2.i185, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 12, i32* %13, align 8
- %14 = call i64 @_ZN4llvm12SelectionDAG9getVTListENS_3MVTES1_(%"struct.llvm::SelectionDAG"* %DAG, %"struct.llvm::MVT"* byval align 4 %VT1.i186, %"struct.llvm::MVT"* byval align 4 %VT2.i185) nounwind ; <i64> [#uses=1]
- %15 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i187, i32 0, i32 0, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %11, %"struct.llvm::SDNode"** %15, align 8
- %16 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i187, i32 0, i32 0, i32 1 ; <i32*> [#uses=1]
- store i32 0, i32* %16, align 4
- %17 = getelementptr %"struct.llvm::SDNode"* %tmp52, i32 0, i32 9 ; <i16*> [#uses=1]
- %18 = load i16* %17, align 2 ; <i16> [#uses=1]
- %19 = zext i16 %18 to i32 ; <i32> [#uses=1]
- %20 = icmp ugt i32 %19, %10 ; <i1> [#uses=1]
- br i1 %20, label %_ZN4llvm12SelectionDAG12getCopyToRegENS_7SDValueENS_8DebugLocEjS1_S1_.exit193, label %bb.i.i.i188
-
-bb.i.i.i188: ; preds = %entry
- call void @__assert_rtn(i8* getelementptr ([13 x i8]* @_ZZNK4llvm6SDNode12getValueTypeEjE8__func__, i32 0, i32 0), i8* getelementptr ([65 x i8]* @"\01LC81", i32 0, i32 0), i32 1314, i8* getelementptr ([46 x i8]* @"\01LC83", i32 0, i32 0)) noreturn nounwind
- unreachable
-
-_ZN4llvm12SelectionDAG12getCopyToRegENS_7SDValueENS_8DebugLocEjS1_S1_.exit193: ; preds = %entry
- %21 = trunc i64 %14 to i32 ; <i32> [#uses=1]
- %tmp4.i.i189 = inttoptr i32 %21 to %"struct.llvm::MVT"* ; <%"struct.llvm::MVT"*> [#uses=1]
- %22 = getelementptr %"struct.llvm::SDNode"* %tmp52, i32 0, i32 6 ; <%"struct.llvm::MVT"**> [#uses=1]
- %23 = load %"struct.llvm::MVT"** %22, align 4 ; <%"struct.llvm::MVT"*> [#uses=1]
- %24 = getelementptr %"struct.llvm::MVT"* %23, i32 %10, i32 0, i32 0 ; <i32*> [#uses=1]
- %25 = load i32* %24, align 4 ; <i32> [#uses=1]
- %26 = getelementptr %"struct.llvm::MVT"* %0, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 %25, i32* %26, align 8
- %27 = call i64 @_ZN4llvm12SelectionDAG11getRegisterEjNS_3MVTE(%"struct.llvm::SelectionDAG"* %DAG, i32 19, %"struct.llvm::MVT"* byval align 4 %0) nounwind ; <i64> [#uses=2]
- %28 = trunc i64 %27 to i32 ; <i32> [#uses=1]
- %sroa.store.elt.i190 = lshr i64 %27, 32 ; <i64> [#uses=1]
- %29 = trunc i64 %sroa.store.elt.i190 to i32 ; <i32> [#uses=1]
- %30 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i187, i32 0, i32 1, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- %tmp5.i191 = inttoptr i32 %28 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp5.i191, %"struct.llvm::SDNode"** %30, align 8
- %31 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i187, i32 0, i32 1, i32 1 ; <i32*> [#uses=1]
- store i32 %29, i32* %31, align 4
- %32 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i187, i32 0, i32 2, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp52, %"struct.llvm::SDNode"** %32, align 8
- %33 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i187, i32 0, i32 2, i32 1 ; <i32*> [#uses=1]
- store i32 %10, i32* %33, align 4
- %34 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i187, i32 0, i32 3, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* null, %"struct.llvm::SDNode"** %34, align 8
- %35 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i187, i32 0, i32 3, i32 1 ; <i32*> [#uses=1]
- store i32 0, i32* %35, align 4
- %36 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i187, i32 0, i32 0 ; <%"struct.llvm::SDValue"*> [#uses=1]
- %37 = call i64 @_ZN4llvm12SelectionDAG7getNodeEjNS_8DebugLocEPKNS_3MVTEjPKNS_7SDValueEj(%"struct.llvm::SelectionDAG"* %DAG, i32 36, i32 %7, %"struct.llvm::MVT"* %tmp4.i.i189, i32 2, %"struct.llvm::SDValue"* %36, i32 3) nounwind ; <i64> [#uses=2]
- %38 = trunc i64 %37 to i32 ; <i32> [#uses=1]
- %tmp66 = inttoptr i32 %38 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=2]
- %39 = getelementptr %"struct.llvm::MVT"* %5, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 12, i32* %39, align 8
- %40 = getelementptr %"struct.llvm::MVT"* %4, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 0, i32* %40, align 8
- %41 = call i64 @_ZN4llvm12SelectionDAG9getVTListENS_3MVTES1_S1_(%"struct.llvm::SelectionDAG"* %DAG, %"struct.llvm::MVT"* byval align 4 %PtrVT, %"struct.llvm::MVT"* byval align 4 %4, %"struct.llvm::MVT"* byval align 4 %5) nounwind ; <i64> [#uses=2]
- %42 = trunc i64 %41 to i32 ; <i32> [#uses=1]
- %sroa.store.elt75 = lshr i64 %41, 32 ; <i64> [#uses=1]
- %43 = trunc i64 %sroa.store.elt75 to i16 ; <i16> [#uses=1]
- %44 = getelementptr %"struct.llvm::SDVTList"* %NodeTys, i32 0, i32 0 ; <%"struct.llvm::MVT"**> [#uses=2]
- %tmp78 = inttoptr i32 %42 to %"struct.llvm::MVT"* ; <%"struct.llvm::MVT"*> [#uses=1]
- store %"struct.llvm::MVT"* %tmp78, %"struct.llvm::MVT"** %44, align 8
- %45 = getelementptr %"struct.llvm::SDVTList"* %NodeTys, i32 0, i32 1 ; <i16*> [#uses=2]
- store i16 %43, i16* %45, align 4
- %46 = getelementptr %"struct.llvm::GlobalAddressSDNode"* %GA, i32 0, i32 0, i32 9 ; <i16*> [#uses=1]
- %47 = load i16* %46, align 2 ; <i16> [#uses=1]
- %48 = icmp eq i16 %47, 0 ; <i1> [#uses=1]
- br i1 %48, label %bb.i, label %_ZNK4llvm6SDNode12getValueTypeEj.exit
-
-bb.i: ; preds = %_ZN4llvm12SelectionDAG12getCopyToRegENS_7SDValueENS_8DebugLocEjS1_S1_.exit193
- call void @__assert_rtn(i8* getelementptr ([13 x i8]* @_ZZNK4llvm6SDNode12getValueTypeEjE8__func__, i32 0, i32 0), i8* getelementptr ([65 x i8]* @"\01LC81", i32 0, i32 0), i32 1314, i8* getelementptr ([46 x i8]* @"\01LC83", i32 0, i32 0)) noreturn nounwind
- unreachable
-
-_ZNK4llvm6SDNode12getValueTypeEj.exit: ; preds = %_ZN4llvm12SelectionDAG12getCopyToRegENS_7SDValueENS_8DebugLocEjS1_S1_.exit193
- %sroa.store.elt63 = lshr i64 %37, 32 ; <i64> [#uses=1]
- %49 = trunc i64 %sroa.store.elt63 to i32 ; <i32> [#uses=1]
- %50 = getelementptr %"struct.llvm::GlobalAddressSDNode"* %GA, i32 0, i32 2 ; <i64*> [#uses=1]
- %51 = load i64* %50, align 4 ; <i64> [#uses=1]
- %52 = getelementptr %"struct.llvm::GlobalAddressSDNode"* %GA, i32 0, i32 0, i32 6 ; <%"struct.llvm::MVT"**> [#uses=1]
- %53 = load %"struct.llvm::MVT"** %52, align 4 ; <%"struct.llvm::MVT"*> [#uses=1]
- %54 = getelementptr %"struct.llvm::MVT"* %53, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- %55 = load i32* %54, align 4 ; <i32> [#uses=1]
- %56 = getelementptr %"struct.llvm::GlobalAddressSDNode"* %GA, i32 0, i32 1 ; <%"struct.llvm::GlobalValue"**> [#uses=1]
- %57 = load %"struct.llvm::GlobalValue"** %56, align 4 ; <%"struct.llvm::GlobalValue"*> [#uses=1]
- %58 = getelementptr %"struct.llvm::MVT"* %VT182, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 %55, i32* %58, align 8
- %59 = call i64 @_ZN4llvm12SelectionDAG16getGlobalAddressEPKNS_11GlobalValueENS_3MVTExb(%"struct.llvm::SelectionDAG"* %DAG, %"struct.llvm::GlobalValue"* %57, %"struct.llvm::MVT"* byval align 4 %VT182, i64 %51, i8 zeroext 1) nounwind ; <i64> [#uses=2]
- %60 = trunc i64 %59 to i32 ; <i32> [#uses=1]
- %sroa.store.elt83 = lshr i64 %59, 32 ; <i64> [#uses=1]
- %61 = trunc i64 %sroa.store.elt83 to i32 ; <i32> [#uses=1]
- %tmp86 = inttoptr i32 %60 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=1]
- %62 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops, i32 0, i32 0, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp66, %"struct.llvm::SDNode"** %62, align 8
- %63 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops, i32 0, i32 0, i32 1 ; <i32*> [#uses=1]
- store i32 %49, i32* %63, align 4
- %64 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops, i32 0, i32 1, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp86, %"struct.llvm::SDNode"** %64, align 8
- %65 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops, i32 0, i32 1, i32 1 ; <i32*> [#uses=1]
- store i32 %61, i32* %65, align 4
- %66 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops, i32 0, i32 2, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp66, %"struct.llvm::SDNode"** %66, align 8
- %67 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops, i32 0, i32 2, i32 1 ; <i32*> [#uses=1]
- store i32 1, i32* %67, align 4
- %68 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops, i32 0, i32 0 ; <%"struct.llvm::SDValue"*> [#uses=1]
- %69 = call i64 @_ZN4llvm12SelectionDAG7getNodeEjNS_8DebugLocENS_8SDVTListEPKNS_7SDValueEj(%"struct.llvm::SelectionDAG"* %DAG, i32 220, i32 %7, %"struct.llvm::SDVTList"* byval align 4 %NodeTys, %"struct.llvm::SDValue"* %68, i32 3) nounwind ; <i64> [#uses=2]
- %70 = trunc i64 %69 to i32 ; <i32> [#uses=1]
- %sroa.store.elt89 = lshr i64 %69, 32 ; <i64> [#uses=1]
- %71 = trunc i64 %sroa.store.elt89 to i32 ; <i32> [#uses=3]
- %tmp92 = inttoptr i32 %70 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=7]
- call void @_ZNK4llvm6SDNode4dumpEv(%"struct.llvm::SDNode"* %tmp92) nounwind
- %72 = getelementptr %"struct.llvm::MVT"* %VT1.i174, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 0, i32* %72, align 8
- %73 = getelementptr %"struct.llvm::MVT"* %VT2.i173, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 12, i32* %73, align 8
- %74 = call i64 @_ZN4llvm12SelectionDAG9getVTListENS_3MVTES1_(%"struct.llvm::SelectionDAG"* %DAG, %"struct.llvm::MVT"* byval align 4 %VT1.i174, %"struct.llvm::MVT"* byval align 4 %VT2.i173) nounwind ; <i64> [#uses=1]
- %75 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i175, i32 0, i32 0, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp92, %"struct.llvm::SDNode"** %75, align 8
- %76 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i175, i32 0, i32 0, i32 1 ; <i32*> [#uses=1]
- store i32 1, i32* %76, align 4
- %77 = getelementptr %"struct.llvm::SDNode"* %tmp92, i32 0, i32 9 ; <i16*> [#uses=1]
- %78 = load i16* %77, align 2 ; <i16> [#uses=1]
- %79 = zext i16 %78 to i32 ; <i32> [#uses=1]
- %80 = icmp ugt i32 %79, %71 ; <i1> [#uses=1]
- br i1 %80, label %_ZN4llvm12SelectionDAG12getCopyToRegENS_7SDValueENS_8DebugLocEjS1_S1_.exit, label %bb.i.i.i
-
-bb.i.i.i: ; preds = %_ZNK4llvm6SDNode12getValueTypeEj.exit
- call void @__assert_rtn(i8* getelementptr ([13 x i8]* @_ZZNK4llvm6SDNode12getValueTypeEjE8__func__, i32 0, i32 0), i8* getelementptr ([65 x i8]* @"\01LC81", i32 0, i32 0), i32 1314, i8* getelementptr ([46 x i8]* @"\01LC83", i32 0, i32 0)) noreturn nounwind
- unreachable
-
-_ZN4llvm12SelectionDAG12getCopyToRegENS_7SDValueENS_8DebugLocEjS1_S1_.exit: ; preds = %_ZNK4llvm6SDNode12getValueTypeEj.exit
- %81 = trunc i64 %74 to i32 ; <i32> [#uses=1]
- %tmp4.i.i176 = inttoptr i32 %81 to %"struct.llvm::MVT"* ; <%"struct.llvm::MVT"*> [#uses=1]
- %82 = getelementptr %"struct.llvm::SDNode"* %tmp92, i32 0, i32 6 ; <%"struct.llvm::MVT"**> [#uses=1]
- %83 = load %"struct.llvm::MVT"** %82, align 4 ; <%"struct.llvm::MVT"*> [#uses=1]
- %84 = getelementptr %"struct.llvm::MVT"* %83, i32 %71, i32 0, i32 0 ; <i32*> [#uses=1]
- %85 = load i32* %84, align 4 ; <i32> [#uses=1]
- %86 = getelementptr %"struct.llvm::MVT"* %1, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 %85, i32* %86, align 8
- %87 = call i64 @_ZN4llvm12SelectionDAG11getRegisterEjNS_3MVTE(%"struct.llvm::SelectionDAG"* %DAG, i32 17, %"struct.llvm::MVT"* byval align 4 %1) nounwind ; <i64> [#uses=2]
- %88 = trunc i64 %87 to i32 ; <i32> [#uses=1]
- %sroa.store.elt.i177 = lshr i64 %87, 32 ; <i64> [#uses=1]
- %89 = trunc i64 %sroa.store.elt.i177 to i32 ; <i32> [#uses=1]
- %90 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i175, i32 0, i32 1, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- %tmp5.i178 = inttoptr i32 %88 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp5.i178, %"struct.llvm::SDNode"** %90, align 8
- %91 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i175, i32 0, i32 1, i32 1 ; <i32*> [#uses=1]
- store i32 %89, i32* %91, align 4
- %92 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i175, i32 0, i32 2, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp92, %"struct.llvm::SDNode"** %92, align 8
- %93 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i175, i32 0, i32 2, i32 1 ; <i32*> [#uses=1]
- store i32 %71, i32* %93, align 4
- %94 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i175, i32 0, i32 3, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp92, %"struct.llvm::SDNode"** %94, align 8
- %95 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i175, i32 0, i32 3, i32 1 ; <i32*> [#uses=1]
- store i32 2, i32* %95, align 4
- %96 = icmp eq %"struct.llvm::SDNode"* %tmp92, null ; <i1> [#uses=1]
- %iftmp.583.0.i = select i1 %96, i32 3, i32 4 ; <i32> [#uses=1]
- %97 = getelementptr [4 x %"struct.llvm::SDValue"]* %Ops.i175, i32 0, i32 0 ; <%"struct.llvm::SDValue"*> [#uses=1]
- %98 = call i64 @_ZN4llvm12SelectionDAG7getNodeEjNS_8DebugLocEPKNS_3MVTEjPKNS_7SDValueEj(%"struct.llvm::SelectionDAG"* %DAG, i32 36, i32 %7, %"struct.llvm::MVT"* %tmp4.i.i176, i32 2, %"struct.llvm::SDValue"* %97, i32 %iftmp.583.0.i) nounwind ; <i64> [#uses=2]
- %99 = trunc i64 %98 to i32 ; <i32> [#uses=1]
- %sroa.store.elt107 = lshr i64 %98, 32 ; <i64> [#uses=1]
- %100 = trunc i64 %sroa.store.elt107 to i32 ; <i32> [#uses=1]
- %tmp110 = inttoptr i32 %99 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=2]
- %101 = getelementptr %"struct.llvm::MVT"* %3, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 12, i32* %101, align 8
- %102 = getelementptr %"struct.llvm::MVT"* %2, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 0, i32* %102, align 8
- %103 = call i64 @_ZN4llvm12SelectionDAG9getVTListENS_3MVTES1_(%"struct.llvm::SelectionDAG"* %DAG, %"struct.llvm::MVT"* byval align 4 %2, %"struct.llvm::MVT"* byval align 4 %3) nounwind ; <i64> [#uses=2]
- %104 = trunc i64 %103 to i32 ; <i32> [#uses=1]
- %sroa.store.elt119 = lshr i64 %103, 32 ; <i64> [#uses=1]
- %105 = trunc i64 %sroa.store.elt119 to i16 ; <i16> [#uses=1]
- %tmp122 = inttoptr i32 %104 to %"struct.llvm::MVT"* ; <%"struct.llvm::MVT"*> [#uses=1]
- store %"struct.llvm::MVT"* %tmp122, %"struct.llvm::MVT"** %44, align 8
- store i16 %105, i16* %45, align 4
- %106 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 0, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp110, %"struct.llvm::SDNode"** %106, align 8
- %107 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 0, i32 1 ; <i32*> [#uses=1]
- store i32 %100, i32* %107, align 4
- %108 = call i64 @_ZN4llvm12SelectionDAG23getTargetExternalSymbolEPKcNS_3MVTE(%"struct.llvm::SelectionDAG"* %DAG, i8* getelementptr ([16 x i8]* @"\01LC197", i32 0, i32 0), %"struct.llvm::MVT"* byval align 4 %PtrVT) nounwind ; <i64> [#uses=2]
- %109 = trunc i64 %108 to i32 ; <i32> [#uses=1]
- %sroa.store.elt125 = lshr i64 %108, 32 ; <i64> [#uses=1]
- %110 = trunc i64 %sroa.store.elt125 to i32 ; <i32> [#uses=1]
- %111 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 1, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- %tmp128 = inttoptr i32 %109 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp128, %"struct.llvm::SDNode"** %111, align 8
- %112 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 1, i32 1 ; <i32*> [#uses=1]
- store i32 %110, i32* %112, align 4
- %113 = call i64 @_ZN4llvm12SelectionDAG11getRegisterEjNS_3MVTE(%"struct.llvm::SelectionDAG"* %DAG, i32 17, %"struct.llvm::MVT"* byval align 4 %PtrVT) nounwind ; <i64> [#uses=2]
- %114 = trunc i64 %113 to i32 ; <i32> [#uses=1]
- %sroa.store.elt131 = lshr i64 %113, 32 ; <i64> [#uses=1]
- %115 = trunc i64 %sroa.store.elt131 to i32 ; <i32> [#uses=1]
- %116 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 2, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- %tmp134 = inttoptr i32 %114 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp134, %"struct.llvm::SDNode"** %116, align 8
- %117 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 2, i32 1 ; <i32*> [#uses=1]
- store i32 %115, i32* %117, align 4
- %118 = call i64 @_ZN4llvm12SelectionDAG11getRegisterEjNS_3MVTE(%"struct.llvm::SelectionDAG"* %DAG, i32 19, %"struct.llvm::MVT"* byval align 4 %PtrVT) nounwind ; <i64> [#uses=2]
- %119 = trunc i64 %118 to i32 ; <i32> [#uses=1]
- %sroa.store.elt137 = lshr i64 %118, 32 ; <i64> [#uses=1]
- %120 = trunc i64 %sroa.store.elt137 to i32 ; <i32> [#uses=1]
- %121 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 3, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- %tmp140 = inttoptr i32 %119 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp140, %"struct.llvm::SDNode"** %121, align 8
- %122 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 3, i32 1 ; <i32*> [#uses=1]
- store i32 %120, i32* %122, align 4
- %123 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 4, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp110, %"struct.llvm::SDNode"** %123, align 8
- %124 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 4, i32 1 ; <i32*> [#uses=1]
- store i32 1, i32* %124, align 4
- %125 = getelementptr [5 x %"struct.llvm::SDValue"]* %Ops1, i32 0, i32 0 ; <%"struct.llvm::SDValue"*> [#uses=1]
- %126 = call i64 @_ZN4llvm12SelectionDAG7getNodeEjNS_8DebugLocENS_8SDVTListEPKNS_7SDValueEj(%"struct.llvm::SelectionDAG"* %DAG, i32 195, i32 %7, %"struct.llvm::SDVTList"* byval align 4 %NodeTys, %"struct.llvm::SDValue"* %125, i32 5) nounwind ; <i64> [#uses=2]
- %127 = trunc i64 %126 to i32 ; <i32> [#uses=1]
- %sroa.store.elt143 = lshr i64 %126, 32 ; <i64> [#uses=1]
- %128 = trunc i64 %sroa.store.elt143 to i32 ; <i32> [#uses=1]
- %tmp146 = inttoptr i32 %127 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=3]
- %tmp171195 = getelementptr %"struct.llvm::MVT"* %PtrVT, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- %tmp197 = load i32* %tmp171195, align 1 ; <i32> [#uses=2]
- %129 = getelementptr %"struct.llvm::MVT"* %VT, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 %tmp197, i32* %129, align 8
- %130 = getelementptr %"struct.llvm::MVT"* %VT1.i, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 %tmp197, i32* %130, align 8
- %131 = getelementptr %"struct.llvm::MVT"* %VT2.i, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 0, i32* %131, align 8
- %132 = getelementptr %"struct.llvm::MVT"* %VT3.i, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 12, i32* %132, align 8
- %133 = call i64 @_ZN4llvm12SelectionDAG9getVTListENS_3MVTES1_S1_(%"struct.llvm::SelectionDAG"* %DAG, %"struct.llvm::MVT"* byval align 4 %VT1.i, %"struct.llvm::MVT"* byval align 4 %VT2.i, %"struct.llvm::MVT"* byval align 4 %VT3.i) nounwind ; <i64> [#uses=1]
- %134 = trunc i64 %133 to i32 ; <i32> [#uses=1]
- %tmp4.i.i = inttoptr i32 %134 to %"struct.llvm::MVT"* ; <%"struct.llvm::MVT"*> [#uses=1]
- %135 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops.i, i32 0, i32 0, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp146, %"struct.llvm::SDNode"** %135, align 8
- %136 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops.i, i32 0, i32 0, i32 1 ; <i32*> [#uses=1]
- store i32 %128, i32* %136, align 4
- %137 = call i64 @_ZN4llvm12SelectionDAG11getRegisterEjNS_3MVTE(%"struct.llvm::SelectionDAG"* %DAG, i32 17, %"struct.llvm::MVT"* byval align 4 %VT) nounwind ; <i64> [#uses=2]
- %138 = trunc i64 %137 to i32 ; <i32> [#uses=1]
- %sroa.store.elt.i = lshr i64 %137, 32 ; <i64> [#uses=1]
- %139 = trunc i64 %sroa.store.elt.i to i32 ; <i32> [#uses=1]
- %140 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops.i, i32 0, i32 1, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- %tmp5.i = inttoptr i32 %138 to %"struct.llvm::SDNode"* ; <%"struct.llvm::SDNode"*> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp5.i, %"struct.llvm::SDNode"** %140, align 8
- %141 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops.i, i32 0, i32 1, i32 1 ; <i32*> [#uses=1]
- store i32 %139, i32* %141, align 4
- %142 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops.i, i32 0, i32 2, i32 0 ; <%"struct.llvm::SDNode"**> [#uses=1]
- store %"struct.llvm::SDNode"* %tmp146, %"struct.llvm::SDNode"** %142, align 8
- %143 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops.i, i32 0, i32 2, i32 1 ; <i32*> [#uses=1]
- store i32 1, i32* %143, align 4
- %144 = icmp eq %"struct.llvm::SDNode"* %tmp146, null ; <i1> [#uses=1]
- %iftmp.588.0.i = select i1 %144, i32 2, i32 3 ; <i32> [#uses=1]
- %145 = getelementptr [3 x %"struct.llvm::SDValue"]* %Ops.i, i32 0, i32 0 ; <%"struct.llvm::SDValue"*> [#uses=1]
- %146 = call i64 @_ZN4llvm12SelectionDAG7getNodeEjNS_8DebugLocEPKNS_3MVTEjPKNS_7SDValueEj(%"struct.llvm::SelectionDAG"* %DAG, i32 37, i32 %7, %"struct.llvm::MVT"* %tmp4.i.i, i32 3, %"struct.llvm::SDValue"* %145, i32 %iftmp.588.0.i) nounwind ; <i64> [#uses=1]
- ret i64 %146
-}
-
-declare void @__assert_rtn(i8*, i8*, i32, i8*) noreturn
-
-declare i64 @_ZN4llvm12SelectionDAG16getGlobalAddressEPKNS_11GlobalValueENS_3MVTExb(%"struct.llvm::SelectionDAG"*, %"struct.llvm::GlobalValue"*, %"struct.llvm::MVT"* byval align 4, i64, i8 zeroext)
-
-declare i64 @_ZN4llvm12SelectionDAG9getVTListENS_3MVTES1_(%"struct.llvm::SelectionDAG"*, %"struct.llvm::MVT"* byval align 4, %"struct.llvm::MVT"* byval align 4)
-
-declare i64 @_ZN4llvm12SelectionDAG7getNodeEjNS_8DebugLocENS_8SDVTListEPKNS_7SDValueEj(%"struct.llvm::SelectionDAG"*, i32, i32, %"struct.llvm::SDVTList"* byval align 4, %"struct.llvm::SDValue"*, i32)
-
-declare i64 @_ZN4llvm12SelectionDAG11getRegisterEjNS_3MVTE(%"struct.llvm::SelectionDAG"*, i32, %"struct.llvm::MVT"* byval align 4)
-
-declare i64 @_ZN4llvm12SelectionDAG7getNodeEjNS_8DebugLocEPKNS_3MVTEjPKNS_7SDValueEj(%"struct.llvm::SelectionDAG"*, i32, i32, %"struct.llvm::MVT"*, i32, %"struct.llvm::SDValue"*, i32)
-
-declare i64 @_ZN4llvm12SelectionDAG9getVTListENS_3MVTES1_S1_(%"struct.llvm::SelectionDAG"*, %"struct.llvm::MVT"* byval align 4, %"struct.llvm::MVT"* byval align 4, %"struct.llvm::MVT"* byval align 4)
-
-declare i64 @_ZN4llvm12SelectionDAG23getTargetExternalSymbolEPKcNS_3MVTE(%"struct.llvm::SelectionDAG"*, i8*, %"struct.llvm::MVT"* byval align 4)
-
-declare i64 @_ZN4llvm12SelectionDAG7getNodeEjNS_8DebugLocENS_3MVTE(%"struct.llvm::SelectionDAG"*, i32, i32, %"struct.llvm::MVT"* byval align 4)
-
-declare void @_ZNK4llvm6SDNode4dumpEv(%"struct.llvm::SDNode"*)
diff --git a/test/CodeGen/X86/2009-04-21-NoReloadImpDef.ll b/test/CodeGen/X86/2009-04-21-NoReloadImpDef.ll
index 5bd956a..abbe97a 100644
--- a/test/CodeGen/X86/2009-04-21-NoReloadImpDef.ll
+++ b/test/CodeGen/X86/2009-04-21-NoReloadImpDef.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=i386-apple-darwin10.0 -relocation-model=pic \
+; RUN: llc -mtriple=i386-apple-darwin10.0 -relocation-model=pic -asm-verbose=false \
; RUN: -disable-fp-elim -mattr=-sse41,-sse3,+sse2 -post-RA-scheduler=false < %s | \
; RUN: FileCheck %s
; rdar://6808032
diff --git a/test/CodeGen/X86/2009-09-07-CoalescerBug.ll b/test/CodeGen/X86/2009-09-07-CoalescerBug.ll
index 55432be..a5b4a79 100644
--- a/test/CodeGen/X86/2009-09-07-CoalescerBug.ll
+++ b/test/CodeGen/X86/2009-09-07-CoalescerBug.ll
@@ -8,8 +8,8 @@
define i64 @hammer_time(i64 %modulep, i64 %physfree) nounwind ssp noredzone noimplicitfloat {
; CHECK: hammer_time:
; CHECK: movq $Xrsvd, %rax
+; CHECK: movq $Xrsvd, %rsi
; CHECK: movq $Xrsvd, %rdi
-; CHECK: movq $Xrsvd, %r8
entry:
br i1 undef, label %if.then, label %if.end
diff --git a/test/CodeGen/X86/2009-09-10-LoadFoldingBug.ll b/test/CodeGen/X86/2009-09-10-LoadFoldingBug.ll
index 9e58872..7b5e871 100644
--- a/test/CodeGen/X86/2009-09-10-LoadFoldingBug.ll
+++ b/test/CodeGen/X86/2009-09-10-LoadFoldingBug.ll
@@ -13,7 +13,6 @@ define i32 @t(i32 %clientPort, i32 %pluginID, i32 %requestID, i32 %objectID, i64
entry:
; CHECK: _t:
; CHECK: movl 16(%rbp),
-; CHECK: movl 16(%rbp), %edx
%0 = zext i32 %argumentsLength to i64 ; <i64> [#uses=1]
%1 = zext i32 %clientPort to i64 ; <i64> [#uses=1]
%2 = inttoptr i64 %1 to %struct.ComplexType* ; <%struct.ComplexType*> [#uses=1]
diff --git a/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll b/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll
index 628b899..b5be65f 100644
--- a/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll
+++ b/test/CodeGen/X86/2009-11-04-SubregCoalescingBug.ll
@@ -5,7 +5,7 @@ define void @bar(i32 %b, i32 %a) nounwind optsize ssp {
entry:
; CHECK: leal 15(%rsi), %edi
; CHECK-NOT: movl
-; CHECK: callq _foo
+; CHECK: _foo
%0 = add i32 %a, 15 ; <i32> [#uses=1]
%1 = zext i32 %0 to i64 ; <i64> [#uses=1]
tail call void @foo(i64 %1) nounwind
diff --git a/test/CodeGen/X86/2010-02-01-TaillCallCrash.ll b/test/CodeGen/X86/2010-02-01-TaillCallCrash.ll
new file mode 100644
index 0000000..2751174
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-01-TaillCallCrash.ll
@@ -0,0 +1,12 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu
+; PR6196
+
+%"char[]" = type [1 x i8]
+
+@.str = external constant %"char[]", align 1 ; <%"char[]"*> [#uses=1]
+
+define i32 @regex_subst() nounwind {
+entry:
+ %0 = tail call i32 bitcast (%"char[]"* @.str to i32 (i32)*)(i32 0) nounwind ; <i32> [#uses=1]
+ ret i32 %0
+}
diff --git a/test/CodeGen/X86/2010-02-03-DualUndef.ll b/test/CodeGen/X86/2010-02-03-DualUndef.ll
new file mode 100644
index 0000000..d116ecc
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-03-DualUndef.ll
@@ -0,0 +1,27 @@
+; RUN: llc < %s -march=x86-64
+; PR6086
+define fastcc void @prepOutput() nounwind {
+bb: ; preds = %output.exit
+ br label %bb.i1
+
+bb.i1: ; preds = %bb7.i, %bb
+ br i1 undef, label %bb7.i, label %bb.nph.i
+
+bb.nph.i: ; preds = %bb.i1
+ br label %bb3.i
+
+bb3.i: ; preds = %bb5.i6, %bb.nph.i
+ %tmp10.i = trunc i64 undef to i32 ; <i32> [#uses=1]
+ br i1 undef, label %bb4.i, label %bb5.i6
+
+bb4.i: ; preds = %bb3.i
+ br label %bb5.i6
+
+bb5.i6: ; preds = %bb4.i, %bb3.i
+ %0 = phi i32 [ undef, %bb4.i ], [ undef, %bb3.i ] ; <i32> [#uses=1]
+ %1 = icmp slt i32 %0, %tmp10.i ; <i1> [#uses=1]
+ br i1 %1, label %bb7.i, label %bb3.i
+
+bb7.i: ; preds = %bb5.i6, %bb.i1
+ br label %bb.i1
+}
diff --git a/test/CodeGen/X86/2010-02-04-SchedulerBug.ll b/test/CodeGen/X86/2010-02-04-SchedulerBug.ll
new file mode 100644
index 0000000..c966e21
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-04-SchedulerBug.ll
@@ -0,0 +1,28 @@
+; RUN: llc < %s -mtriple=i386-apple-darwin11
+; rdar://7604000
+
+%struct.a_t = type { i8*, i64*, i8*, i32, i32, i64*, i64*, i64* }
+%struct.b_t = type { i32, i32, i32, i32, i64, i64, i64, i64 }
+
+define void @t(i32 %cNum, i64 %max) nounwind optsize ssp noimplicitfloat {
+entry:
+ %0 = load %struct.b_t** null, align 4 ; <%struct.b_t*> [#uses=1]
+ %1 = getelementptr inbounds %struct.b_t* %0, i32 %cNum, i32 5 ; <i64*> [#uses=1]
+ %2 = load i64* %1, align 4 ; <i64> [#uses=1]
+ %3 = icmp ult i64 %2, %max ; <i1> [#uses=1]
+ %4 = getelementptr inbounds %struct.a_t* null, i32 0, i32 7 ; <i64**> [#uses=1]
+ %5 = load i64** %4, align 4 ; <i64*> [#uses=0]
+ %6 = load i64* null, align 4 ; <i64> [#uses=1]
+ br i1 %3, label %bb2, label %bb
+
+bb: ; preds = %entry
+ br label %bb3
+
+bb2: ; preds = %entry
+ %7 = or i64 %6, undef ; <i64> [#uses=1]
+ br label %bb3
+
+bb3: ; preds = %bb2, %bb
+ %misc_enables.0 = phi i64 [ undef, %bb ], [ %7, %bb2 ] ; <i64> [#uses=0]
+ ret void
+}
diff --git a/test/CodeGen/X86/2010-02-12-CoalescerBug-Impdef.ll b/test/CodeGen/X86/2010-02-12-CoalescerBug-Impdef.ll
new file mode 100644
index 0000000..c5d3d16
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-12-CoalescerBug-Impdef.ll
@@ -0,0 +1,260 @@
+; RUN: llc < %s > %t
+; PR6283
+
+; Tricky coalescer bug:
+; After coalescing %RAX with a virtual register, this instruction was rematted:
+;
+; %EAX<def> = MOV32rr %reg1070<kill>
+;
+; This instruction silently defined %RAX, and when rematting removed the
+; instruction, the live interval for %RAX was not properly updated. The valno
+; referred to a deleted instruction and bad things happened.
+;
+; The fix is to implicitly define %RAX when coalescing:
+;
+; %EAX<def> = MOV32rr %reg1070<kill>, %RAX<imp-def>
+;
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+module asm "\09.ident\09\22GCC: (GNU) 4.5.0 20100212 (experimental) LLVM: 95975\22"
+
+%0 = type { %"union gimple_statement_d"* }
+%"BITMAP_WORD[]" = type [2 x i64]
+%"char[]" = type [4 x i8]
+%"enum dom_state[]" = type [2 x i32]
+%"int[]" = type [4 x i32]
+%"struct VEC_basic_block_base" = type { i32, i32, [1 x %"struct basic_block_def"*] }
+%"struct VEC_basic_block_gc" = type { %"struct VEC_basic_block_base" }
+%"struct VEC_edge_base" = type { i32, i32, [1 x %"struct edge_def"*] }
+%"struct VEC_edge_gc" = type { %"struct VEC_edge_base" }
+%"struct VEC_gimple_base" = type { i32, i32, [1 x %"union gimple_statement_d"*] }
+%"struct VEC_gimple_gc" = type { %"struct VEC_gimple_base" }
+%"struct VEC_iv_cand_p_base" = type { i32, i32, [1 x %"struct iv_cand"*] }
+%"struct VEC_iv_cand_p_heap" = type { %"struct VEC_iv_cand_p_base" }
+%"struct VEC_iv_use_p_base" = type { i32, i32, [1 x %"struct iv_use"*] }
+%"struct VEC_iv_use_p_heap" = type { %"struct VEC_iv_use_p_base" }
+%"struct VEC_loop_p_base" = type { i32, i32, [1 x %"struct loop"*] }
+%"struct VEC_loop_p_gc" = type { %"struct VEC_loop_p_base" }
+%"struct VEC_rtx_base" = type { i32, i32, [1 x %"struct rtx_def"*] }
+%"struct VEC_rtx_gc" = type { %"struct VEC_rtx_base" }
+%"struct VEC_tree_base" = type { i32, i32, [1 x %"union tree_node"*] }
+%"struct VEC_tree_gc" = type { %"struct VEC_tree_base" }
+%"struct _obstack_chunk" = type { i8*, %"struct _obstack_chunk"*, %"char[]" }
+%"struct basic_block_def" = type { %"struct VEC_edge_gc"*, %"struct VEC_edge_gc"*, i8*, %"struct loop"*, [2 x %"struct et_node"*], %"struct basic_block_def"*, %"struct basic_block_def"*, %"union basic_block_il_dependent", i64, i32, i32, i32, i32, i32 }
+%"struct bitmap_element" = type { %"struct bitmap_element"*, %"struct bitmap_element"*, i32, %"BITMAP_WORD[]" }
+%"struct bitmap_head_def" = type { %"struct bitmap_element"*, %"struct bitmap_element"*, i32, %"struct bitmap_obstack"* }
+%"struct bitmap_obstack" = type { %"struct bitmap_element"*, %"struct bitmap_head_def"*, %"struct obstack" }
+%"struct block_symbol" = type { [3 x %"union rtunion"], %"struct object_block"*, i64 }
+%"struct comp_cost" = type { i32, i32 }
+%"struct control_flow_graph" = type { %"struct basic_block_def"*, %"struct basic_block_def"*, %"struct VEC_basic_block_gc"*, i32, i32, i32, %"struct VEC_basic_block_gc"*, i32, %"enum dom_state[]", %"enum dom_state[]", i32, i32 }
+%"struct cost_pair" = type { %"struct iv_cand"*, %"struct comp_cost", %"struct bitmap_head_def"*, %"union tree_node"* }
+%"struct def_optype_d" = type { %"struct def_optype_d"*, %"union tree_node"** }
+%"struct double_int" = type { i64, i64 }
+%"struct edge_def" = type { %"struct basic_block_def"*, %"struct basic_block_def"*, %"union edge_def_insns", i8*, %"union tree_node"*, i32, i32, i32, i32, i64 }
+%"struct eh_status" = type opaque
+%"struct et_node" = type opaque
+%"struct function" = type { %"struct eh_status"*, %"struct control_flow_graph"*, %"struct gimple_seq_d"*, %"struct gimple_df"*, %"struct loops"*, %"struct htab"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"struct machine_function"*, %"struct language_function"*, %"struct htab"*, i32, i32, i32, i32, i32, i32, i8*, i8, i8, i8, i8 }
+%"struct gimple_bb_info" = type { %"struct gimple_seq_d"*, %"struct gimple_seq_d"* }
+%"struct gimple_df" = type { %"struct htab"*, %"struct VEC_gimple_gc"*, %"struct VEC_tree_gc"*, %"union tree_node"*, %"struct pt_solution", %"struct pt_solution", %"struct pointer_map_t"*, %"union tree_node"*, %"struct htab"*, %"struct bitmap_head_def"*, i8, %"struct ssa_operands" }
+%"struct gimple_seq_d" = type { %"struct gimple_seq_node_d"*, %"struct gimple_seq_node_d"*, %"struct gimple_seq_d"* }
+%"struct gimple_seq_node_d" = type { %"union gimple_statement_d"*, %"struct gimple_seq_node_d"*, %"struct gimple_seq_node_d"* }
+%"struct gimple_statement_base" = type { i8, i8, i16, i32, i32, i32, %"struct basic_block_def"*, %"union tree_node"* }
+%"struct gimple_statement_phi" = type { %"struct gimple_statement_base", i32, i32, %"union tree_node"*, %"struct phi_arg_d[]" }
+%"struct htab" = type { i32 (i8*)*, i32 (i8*, i8*)*, void (i8*)*, i8**, i64, i64, i64, i32, i32, i8* (i64, i64)*, void (i8*)*, i8*, i8* (i8*, i64, i64)*, void (i8*, i8*)*, i32 }
+%"struct iv" = type { %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, i8, i8, i32 }
+%"struct iv_cand" = type { i32, i8, i32, %"union gimple_statement_d"*, %"union tree_node"*, %"union tree_node"*, %"struct iv"*, i32, i32, %"struct iv_use"*, %"struct bitmap_head_def"* }
+%"struct iv_use" = type { i32, i32, %"struct iv"*, %"union gimple_statement_d"*, %"union tree_node"**, %"struct bitmap_head_def"*, i32, %"struct cost_pair"*, %"struct iv_cand"* }
+%"struct ivopts_data" = type { %"struct loop"*, %"struct pointer_map_t"*, i32, i32, %"struct version_info"*, %"struct bitmap_head_def"*, %"struct VEC_iv_use_p_heap"*, %"struct VEC_iv_cand_p_heap"*, %"struct bitmap_head_def"*, i32, i8, i8 }
+%"struct lang_decl" = type opaque
+%"struct language_function" = type opaque
+%"struct loop" = type { i32, i32, %"struct basic_block_def"*, %"struct basic_block_def"*, %"struct comp_cost", i32, i32, %"struct VEC_loop_p_gc"*, %"struct loop"*, %"struct loop"*, i8*, %"union tree_node"*, %"struct double_int", %"struct double_int", i8, i8, i32, %"struct nb_iter_bound"*, %"struct loop_exit"*, i8, %"union tree_node"* }
+%"struct loop_exit" = type { %"struct edge_def"*, %"struct loop_exit"*, %"struct loop_exit"*, %"struct loop_exit"* }
+%"struct loops" = type { i32, %"struct VEC_loop_p_gc"*, %"struct htab"*, %"struct loop"* }
+%"struct machine_cfa_state" = type { %"struct rtx_def"*, i64 }
+%"struct machine_function" = type { %"struct stack_local_entry"*, i8*, i32, i32, %"int[]", i32, %"struct machine_cfa_state", i32, i8 }
+%"struct nb_iter_bound" = type { %"union gimple_statement_d"*, %"struct double_int", i8, %"struct nb_iter_bound"* }
+%"struct object_block" = type { %"union section"*, i32, i64, %"struct VEC_rtx_gc"*, %"struct VEC_rtx_gc"* }
+%"struct obstack" = type { i64, %"struct _obstack_chunk"*, i8*, i8*, i8*, i64, i32, %"struct _obstack_chunk"* (i8*, i64)*, void (i8*, %"struct _obstack_chunk"*)*, i8*, i8 }
+%"struct phi_arg_d" = type { %"struct ssa_use_operand_d", %"union tree_node"*, i32 }
+%"struct phi_arg_d[]" = type [1 x %"struct phi_arg_d"]
+%"struct pointer_map_t" = type opaque
+%"struct pt_solution" = type { i8, %"struct bitmap_head_def"* }
+%"struct rtx_def" = type { i16, i8, i8, %"union u" }
+%"struct section_common" = type { i32 }
+%"struct ssa_operand_memory_d" = type { %"struct ssa_operand_memory_d"*, %"uchar[]" }
+%"struct ssa_operands" = type { %"struct ssa_operand_memory_d"*, i32, i32, i8, %"struct def_optype_d"*, %"struct use_optype_d"* }
+%"struct ssa_use_operand_d" = type { %"struct ssa_use_operand_d"*, %"struct ssa_use_operand_d"*, %0, %"union tree_node"** }
+%"struct stack_local_entry" = type opaque
+%"struct tree_base" = type <{ i16, i8, i8, i8, [2 x i8], i8 }>
+%"struct tree_common" = type { %"struct tree_base", %"union tree_node"*, %"union tree_node"* }
+%"struct tree_decl_common" = type { %"struct tree_decl_minimal", %"union tree_node"*, i8, i8, i8, i8, i8, i32, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"struct lang_decl"* }
+%"struct tree_decl_minimal" = type { %"struct tree_common", i32, i32, %"union tree_node"*, %"union tree_node"* }
+%"struct tree_decl_non_common" = type { %"struct tree_decl_with_vis", %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"* }
+%"struct tree_decl_with_rtl" = type { %"struct tree_decl_common", %"struct rtx_def"* }
+%"struct tree_decl_with_vis" = type { %"struct tree_decl_with_rtl", %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, i8, i8, i8 }
+%"struct tree_function_decl" = type { %"struct tree_decl_non_common", %"struct function"*, %"union tree_node"*, %"union tree_node"*, %"union tree_node"*, i16, i8, i8 }
+%"struct unnamed_section" = type { %"struct section_common", void (i8*)*, i8*, %"union section"* }
+%"struct use_optype_d" = type { %"struct use_optype_d"*, %"struct ssa_use_operand_d" }
+%"struct version_info" = type { %"union tree_node"*, %"struct iv"*, i8, i32, i8 }
+%"uchar[]" = type [1 x i8]
+%"union basic_block_il_dependent" = type { %"struct gimple_bb_info"* }
+%"union edge_def_insns" = type { %"struct gimple_seq_d"* }
+%"union gimple_statement_d" = type { %"struct gimple_statement_phi" }
+%"union rtunion" = type { i8* }
+%"union section" = type { %"struct unnamed_section" }
+%"union tree_node" = type { %"struct tree_function_decl" }
+%"union u" = type { %"struct block_symbol" }
+
+declare fastcc %"union tree_node"* @get_computation_at(%"struct loop"*, %"struct iv_use"* nocapture, %"struct iv_cand"* nocapture, %"union gimple_statement_d"*) nounwind
+
+declare fastcc i32 @computation_cost(%"union tree_node"*, i8 zeroext) nounwind
+
+define fastcc i64 @get_computation_cost_at(%"struct ivopts_data"* %data, %"struct iv_use"* nocapture %use, %"struct iv_cand"* nocapture %cand, i8 zeroext %address_p, %"struct bitmap_head_def"** %depends_on, %"union gimple_statement_d"* %at, i8* %can_autoinc) nounwind {
+entry:
+ br i1 undef, label %"100", label %"4"
+
+"4": ; preds = %entry
+ br i1 undef, label %"6", label %"5"
+
+"5": ; preds = %"4"
+ unreachable
+
+"6": ; preds = %"4"
+ br i1 undef, label %"8", label %"7"
+
+"7": ; preds = %"6"
+ unreachable
+
+"8": ; preds = %"6"
+ br i1 undef, label %"100", label %"10"
+
+"10": ; preds = %"8"
+ br i1 undef, label %"17", label %"16"
+
+"16": ; preds = %"10"
+ unreachable
+
+"17": ; preds = %"10"
+ br i1 undef, label %"19", label %"18"
+
+"18": ; preds = %"17"
+ unreachable
+
+"19": ; preds = %"17"
+ br i1 undef, label %"93", label %"20"
+
+"20": ; preds = %"19"
+ br i1 undef, label %"23", label %"21"
+
+"21": ; preds = %"20"
+ unreachable
+
+"23": ; preds = %"20"
+ br i1 undef, label %"100", label %"25"
+
+"25": ; preds = %"23"
+ br i1 undef, label %"100", label %"26"
+
+"26": ; preds = %"25"
+ br i1 undef, label %"30", label %"28"
+
+"28": ; preds = %"26"
+ unreachable
+
+"30": ; preds = %"26"
+ br i1 undef, label %"59", label %"51"
+
+"51": ; preds = %"30"
+ br i1 undef, label %"55", label %"52"
+
+"52": ; preds = %"51"
+ unreachable
+
+"55": ; preds = %"51"
+ %0 = icmp ugt i32 0, undef ; <i1> [#uses=1]
+ br i1 %0, label %"50.i", label %"9.i"
+
+"9.i": ; preds = %"55"
+ unreachable
+
+"50.i": ; preds = %"55"
+ br i1 undef, label %"55.i", label %"54.i"
+
+"54.i": ; preds = %"50.i"
+ br i1 undef, label %"57.i", label %"55.i"
+
+"55.i": ; preds = %"54.i", %"50.i"
+ unreachable
+
+"57.i": ; preds = %"54.i"
+ br label %"63.i"
+
+"61.i": ; preds = %"63.i"
+ br i1 undef, label %"64.i", label %"62.i"
+
+"62.i": ; preds = %"61.i"
+ br label %"63.i"
+
+"63.i": ; preds = %"62.i", %"57.i"
+ br i1 undef, label %"61.i", label %"64.i"
+
+"64.i": ; preds = %"63.i", %"61.i"
+ unreachable
+
+"59": ; preds = %"30"
+ br i1 undef, label %"60", label %"82"
+
+"60": ; preds = %"59"
+ br i1 undef, label %"61", label %"82"
+
+"61": ; preds = %"60"
+ br i1 undef, label %"62", label %"82"
+
+"62": ; preds = %"61"
+ br i1 undef, label %"100", label %"63"
+
+"63": ; preds = %"62"
+ br i1 undef, label %"65", label %"64"
+
+"64": ; preds = %"63"
+ unreachable
+
+"65": ; preds = %"63"
+ br i1 undef, label %"66", label %"67"
+
+"66": ; preds = %"65"
+ unreachable
+
+"67": ; preds = %"65"
+ %1 = load i32* undef, align 4 ; <i32> [#uses=0]
+ br label %"100"
+
+"82": ; preds = %"61", %"60", %"59"
+ unreachable
+
+"93": ; preds = %"19"
+ %2 = call fastcc %"union tree_node"* @get_computation_at(%"struct loop"* undef, %"struct iv_use"* %use, %"struct iv_cand"* %cand, %"union gimple_statement_d"* %at) nounwind ; <%"union tree_node"*> [#uses=1]
+ br i1 undef, label %"100", label %"97"
+
+"97": ; preds = %"93"
+ br i1 undef, label %"99", label %"98"
+
+"98": ; preds = %"97"
+ br label %"99"
+
+"99": ; preds = %"98", %"97"
+ %3 = phi %"union tree_node"* [ undef, %"98" ], [ %2, %"97" ] ; <%"union tree_node"*> [#uses=1]
+ %4 = call fastcc i32 @computation_cost(%"union tree_node"* %3, i8 zeroext undef) nounwind ; <i32> [#uses=1]
+ br label %"100"
+
+"100": ; preds = %"99", %"93", %"67", %"62", %"25", %"23", %"8", %entry
+ %memtmp1.1.0 = phi i32 [ 0, %"99" ], [ 10000000, %entry ], [ 10000000, %"8" ], [ 10000000, %"23" ], [ 10000000, %"25" ], [ undef, %"62" ], [ undef, %"67" ], [ 10000000, %"93" ] ; <i32> [#uses=1]
+ %memtmp1.0.0 = phi i32 [ %4, %"99" ], [ 10000000, %entry ], [ 10000000, %"8" ], [ 10000000, %"23" ], [ 10000000, %"25" ], [ undef, %"62" ], [ undef, %"67" ], [ 10000000, %"93" ] ; <i32> [#uses=1]
+ %5 = zext i32 %memtmp1.0.0 to i64 ; <i64> [#uses=1]
+ %6 = zext i32 %memtmp1.1.0 to i64 ; <i64> [#uses=1]
+ %7 = shl i64 %6, 32 ; <i64> [#uses=1]
+ %8 = or i64 %7, %5 ; <i64> [#uses=1]
+ ret i64 %8
+}
diff --git a/test/CodeGen/X86/2010-02-15-ImplicitDefBug.ll b/test/CodeGen/X86/2010-02-15-ImplicitDefBug.ll
new file mode 100644
index 0000000..c429172
--- /dev/null
+++ b/test/CodeGen/X86/2010-02-15-ImplicitDefBug.ll
@@ -0,0 +1,80 @@
+; RUN: llc < %s > %t
+; PR6300
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-pc-linux-gnu"
+
+; When the "154" loops back onto itself, it defines a register after using it.
+; The first value of the register is implicit-def.
+
+%"struct location_chain_def" = type { %"struct location_chain_def"*, %"struct rtx_def"*, %"struct rtx_def"*, i32 }
+%"struct real_value" = type { i32, [5 x i32] }
+%"struct rtx_def" = type { i16, i8, i8, %"union u" }
+%"union u" = type { %"struct real_value" }
+
+define i32 @variable_union(i8** nocapture %slot, i8* nocapture %data) nounwind {
+entry:
+ br i1 undef, label %"4.thread", label %"3"
+
+"4.thread": ; preds = %entry
+ unreachable
+
+"3": ; preds = %entry
+ br i1 undef, label %"19", label %"20"
+
+"19": ; preds = %"3"
+ unreachable
+
+"20": ; preds = %"3"
+ br i1 undef, label %"56.preheader", label %dv_onepart_p.exit
+
+dv_onepart_p.exit: ; preds = %"20"
+ unreachable
+
+"56.preheader": ; preds = %"20"
+ br label %"56"
+
+"50": ; preds = %"57"
+ br label %"56"
+
+"56": ; preds = %"50", %"56.preheader"
+ br i1 undef, label %"57", label %"58"
+
+"57": ; preds = %"56"
+ br i1 undef, label %"50", label %"58"
+
+"58": ; preds = %"57", %"56"
+ br i1 undef, label %"62", label %"63"
+
+"62": ; preds = %"58"
+ unreachable
+
+"63": ; preds = %"58"
+ br i1 undef, label %"67", label %"66"
+
+"66": ; preds = %"63"
+ br label %"67"
+
+"67": ; preds = %"66", %"63"
+ br label %"68"
+
+"68": ; preds = %"161", %"67"
+ br i1 undef, label %"153", label %"161"
+
+"153": ; preds = %"68"
+ br i1 undef, label %"160", label %bb.nph46
+
+bb.nph46: ; preds = %"153"
+ br label %"154"
+
+"154": ; preds = %"154", %bb.nph46
+ %0 = phi %"struct location_chain_def"** [ undef, %bb.nph46 ], [ %1, %"154" ] ; <%"struct location_chain_def"**> [#uses=1]
+ %1 = bitcast i8* undef to %"struct location_chain_def"** ; <%"struct location_chain_def"**> [#uses=1]
+ store %"struct location_chain_def"* undef, %"struct location_chain_def"** %0, align 4
+ br i1 undef, label %"160", label %"154"
+
+"160": ; preds = %"154", %"153"
+ br label %"161"
+
+"161": ; preds = %"160", %"68"
+ br label %"68"
+}
diff --git a/test/CodeGen/Generic/SwitchLowering.ll b/test/CodeGen/X86/SwitchLowering.ll
index 29a0e82..29a0e82 100644
--- a/test/CodeGen/Generic/SwitchLowering.ll
+++ b/test/CodeGen/X86/SwitchLowering.ll
diff --git a/test/CodeGen/X86/add-trick32.ll b/test/CodeGen/X86/add-trick32.ll
deleted file mode 100644
index e86045d..0000000
--- a/test/CodeGen/X86/add-trick32.ll
+++ /dev/null
@@ -1,11 +0,0 @@
-; RUN: llc < %s -march=x86 > %t
-; RUN: not grep add %t
-; RUN: grep subl %t | count 1
-
-; The immediate can be encoded in a smaller way if the
-; instruction is a sub instead of an add.
-
-define i32 @foo(i32 inreg %a) nounwind {
- %b = add i32 %a, 128
- ret i32 %b
-}
diff --git a/test/CodeGen/X86/add-trick64.ll b/test/CodeGen/X86/add-trick64.ll
deleted file mode 100644
index 2f1fcee..0000000
--- a/test/CodeGen/X86/add-trick64.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: llc < %s -march=x86-64 > %t
-; RUN: not grep add %t
-; RUN: grep subq %t | count 2
-
-; The immediate can be encoded in a smaller way if the
-; instruction is a sub instead of an add.
-
-define i64 @foo(i64 inreg %a) nounwind {
- %b = add i64 %a, 2147483648
- ret i64 %b
-}
-define i64 @bar(i64 inreg %a) nounwind {
- %b = add i64 %a, 128
- ret i64 %b
-}
diff --git a/test/CodeGen/X86/add-with-overflow.ll b/test/CodeGen/X86/add-with-overflow.ll
deleted file mode 100644
index 0f705dc..0000000
--- a/test/CodeGen/X86/add-with-overflow.ll
+++ /dev/null
@@ -1,75 +0,0 @@
-; RUN: llc < %s -march=x86 | grep {jo} | count 2
-; RUN: llc < %s -march=x86 | grep {jb} | count 2
-; RUN: llc < %s -march=x86 -O0 | grep {jo} | count 2
-; RUN: llc < %s -march=x86 -O0 | grep {jb} | count 2
-
-@ok = internal constant [4 x i8] c"%d\0A\00"
-@no = internal constant [4 x i8] c"no\0A\00"
-
-define i1 @func1(i32 %v1, i32 %v2) nounwind {
-entry:
- %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
- %sum = extractvalue {i32, i1} %t, 0
- %obit = extractvalue {i32, i1} %t, 1
- br i1 %obit, label %overflow, label %normal
-
-normal:
- %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
- ret i1 true
-
-overflow:
- %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind
- ret i1 false
-}
-
-define i1 @func2(i32 %v1, i32 %v2) nounwind {
-entry:
- %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
- %sum = extractvalue {i32, i1} %t, 0
- %obit = extractvalue {i32, i1} %t, 1
- br i1 %obit, label %carry, label %normal
-
-normal:
- %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
- ret i1 true
-
-carry:
- %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind
- ret i1 false
-}
-
-define i1 @func3() nounwind {
-entry:
- %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 0, i32 0)
- %sum = extractvalue {i32, i1} %t, 0
- %obit = extractvalue {i32, i1} %t, 1
- br i1 %obit, label %carry, label %normal
-
-normal:
- %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
- ret i1 true
-
-carry:
- %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind
- ret i1 false
-}
-
-define i1 @func4() nounwind {
-entry:
- %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 0, i32 0)
- %sum = extractvalue {i32, i1} %t, 0
- %obit = extractvalue {i32, i1} %t, 1
- br i1 %obit, label %carry, label %normal
-
-normal:
- %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
- ret i1 true
-
-carry:
- %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind
- ret i1 false
-}
-
-declare i32 @printf(i8*, ...) nounwind
-declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32)
-declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32)
diff --git a/test/CodeGen/X86/add.ll b/test/CodeGen/X86/add.ll
new file mode 100644
index 0000000..3991a68
--- /dev/null
+++ b/test/CodeGen/X86/add.ll
@@ -0,0 +1,94 @@
+; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32
+; RUN: llc < %s -march=x86-64 | FileCheck %s -check-prefix=X64
+
+; The immediate can be encoded in a smaller way if the
+; instruction is a sub instead of an add.
+
+define i32 @test1(i32 inreg %a) nounwind {
+ %b = add i32 %a, 128
+ ret i32 %b
+; X32: subl $-128, %eax
+; X64: subl $-128,
+}
+define i64 @test2(i64 inreg %a) nounwind {
+ %b = add i64 %a, 2147483648
+ ret i64 %b
+; X32: addl $-2147483648, %eax
+; X64: subq $-2147483648,
+}
+define i64 @test3(i64 inreg %a) nounwind {
+ %b = add i64 %a, 128
+ ret i64 %b
+
+; X32: addl $128, %eax
+; X64: subq $-128,
+}
+
+define i1 @test4(i32 %v1, i32 %v2, i32* %X) nounwind {
+entry:
+ %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
+ %sum = extractvalue {i32, i1} %t, 0
+ %obit = extractvalue {i32, i1} %t, 1
+ br i1 %obit, label %overflow, label %normal
+
+normal:
+ store i32 0, i32* %X
+ br label %overflow
+
+overflow:
+ ret i1 false
+
+; X32: test4:
+; X32: addl
+; X32-NEXT: jo
+
+; X64: test4:
+; X64: addl %esi, %edi
+; X64-NEXT: jo
+}
+
+define i1 @test5(i32 %v1, i32 %v2, i32* %X) nounwind {
+entry:
+ %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
+ %sum = extractvalue {i32, i1} %t, 0
+ %obit = extractvalue {i32, i1} %t, 1
+ br i1 %obit, label %carry, label %normal
+
+normal:
+ store i32 0, i32* %X
+ br label %carry
+
+carry:
+ ret i1 false
+
+; X32: test5:
+; X32: addl
+; X32-NEXT: jb
+
+; X64: test5:
+; X64: addl %esi, %edi
+; X64-NEXT: jb
+}
+
+declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32)
+declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32)
+
+
+define i64 @test6(i64 %A, i32 %B) nounwind {
+ %tmp12 = zext i32 %B to i64 ; <i64> [#uses=1]
+ %tmp3 = shl i64 %tmp12, 32 ; <i64> [#uses=1]
+ %tmp5 = add i64 %tmp3, %A ; <i64> [#uses=1]
+ ret i64 %tmp5
+
+; X32: test6:
+; X32: movl 12(%esp), %edx
+; X32-NEXT: addl 8(%esp), %edx
+; X32-NEXT: movl 4(%esp), %eax
+; X32-NEXT: ret
+
+; X64: test6:
+; X64: shlq $32, %rsi
+; X64: leaq (%rsi,%rdi), %rax
+; X64: ret
+}
+
diff --git a/test/CodeGen/X86/addr-label-difference.ll b/test/CodeGen/X86/addr-label-difference.ll
index 547d6b5..be0908a 100644
--- a/test/CodeGen/X86/addr-label-difference.ll
+++ b/test/CodeGen/X86/addr-label-difference.ll
@@ -9,14 +9,18 @@ target triple = "i386-apple-darwin10.0"
define void @test(i32 %i) nounwind ssp {
entry:
+ call void @test(i32 1)
br label %foo
-foo: ; preds = %indirectgoto, %indirectgoto, %indirectgoto, %indirectgoto, %indirectgoto
+foo:
+ call void @test(i32 1)
br label %bar
-bar: ; preds = %foo, %indirectgoto
+bar:
+ call void @test(i32 1)
br label %hack
-hack: ; preds = %bar, %indirectgoto
+hack:
+ call void @test(i32 1)
ret void
}
diff --git a/test/CodeGen/X86/aliases.ll b/test/CodeGen/X86/aliases.ll
index 0b26859..3020eb3 100644
--- a/test/CodeGen/X86/aliases.ll
+++ b/test/CodeGen/X86/aliases.ll
@@ -1,5 +1,6 @@
; RUN: llc < %s -mtriple=i686-pc-linux-gnu -asm-verbose=false -o %t
-; RUN: grep set %t | count 7
+; RUN: grep { = } %t | count 7
+; RUN: grep set %t | count 16
; RUN: grep globl %t | count 6
; RUN: grep weak %t | count 1
; RUN: grep hidden %t | count 1
diff --git a/test/CodeGen/X86/aligned-comm.ll b/test/CodeGen/X86/aligned-comm.ll
index c0f3a81..7715869 100644
--- a/test/CodeGen/X86/aligned-comm.ll
+++ b/test/CodeGen/X86/aligned-comm.ll
@@ -1,8 +1,6 @@
; RUN: llc < %s -march=x86
; RUN: llc < %s -mtriple=i386-apple-darwin10 | grep {array,16512,7}
; RUN: llc < %s -mtriple=i386-apple-darwin9 | grep {array,16512,7}
-; RUN: llc < %s -mtriple=i386-apple-darwin8 | not grep {7}
-; Darwin 9+ should get alignment on common symbols. Darwin8 does
-; not support this.
+; Darwin 9+ should get alignment on common symbols.
@array = common global [4128 x i32] zeroinitializer, align 128
diff --git a/test/CodeGen/X86/call-push.ll b/test/CodeGen/X86/call-push.ll
index 7bae5cd..02cbccc 100644
--- a/test/CodeGen/X86/call-push.ll
+++ b/test/CodeGen/X86/call-push.ll
@@ -1,9 +1,14 @@
-; RUN: llc < %s -march=x86 -disable-fp-elim | grep subl | count 1
+; RUN: llc < %s -mtriple=i386-apple-darwin -disable-fp-elim | FileCheck %s
%struct.decode_t = type { i8, i8, i8, i8, i16, i8, i8, %struct.range_t** }
%struct.range_t = type { float, float, i32, i32, i32, [0 x i8] }
-define i32 @decode_byte(%struct.decode_t* %decode) {
+define i32 @decode_byte(%struct.decode_t* %decode) nounwind {
+; CHECK: decode_byte:
+; CHECK: pushl
+; CHECK: popl
+; CHECK: popl
+; CHECK: jmp
entry:
%tmp2 = getelementptr %struct.decode_t* %decode, i32 0, i32 4 ; <i16*> [#uses=1]
%tmp23 = bitcast i16* %tmp2 to i32* ; <i32*> [#uses=1]
diff --git a/test/CodeGen/X86/twoaddr-delete.ll b/test/CodeGen/X86/codegen-dce.ll
index 77e3c75..d83efaf 100644
--- a/test/CodeGen/X86/twoaddr-delete.ll
+++ b/test/CodeGen/X86/codegen-dce.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=x86 -stats |& grep {twoaddrinstr} | grep {Number of dead instructions deleted}
+; RUN: llc < %s -march=x86 -stats |& grep {codegen-dce} | grep {Number of dead instructions deleted}
%struct.anon = type { [3 x double], double, %struct.node*, [64 x %struct.bnode*], [64 x %struct.bnode*] }
%struct.bnode = type { i16, double, [3 x double], i32, i32, [3 x double], [3 x double], [3 x double], double, %struct.bnode*, %struct.bnode* }
diff --git a/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll b/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll
index 337f1b2..8e38fe3 100644
--- a/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll
+++ b/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll
@@ -1,19 +1,20 @@
; RUN: llc < %s -march=x86-64 -o %t -stats -info-output-file - | \
-; RUN: grep {asm-printer} | grep {Number of machine instrs printed} | grep 5
+; RUN: grep {asm-printer} | grep {Number of machine instrs printed} | grep 10
; RUN: grep {leal 1(\%rsi),} %t
-define fastcc zeroext i8 @fullGtU(i32 %i1, i32 %i2) nounwind optsize {
+define fastcc zeroext i8 @fullGtU(i32 %i1, i32 %i2, i8* %ptr) nounwind optsize {
entry:
%0 = add i32 %i2, 1 ; <i32> [#uses=1]
%1 = sext i32 %0 to i64 ; <i64> [#uses=1]
- %2 = getelementptr i8* null, i64 %1 ; <i8*> [#uses=1]
+ %2 = getelementptr i8* %ptr, i64 %1 ; <i8*> [#uses=1]
%3 = load i8* %2, align 1 ; <i8> [#uses=1]
%4 = icmp eq i8 0, %3 ; <i1> [#uses=1]
br i1 %4, label %bb3, label %bb34
bb3: ; preds = %entry
%5 = add i32 %i2, 4 ; <i32> [#uses=0]
- ret i8 0
+ %6 = trunc i32 %5 to i8
+ ret i8 %6
bb34: ; preds = %entry
ret i8 0
diff --git a/test/CodeGen/X86/dllexport.ll b/test/CodeGen/X86/dllexport.ll
new file mode 100644
index 0000000..2c699bf
--- /dev/null
+++ b/test/CodeGen/X86/dllexport.ll
@@ -0,0 +1,12 @@
+; RUN: llc < %s | FileCheck %s
+; PR2936
+
+target triple = "i386-mingw32"
+
+define dllexport x86_fastcallcc i32 @foo() nounwind {
+entry:
+ ret i32 0
+}
+
+; CHECK: .section .drectve
+; CHECK: -export:@foo@0 \ No newline at end of file
diff --git a/test/CodeGen/X86/fastcall-correct-mangling.ll b/test/CodeGen/X86/fastcall-correct-mangling.ll
index 2b48f5f..33b18bb 100644
--- a/test/CodeGen/X86/fastcall-correct-mangling.ll
+++ b/test/CodeGen/X86/fastcall-correct-mangling.ll
@@ -1,9 +1,9 @@
-; RUN: llc < %s -mtriple=i386-unknown-mingw32 | \
-; RUN: grep {@12}
+; RUN: llc < %s -mtriple=i386-unknown-mingw32 | FileCheck %s
; Check that a fastcall function gets correct mangling
define x86_fastcallcc void @func(i64 %X, i8 %Y, i8 %G, i16 %Z) {
+; CHECK: @func@20:
ret void
}
diff --git a/test/CodeGen/X86/full-lsr.ll b/test/CodeGen/X86/full-lsr.ll
index 3bd58b6..ff9b1b0 100644
--- a/test/CodeGen/X86/full-lsr.ll
+++ b/test/CodeGen/X86/full-lsr.ll
@@ -1,12 +1,7 @@
; RUN: llc < %s -march=x86 >%t
-; TODO: Enhance full lsr mode to get this:
-; RUNX: grep {addl \\\$4,} %t | count 3
-; RUNX: not grep {,%} %t
-
-; For now, it should find this, which is still pretty good:
-; RUN: not grep {addl \\\$4,} %t
-; RUN: grep {,%} %t | count 6
+; RUN: grep {addl \\\$4,} %t | count 3
+; RUN: not grep {,%} %t
define void @foo(float* nocapture %A, float* nocapture %B, float* nocapture %C, i32 %N) nounwind {
entry:
diff --git a/test/CodeGen/X86/ins_subreg_coalesce-3.ll b/test/CodeGen/X86/ins_subreg_coalesce-3.ll
index e443085..627edc5 100644
--- a/test/CodeGen/X86/ins_subreg_coalesce-3.ll
+++ b/test/CodeGen/X86/ins_subreg_coalesce-3.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=x86-64 | grep mov | count 11
+; RUN: llc < %s -march=x86-64 | grep mov | count 5
%struct.COMPOSITE = type { i8, i16, i16 }
%struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
diff --git a/test/CodeGen/X86/iv-users-in-other-loops.ll b/test/CodeGen/X86/iv-users-in-other-loops.ll
index c695c29..408fb20 100644
--- a/test/CodeGen/X86/iv-users-in-other-loops.ll
+++ b/test/CodeGen/X86/iv-users-in-other-loops.ll
@@ -1,11 +1,11 @@
; RUN: llc < %s -march=x86-64 -o %t
-; RUN: grep inc %t | count 1
+; RUN: not grep inc %t
; RUN: grep dec %t | count 2
; RUN: grep addq %t | count 13
; RUN: not grep addb %t
-; RUN: grep leaq %t | count 9
-; RUN: grep leal %t | count 3
-; RUN: grep movq %t | count 5
+; RUN: not grep leaq %t
+; RUN: not grep leal %t
+; RUN: not grep movq %t
; IV users in each of the loops from other loops shouldn't cause LSR
; to insert new induction variables. Previously it would create a
diff --git a/test/CodeGen/X86/loop-strength-reduce-2.ll b/test/CodeGen/X86/loop-strength-reduce-2.ll
index 30b5114..b546462 100644
--- a/test/CodeGen/X86/loop-strength-reduce-2.ll
+++ b/test/CodeGen/X86/loop-strength-reduce-2.ll
@@ -1,11 +1,24 @@
-; RUN: llc < %s -march=x86 -relocation-model=pic | \
-; RUN: grep {, 4} | count 1
-; RUN: llc < %s -march=x86 | not grep lea
+; RUN: llc < %s -march=x86 -relocation-model=pic | FileCheck %s -check-prefix=PIC
+; RUN: llc < %s -march=x86 -relocation-model=static | FileCheck %s -check-prefix=STATIC
;
; Make sure the common loop invariant A is hoisted up to preheader,
; since too many registers are needed to subsume it into the addressing modes.
; It's safe to sink A in when it's not pic.
+; PIC: align
+; PIC: movl $4, -4([[REG:%e[a-z]+]])
+; PIC: movl $5, ([[REG]])
+; PIC: addl $4, [[REG]]
+; PIC: decl {{%e[[a-z]+}}
+; PIC: jne
+
+; STATIC: align
+; STATIC: movl $4, -4(%ecx)
+; STATIC: movl $5, (%ecx)
+; STATIC: addl $4, %ecx
+; STATIC: decl %eax
+; STATIC: jne
+
@A = global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2]
define void @test(i32 %row, i32 %N.in) nounwind {
diff --git a/test/CodeGen/X86/loop-strength-reduce-3.ll b/test/CodeGen/X86/loop-strength-reduce-3.ll
index 70c9134..b1c9fb9 100644
--- a/test/CodeGen/X86/loop-strength-reduce-3.ll
+++ b/test/CodeGen/X86/loop-strength-reduce-3.ll
@@ -1,8 +1,11 @@
-; RUN: llc < %s -mtriple=i386-apple-darwin -relocation-model=dynamic-no-pic | \
-; RUN: grep {A+} | count 2
-;
-; Make sure the common loop invariant A is not hoisted up to preheader,
-; since it can be subsumed it into the addressing modes.
+; RUN: llc < %s -mtriple=i386-apple-darwin -relocation-model=dynamic-no-pic | FileCheck %s
+
+; CHECK: align
+; CHECK: movl $4, -4(%ecx)
+; CHECK: movl $5, (%ecx)
+; CHECK: addl $4, %ecx
+; CHECK: decl %eax
+; CHECK: jne
@A = global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2]
diff --git a/test/CodeGen/X86/loop-strength-reduce.ll b/test/CodeGen/X86/loop-strength-reduce.ll
index 4cb56ca..42c6ac4 100644
--- a/test/CodeGen/X86/loop-strength-reduce.ll
+++ b/test/CodeGen/X86/loop-strength-reduce.ll
@@ -1,8 +1,11 @@
-; RUN: llc < %s -march=x86 -relocation-model=static | \
-; RUN: grep {A+} | count 2
-;
-; Make sure the common loop invariant A is not hoisted up to preheader,
-; since it can be subsumed into the addressing mode in all uses.
+; RUN: llc < %s -march=x86 -relocation-model=static | FileCheck %s
+
+; CHECK: align
+; CHECK: movl $4, -4(%ecx)
+; CHECK: movl $5, (%ecx)
+; CHECK: addl $4, %ecx
+; CHECK: decl %eax
+; CHECK: jne
@A = internal global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2]
diff --git a/test/CodeGen/X86/loop-strength-reduce4.ll b/test/CodeGen/X86/loop-strength-reduce4.ll
index 07e46ec..6c0eb8c 100644
--- a/test/CodeGen/X86/loop-strength-reduce4.ll
+++ b/test/CodeGen/X86/loop-strength-reduce4.ll
@@ -1,5 +1,19 @@
-; RUN: llc < %s -march=x86 | grep cmp | grep 64
-; RUN: llc < %s -march=x86 | not grep inc
+; RUN: llc < %s -march=x86 -relocation-model=static -mtriple=i686-apple-darwin | FileCheck %s -check-prefix=STATIC
+; RUN: llc < %s -march=x86 -relocation-model=pic | FileCheck %s -check-prefix=PIC
+
+; By starting the IV at -64 instead of 0, a cmp is eliminated,
+; as the flags from the add can be used directly.
+
+; STATIC: movl $-64, %ecx
+
+; STATIC: movl %eax, _state+76(%ecx)
+; STATIC: addl $16, %ecx
+; STATIC: jne
+
+; In PIC mode the symbol can't be folded, so the change-compare-stride
+; trick applies.
+
+; PIC: cmpl $64
@state = external global [0 x i32] ; <[0 x i32]*> [#uses=4]
@S = external global [0 x i32] ; <[0 x i32]*> [#uses=4]
diff --git a/test/CodeGen/X86/loop-strength-reduce8.ll b/test/CodeGen/X86/loop-strength-reduce8.ll
index e14cd8a..6b2247d 100644
--- a/test/CodeGen/X86/loop-strength-reduce8.ll
+++ b/test/CodeGen/X86/loop-strength-reduce8.ll
@@ -1,4 +1,10 @@
-; RUN: llc < %s -mtriple=i386-apple-darwin | grep leal | not grep 16
+; RUN: llc < %s -mtriple=i386-apple-darwin | FileCheck %s
+
+; CHECK: leal 16(%eax), %edx
+; CHECK: align
+; CHECK: addl $4, %edx
+; CHECK: decl %ecx
+; CHECK: jne LBB1_2
%struct.CUMULATIVE_ARGS = type { i32, i32, i32, i32, i32, i32, i32 }
%struct.bitmap_element = type { %struct.bitmap_element*, %struct.bitmap_element*, i32, [2 x i64] }
diff --git a/test/CodeGen/X86/lsr-reuse-trunc.ll b/test/CodeGen/X86/lsr-reuse-trunc.ll
new file mode 100644
index 0000000..d1d7144
--- /dev/null
+++ b/test/CodeGen/X86/lsr-reuse-trunc.ll
@@ -0,0 +1,59 @@
+; RUN: llc < %s -march=x86-64 | FileCheck %s
+
+; Full strength reduction wouldn't reduce register pressure, so LSR should
+; stick with indexing here.
+
+; CHECK: movaps (%rsi,%rax,4), %xmm3
+; CHECK: movaps %xmm3, (%rdi,%rax,4)
+; CHECK: addq $4, %rax
+; CHECK: cmpl %eax, (%rdx)
+; CHECK-NEXT: jg
+
+define void @vvfloorf(float* nocapture %y, float* nocapture %x, i32* nocapture %n) nounwind {
+entry:
+ %0 = load i32* %n, align 4
+ %1 = icmp sgt i32 %0, 0
+ br i1 %1, label %bb, label %return
+
+bb:
+ %indvar = phi i64 [ %indvar.next, %bb ], [ 0, %entry ]
+ %tmp = shl i64 %indvar, 2
+ %scevgep = getelementptr float* %y, i64 %tmp
+ %scevgep9 = bitcast float* %scevgep to <4 x float>*
+ %scevgep10 = getelementptr float* %x, i64 %tmp
+ %scevgep1011 = bitcast float* %scevgep10 to <4 x float>*
+ %2 = load <4 x float>* %scevgep1011, align 16
+ %3 = bitcast <4 x float> %2 to <4 x i32>
+ %4 = and <4 x i32> %3, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
+ %5 = bitcast <4 x i32> %4 to <4 x float>
+ %6 = and <4 x i32> %3, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
+ %7 = tail call <4 x float> @llvm.x86.sse.cmp.ps(<4 x float> %5, <4 x float> <float 8.388608e+06, float 8.388608e+06, float 8.388608e+06, float 8.388608e+06>, i8 5) nounwind
+ %tmp.i4 = bitcast <4 x float> %7 to <4 x i32>
+ %8 = xor <4 x i32> %tmp.i4, <i32 -1, i32 -1, i32 -1, i32 -1>
+ %9 = and <4 x i32> %8, <i32 1258291200, i32 1258291200, i32 1258291200, i32 1258291200>
+ %10 = or <4 x i32> %9, %6
+ %11 = bitcast <4 x i32> %10 to <4 x float>
+ %12 = fadd <4 x float> %2, %11
+ %13 = fsub <4 x float> %12, %11
+ %14 = tail call <4 x float> @llvm.x86.sse.cmp.ps(<4 x float> %2, <4 x float> %13, i8 1) nounwind
+ %15 = bitcast <4 x float> %14 to <4 x i32>
+ %16 = tail call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> %15) nounwind readnone
+ %17 = fadd <4 x float> %13, %16
+ %tmp.i = bitcast <4 x float> %17 to <4 x i32>
+ %18 = or <4 x i32> %tmp.i, %6
+ %19 = bitcast <4 x i32> %18 to <4 x float>
+ store <4 x float> %19, <4 x float>* %scevgep9, align 16
+ %tmp12 = add i64 %tmp, 4
+ %tmp13 = trunc i64 %tmp12 to i32
+ %20 = load i32* %n, align 4
+ %21 = icmp sgt i32 %20, %tmp13
+ %indvar.next = add i64 %indvar, 1
+ br i1 %21, label %bb, label %return
+
+return:
+ ret void
+}
+
+declare <4 x float> @llvm.x86.sse.cmp.ps(<4 x float>, <4 x float>, i8) nounwind readnone
+
+declare <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32>) nounwind readnone
diff --git a/test/CodeGen/X86/lsr-reuse.ll b/test/CodeGen/X86/lsr-reuse.ll
new file mode 100644
index 0000000..7f2b8cc
--- /dev/null
+++ b/test/CodeGen/X86/lsr-reuse.ll
@@ -0,0 +1,386 @@
+; RUN: llc < %s -march=x86-64 -O3 | FileCheck %s
+target datalayout = "e-p:64:64:64"
+target triple = "x86_64-unknown-unknown"
+
+; Full strength reduction reduces register pressure from 5 to 4 here.
+; Instruction selection should use the FLAGS value from the dec for
+; the branch. Scheduling should push the adds upwards.
+
+; CHECK: full_me_0:
+; CHECK: movsd (%rsi), %xmm0
+; CHECK: addq $8, %rsi
+; CHECK: mulsd (%rdx), %xmm0
+; CHECK: addq $8, %rdx
+; CHECK: movsd %xmm0, (%rdi)
+; CHECK: addq $8, %rdi
+; CHECK: decq %rcx
+; CHECK: jne
+
+define void @full_me_0(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; Mostly-full strength reduction means we do full strength reduction on all
+; except for the offsets.
+;
+; Given a choice between constant offsets -2048 and 2048, choose the negative
+; value, because at boundary conditions it has a smaller encoding.
+; TODO: That's an over-general heuristic. It would be better for the target
+; to indicate what the encoding cost would be. Then using a 2048 offset
+; would be better on x86-64, since the start value would be 0 instead of
+; 2048.
+
+; CHECK: mostly_full_me_0:
+; CHECK: movsd -2048(%rsi), %xmm0
+; CHECK: mulsd -2048(%rdx), %xmm0
+; CHECK: movsd %xmm0, -2048(%rdi)
+; CHECK: movsd (%rsi), %xmm0
+; CHECK: addq $8, %rsi
+; CHECK: divsd (%rdx), %xmm0
+; CHECK: addq $8, %rdx
+; CHECK: movsd %xmm0, (%rdi)
+; CHECK: addq $8, %rdi
+; CHECK: decq %rcx
+; CHECK: jne
+
+define void @mostly_full_me_0(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %j = add i64 %i, 256
+ %Aj = getelementptr inbounds double* %A, i64 %j
+ %Bj = getelementptr inbounds double* %B, i64 %j
+ %Cj = getelementptr inbounds double* %C, i64 %j
+ %t3 = load double* %Bj
+ %t4 = load double* %Cj
+ %o = fdiv double %t3, %t4
+ store double %o, double* %Aj
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; A minor variation on mostly_full_me_0.
+; Prefer to start the indvar at 0.
+
+; CHECK: mostly_full_me_1:
+; CHECK: movsd (%rsi), %xmm0
+; CHECK: mulsd (%rdx), %xmm0
+; CHECK: movsd %xmm0, (%rdi)
+; CHECK: movsd -2048(%rsi), %xmm0
+; CHECK: addq $8, %rsi
+; CHECK: divsd -2048(%rdx), %xmm0
+; CHECK: addq $8, %rdx
+; CHECK: movsd %xmm0, -2048(%rdi)
+; CHECK: addq $8, %rdi
+; CHECK: decq %rcx
+; CHECK: jne
+
+define void @mostly_full_me_1(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %j = sub i64 %i, 256
+ %Aj = getelementptr inbounds double* %A, i64 %j
+ %Bj = getelementptr inbounds double* %B, i64 %j
+ %Cj = getelementptr inbounds double* %C, i64 %j
+ %t3 = load double* %Bj
+ %t4 = load double* %Cj
+ %o = fdiv double %t3, %t4
+ store double %o, double* %Aj
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; A slightly less minor variation on mostly_full_me_0.
+
+; CHECK: mostly_full_me_2:
+; CHECK: movsd (%rsi), %xmm0
+; CHECK: mulsd (%rdx), %xmm0
+; CHECK: movsd %xmm0, (%rdi)
+; CHECK: movsd -4096(%rsi), %xmm0
+; CHECK: addq $8, %rsi
+; CHECK: divsd -4096(%rdx), %xmm0
+; CHECK: addq $8, %rdx
+; CHECK: movsd %xmm0, -4096(%rdi)
+; CHECK: addq $8, %rdi
+; CHECK: decq %rcx
+; CHECK: jne
+
+define void @mostly_full_me_2(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %k = add i64 %i, 256
+ %Ak = getelementptr inbounds double* %A, i64 %k
+ %Bk = getelementptr inbounds double* %B, i64 %k
+ %Ck = getelementptr inbounds double* %C, i64 %k
+ %t1 = load double* %Bk
+ %t2 = load double* %Ck
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ak
+ %j = sub i64 %i, 256
+ %Aj = getelementptr inbounds double* %A, i64 %j
+ %Bj = getelementptr inbounds double* %B, i64 %j
+ %Cj = getelementptr inbounds double* %C, i64 %j
+ %t3 = load double* %Bj
+ %t4 = load double* %Cj
+ %o = fdiv double %t3, %t4
+ store double %o, double* %Aj
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; In this test, the counting IV exit value is used, so full strength reduction
+; would not reduce register pressure. IndVarSimplify ought to simplify such
+; cases away, but it's useful here to verify that LSR's register pressure
+; heuristics are working as expected.
+
+; CHECK: count_me_0:
+; CHECK: movsd (%rsi,%rax,8), %xmm0
+; CHECK: mulsd (%rdx,%rax,8), %xmm0
+; CHECK: movsd %xmm0, (%rdi,%rax,8)
+; CHECK: incq %rax
+; CHECK: cmpq %rax, %rcx
+; CHECK: jne
+
+define i64 @count_me_0(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ %q = phi i64 [ 0, %entry ], [ %i.next, %loop ]
+ ret i64 %q
+}
+
+; In this test, the trip count value is used, so full strength reduction
+; would not reduce register pressure.
+; (though it would reduce register pressure inside the loop...)
+
+; CHECK: count_me_1:
+; CHECK: movsd (%rsi,%rax,8), %xmm0
+; CHECK: mulsd (%rdx,%rax,8), %xmm0
+; CHECK: movsd %xmm0, (%rdi,%rax,8)
+; CHECK: incq %rax
+; CHECK: cmpq %rax, %rcx
+; CHECK: jne
+
+define i64 @count_me_1(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ %q = phi i64 [ 0, %entry ], [ %n, %loop ]
+ ret i64 %q
+}
+
+; Full strength reduction doesn't save any registers here because the
+; loop tripcount is a constant.
+
+; CHECK: count_me_2:
+; CHECK: movl $10, %eax
+; CHECK: align
+; CHECK: BB7_1:
+; CHECK: movsd -40(%rdi,%rax,8), %xmm0
+; CHECK: addsd -40(%rsi,%rax,8), %xmm0
+; CHECK: movsd %xmm0, -40(%rdx,%rax,8)
+; CHECK: movsd (%rdi,%rax,8), %xmm0
+; CHECK: subsd (%rsi,%rax,8), %xmm0
+; CHECK: movsd %xmm0, (%rdx,%rax,8)
+; CHECK: incq %rax
+; CHECK: cmpq $5010, %rax
+; CHECK: jne
+
+define void @count_me_2(double* nocapture %A, double* nocapture %B, double* nocapture %C) nounwind {
+entry:
+ br label %loop
+
+loop:
+ %i = phi i64 [ 0, %entry ], [ %i.next, %loop ]
+ %i5 = add i64 %i, 5
+ %Ai = getelementptr double* %A, i64 %i5
+ %t2 = load double* %Ai
+ %Bi = getelementptr double* %B, i64 %i5
+ %t4 = load double* %Bi
+ %t5 = fadd double %t2, %t4
+ %Ci = getelementptr double* %C, i64 %i5
+ store double %t5, double* %Ci
+ %i10 = add i64 %i, 10
+ %Ai10 = getelementptr double* %A, i64 %i10
+ %t9 = load double* %Ai10
+ %Bi10 = getelementptr double* %B, i64 %i10
+ %t11 = load double* %Bi10
+ %t12 = fsub double %t9, %t11
+ %Ci10 = getelementptr double* %C, i64 %i10
+ store double %t12, double* %Ci10
+ %i.next = add i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, 5000
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; This should be fully strength-reduced to reduce register pressure.
+
+; CHECK: full_me_1:
+; CHECK: align
+; CHECK: BB8_1:
+; CHECK: movsd (%rdi), %xmm0
+; CHECK: addsd (%rsi), %xmm0
+; CHECK: movsd %xmm0, (%rdx)
+; CHECK: movsd 40(%rdi), %xmm0
+; CHECK: addq $8, %rdi
+; CHECK: subsd 40(%rsi), %xmm0
+; CHECK: addq $8, %rsi
+; CHECK: movsd %xmm0, 40(%rdx)
+; CHECK: addq $8, %rdx
+; CHECK: decq %rcx
+; CHECK: jne
+
+define void @full_me_1(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ br label %loop
+
+loop:
+ %i = phi i64 [ 0, %entry ], [ %i.next, %loop ]
+ %i5 = add i64 %i, 5
+ %Ai = getelementptr double* %A, i64 %i5
+ %t2 = load double* %Ai
+ %Bi = getelementptr double* %B, i64 %i5
+ %t4 = load double* %Bi
+ %t5 = fadd double %t2, %t4
+ %Ci = getelementptr double* %C, i64 %i5
+ store double %t5, double* %Ci
+ %i10 = add i64 %i, 10
+ %Ai10 = getelementptr double* %A, i64 %i10
+ %t9 = load double* %Ai10
+ %Bi10 = getelementptr double* %B, i64 %i10
+ %t11 = load double* %Bi10
+ %t12 = fsub double %t9, %t11
+ %Ci10 = getelementptr double* %C, i64 %i10
+ store double %t12, double* %Ci10
+ %i.next = add i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
+
+; This is a variation on full_me_0 in which the 0,+,1 induction variable
+; has a non-address use, pinning that value in a register.
+
+; CHECK: count_me_3:
+; CHECK: call
+; CHECK: movsd (%r15,%r13,8), %xmm0
+; CHECK: mulsd (%r14,%r13,8), %xmm0
+; CHECK: movsd %xmm0, (%r12,%r13,8)
+; CHECK: incq %r13
+; CHECK: cmpq %r13, %rbx
+; CHECK: jne
+
+declare void @use(i64)
+
+define void @count_me_3(double* nocapture %A, double* nocapture %B, double* nocapture %C, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0
+ br i1 %t0, label %loop, label %return
+
+loop:
+ %i = phi i64 [ %i.next, %loop ], [ 0, %entry ]
+ call void @use(i64 %i)
+ %Ai = getelementptr inbounds double* %A, i64 %i
+ %Bi = getelementptr inbounds double* %B, i64 %i
+ %Ci = getelementptr inbounds double* %C, i64 %i
+ %t1 = load double* %Bi
+ %t2 = load double* %Ci
+ %m = fmul double %t1, %t2
+ store double %m, double* %Ai
+ %i.next = add nsw i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, %n
+ br i1 %exitcond, label %return, label %loop
+
+return:
+ ret void
+}
diff --git a/test/CodeGen/X86/masked-iv-safe.ll b/test/CodeGen/X86/masked-iv-safe.ll
index bc493bd..0b4d73a 100644
--- a/test/CodeGen/X86/masked-iv-safe.ll
+++ b/test/CodeGen/X86/masked-iv-safe.ll
@@ -169,7 +169,7 @@ loop:
%indvar.i24 = and i64 %indvar, 16777215
%t3 = getelementptr double* %d, i64 %indvar.i24
%t4 = load double* %t3
- %t5 = fmul double %t4, 2.3
+ %t5 = fdiv double %t4, 2.3
store double %t5, double* %t3
%t6 = getelementptr double* %d, i64 %indvar
%t7 = load double* %t6
@@ -199,7 +199,7 @@ loop:
%indvar.i24 = ashr i64 %s1, 24
%t3 = getelementptr double* %d, i64 %indvar.i24
%t4 = load double* %t3
- %t5 = fmul double %t4, 2.3
+ %t5 = fdiv double %t4, 2.3
store double %t5, double* %t3
%t6 = getelementptr double* %d, i64 %indvar
%t7 = load double* %t6
@@ -229,7 +229,7 @@ loop:
%indvar.i24 = ashr i64 %s1, 24
%t3 = getelementptr double* %d, i64 %indvar.i24
%t4 = load double* %t3
- %t5 = fmul double %t4, 2.3
+ %t5 = fdiv double %t4, 2.3
store double %t5, double* %t3
%t6 = getelementptr double* %d, i64 %indvar
%t7 = load double* %t6
diff --git a/test/CodeGen/X86/nancvt.ll b/test/CodeGen/X86/nancvt.ll
index 0b56644..82b7331 100644
--- a/test/CodeGen/X86/nancvt.ll
+++ b/test/CodeGen/X86/nancvt.ll
@@ -16,6 +16,8 @@ target triple = "i686-apple-darwin8"
@.str = internal constant [10 x i8] c"%08x%08x\0A\00" ; <[10 x i8]*> [#uses=2]
@.str1 = internal constant [6 x i8] c"%08x\0A\00" ; <[6 x i8]*> [#uses=2]
+@var = external global i32
+
define i32 @main() {
entry:
%retval = alloca i32, align 4 ; <i32*> [#uses=1]
@@ -50,7 +52,8 @@ bb: ; preds = %bb23
%tmp17 = ashr i64 %tmp16, %.cast ; <i64> [#uses=1]
%tmp1718 = trunc i64 %tmp17 to i32 ; <i32> [#uses=1]
%tmp19 = getelementptr [10 x i8]* @.str, i32 0, i32 0 ; <i8*> [#uses=1]
- %tmp20 = call i32 (i8*, ...)* @printf( i8* %tmp19, i32 %tmp1718, i32 %tmp13 ) ; <i32> [#uses=0]
+ volatile store i32 %tmp1718, i32* @var
+ volatile store i32 %tmp13, i32* @var
%tmp21 = load i32* %i, align 4 ; <i32> [#uses=1]
%tmp22 = add i32 %tmp21, 1 ; <i32> [#uses=1]
store i32 %tmp22, i32* %i, align 4
@@ -83,7 +86,7 @@ bb28: ; preds = %bb46
%tmp3940 = bitcast float* %tmp39 to i32* ; <i32*> [#uses=1]
%tmp41 = load i32* %tmp3940, align 4 ; <i32> [#uses=1]
%tmp42 = getelementptr [6 x i8]* @.str1, i32 0, i32 0 ; <i8*> [#uses=1]
- %tmp43 = call i32 (i8*, ...)* @printf( i8* %tmp42, i32 %tmp41 ) ; <i32> [#uses=0]
+ volatile store i32 %tmp41, i32* @var
%tmp44 = load i32* %i, align 4 ; <i32> [#uses=1]
%tmp45 = add i32 %tmp44, 1 ; <i32> [#uses=1]
store i32 %tmp45, i32* %i, align 4
@@ -124,7 +127,8 @@ bb52: ; preds = %bb78
%tmp72 = ashr i64 %tmp70, %.cast71 ; <i64> [#uses=1]
%tmp7273 = trunc i64 %tmp72 to i32 ; <i32> [#uses=1]
%tmp74 = getelementptr [10 x i8]* @.str, i32 0, i32 0 ; <i8*> [#uses=1]
- %tmp75 = call i32 (i8*, ...)* @printf( i8* %tmp74, i32 %tmp7273, i32 %tmp66 ) ; <i32> [#uses=0]
+ volatile store i32 %tmp7273, i32* @var
+ volatile store i32 %tmp66, i32* @var
%tmp76 = load i32* %i, align 4 ; <i32> [#uses=1]
%tmp77 = add i32 %tmp76, 1 ; <i32> [#uses=1]
store i32 %tmp77, i32* %i, align 4
@@ -157,7 +161,7 @@ bb84: ; preds = %bb101
%tmp9495 = bitcast float* %tmp94 to i32* ; <i32*> [#uses=1]
%tmp96 = load i32* %tmp9495, align 4 ; <i32> [#uses=1]
%tmp97 = getelementptr [6 x i8]* @.str1, i32 0, i32 0 ; <i8*> [#uses=1]
- %tmp98 = call i32 (i8*, ...)* @printf( i8* %tmp97, i32 %tmp96 ) ; <i32> [#uses=0]
+ volatile store i32 %tmp96, i32* @var
%tmp99 = load i32* %i, align 4 ; <i32> [#uses=1]
%tmp100 = add i32 %tmp99, 1 ; <i32> [#uses=1]
store i32 %tmp100, i32* %i, align 4
@@ -177,5 +181,3 @@ return: ; preds = %bb106
%retval107 = load i32* %retval ; <i32> [#uses=1]
ret i32 %retval107
}
-
-declare i32 @printf(i8*, ...)
diff --git a/test/CodeGen/X86/personality.ll b/test/CodeGen/X86/personality.ll
index 5acf04c..ce57e8f 100644
--- a/test/CodeGen/X86/personality.ll
+++ b/test/CodeGen/X86/personality.ll
@@ -39,7 +39,7 @@ declare void @__gxx_personality_v0()
declare void @__cxa_end_catch()
; X64: Leh_frame_common_begin:
-; X64: .long ___gxx_personality_v0@GOTPCREL+4
+; X64: .long (___gxx_personality_v0@GOTPCREL)+4
; X32: Leh_frame_common_begin:
; X32: .long L___gxx_personality_v0$non_lazy_ptr-
diff --git a/test/CodeGen/Generic/phi-immediate-factoring.ll b/test/CodeGen/X86/phi-immediate-factoring.ll
index 9f9f921..9f9f921 100644
--- a/test/CodeGen/Generic/phi-immediate-factoring.ll
+++ b/test/CodeGen/X86/phi-immediate-factoring.ll
diff --git a/test/CodeGen/X86/phys-reg-local-regalloc.ll b/test/CodeGen/X86/phys-reg-local-regalloc.ll
index e5e2d4b..045841e 100644
--- a/test/CodeGen/X86/phys-reg-local-regalloc.ll
+++ b/test/CodeGen/X86/phys-reg-local-regalloc.ll
@@ -1,4 +1,6 @@
; RUN: llc < %s -march=x86 -mtriple=i386-apple-darwin9 -regalloc=local | FileCheck %s
+; RUN: llc -O0 < %s -march=x86 -mtriple=i386-apple-darwin9 -regalloc=local | FileCheck %s
+; CHECKed instructions should be the same with or without -O0.
@.str = private constant [12 x i8] c"x + y = %i\0A\00", align 1 ; <[12 x i8]*> [#uses=1]
diff --git a/test/CodeGen/X86/pic.ll b/test/CodeGen/X86/pic.ll
index e886ba0..d3c28a0 100644
--- a/test/CodeGen/X86/pic.ll
+++ b/test/CodeGen/X86/pic.ll
@@ -190,7 +190,7 @@ bb12:
; LINUX: .L8$pb:
; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.Lpicbaseref8-.L8$pb),
; LINUX: addl .LJTI8_0@GOTOFF(
-; LINUX: jmpl *%ecx
+; LINUX: jmpl *
; LINUX: .LJTI8_0:
; LINUX: .long .LBB8_2@GOTOFF
diff --git a/test/CodeGen/X86/pr1505b.ll b/test/CodeGen/X86/pr1505b.ll
index 12736cd..6a08dae 100644
--- a/test/CodeGen/X86/pr1505b.ll
+++ b/test/CodeGen/X86/pr1505b.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -mcpu=i486 | grep fstpl | count 4
-; RUN: llc < %s -mcpu=i486 | grep fstps | count 3
+; RUN: llc < %s -mcpu=i486 | grep fstpl | count 5
+; RUN: llc < %s -mcpu=i486 | grep fstps | count 2
; PR1505
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
diff --git a/test/CodeGen/X86/pr3495.ll b/test/CodeGen/X86/pr3495.ll
index 1795970..e84a84f 100644
--- a/test/CodeGen/X86/pr3495.ll
+++ b/test/CodeGen/X86/pr3495.ll
@@ -1,8 +1,7 @@
; RUN: llc < %s -march=x86 -stats |& grep {Number of loads added} | grep 2
; RUN: llc < %s -march=x86 -stats |& grep {Number of register spills} | grep 1
-; RUN: llc < %s -march=x86 -stats |& grep {Number of machine instrs printed} | grep 38
+; RUN: llc < %s -march=x86 -stats |& grep {Number of machine instrs printed} | grep 34
; PR3495
-; The loop reversal kicks in once here, resulting in one fewer instruction.
target triple = "i386-pc-linux-gnu"
@x = external global [8 x i32], align 32 ; <[8 x i32]*> [#uses=1]
diff --git a/test/CodeGen/X86/pre-split8.ll b/test/CodeGen/X86/pre-split8.ll
index ea4b949..0684bd0 100644
--- a/test/CodeGen/X86/pre-split8.ll
+++ b/test/CodeGen/X86/pre-split8.ll
@@ -20,7 +20,7 @@ bb: ; preds = %bb9.i, %entry
bb9.i: ; preds = %bb
%2 = fsub double %.rle4, %0 ; <double> [#uses=0]
- %3 = tail call double @asin(double 0.000000e+00) nounwind readonly ; <double> [#uses=0]
+ %3 = tail call double @asin(double %.rle4) nounwind readonly ; <double> [#uses=0]
%4 = fmul double 0.000000e+00, %0 ; <double> [#uses=1]
%5 = tail call double @tan(double 0.000000e+00) nounwind readonly ; <double> [#uses=0]
%6 = fmul double %4, 0.000000e+00 ; <double> [#uses=1]
diff --git a/test/CodeGen/X86/pre-split9.ll b/test/CodeGen/X86/pre-split9.ll
index c27d925..86dda33 100644
--- a/test/CodeGen/X86/pre-split9.ll
+++ b/test/CodeGen/X86/pre-split9.ll
@@ -22,7 +22,7 @@ bb: ; preds = %bb9.i, %entry
bb9.i: ; preds = %bb
%2 = fsub double %.rle4, %0 ; <double> [#uses=0]
- %3 = tail call double @asin(double 0.000000e+00) nounwind readonly ; <double> [#uses=0]
+ %3 = tail call double @asin(double %.rle4) nounwind readonly ; <double> [#uses=0]
%4 = tail call double @sin(double 0.000000e+00) nounwind readonly ; <double> [#uses=1]
%5 = fmul double %4, %0 ; <double> [#uses=1]
%6 = tail call double @tan(double 0.000000e+00) nounwind readonly ; <double> [#uses=0]
diff --git a/test/CodeGen/X86/ptrtoint-constexpr.ll b/test/CodeGen/X86/ptrtoint-constexpr.ll
index 7e33e79..dd97905 100644
--- a/test/CodeGen/X86/ptrtoint-constexpr.ll
+++ b/test/CodeGen/X86/ptrtoint-constexpr.ll
@@ -6,3 +6,9 @@
; CHECK: .quad r&4294967295
@r = global %union.x { i64 ptrtoint (%union.x* @r to i64) }, align 4
+
+; CHECK: .globl x
+; CHECK: x:
+; CHECK: .quad 3
+
+@x = global i64 mul (i64 3, i64 ptrtoint (i2* getelementptr (i2* null, i64 1) to i64))
diff --git a/test/CodeGen/X86/scalar_widen_div.ll b/test/CodeGen/X86/scalar_widen_div.ll
index fc67e44..77f320f 100644
--- a/test/CodeGen/X86/scalar_widen_div.ll
+++ b/test/CodeGen/X86/scalar_widen_div.ll
@@ -152,3 +152,32 @@ define <5 x i64> @test_ulong_rem(<5 x i64> %num, <5 x i64> %rem) {
%rem.r = urem <5 x i64> %num, %rem
ret <5 x i64> %rem.r
}
+
+define void @test_int_div(<3 x i32>* %dest, <3 x i32>* %old, i32 %n) {
+; CHECK: idivl
+; CHECK: idivl
+; CHECK: idivl
+; CHECK-NOT: idivl
+; CHECK: ret
+entry:
+ %cmp13 = icmp sgt i32 %n, 0
+ br i1 %cmp13, label %bb.nph, label %for.end
+
+bb.nph:
+ br label %for.body
+
+for.body:
+ %i.014 = phi i32 [ 0, %bb.nph ], [ %inc, %for.body ]
+ %arrayidx11 = getelementptr <3 x i32>* %dest, i32 %i.014
+ %tmp4 = load <3 x i32>* %arrayidx11 ; <<3 x i32>> [#uses=1]
+ %arrayidx7 = getelementptr inbounds <3 x i32>* %old, i32 %i.014
+ %tmp8 = load <3 x i32>* %arrayidx7 ; <<3 x i32>> [#uses=1]
+ %div = sdiv <3 x i32> %tmp4, %tmp8
+ store <3 x i32> %div, <3 x i32>* %arrayidx11
+ %inc = add nsw i32 %i.014, 1
+ %exitcond = icmp eq i32 %inc, %n
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body, %entry
+ ret void
+}
diff --git a/test/CodeGen/X86/sext-i1.ll b/test/CodeGen/X86/sext-i1.ll
new file mode 100644
index 0000000..21c418d
--- /dev/null
+++ b/test/CodeGen/X86/sext-i1.ll
@@ -0,0 +1,63 @@
+; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=32
+; RUN: llc < %s -march=x86-64 | FileCheck %s -check-prefix=64
+; rdar://7573216
+; PR6146
+
+define i32 @t1(i32 %x) nounwind readnone ssp {
+entry:
+; 32: t1:
+; 32: cmpl $1
+; 32: sbbl
+
+; 64: t1:
+; 64: cmpl $1
+; 64: sbbl
+ %0 = icmp eq i32 %x, 0
+ %iftmp.0.0 = select i1 %0, i32 -1, i32 0
+ ret i32 %iftmp.0.0
+}
+
+define i32 @t2(i32 %x) nounwind readnone ssp {
+entry:
+; 32: t2:
+; 32: cmpl $1
+; 32: sbbl
+
+; 64: t2:
+; 64: cmpl $1
+; 64: sbbl
+ %0 = icmp eq i32 %x, 0
+ %iftmp.0.0 = sext i1 %0 to i32
+ ret i32 %iftmp.0.0
+}
+
+%struct.zbookmark = type { i64, i64 }
+%struct.zstream = type { }
+
+define i32 @t3() nounwind readonly {
+entry:
+; 32: t3:
+; 32: cmpl $1
+; 32: sbbl
+; 32: cmpl
+; 32: xorl
+
+; 64: t3:
+; 64: cmpl $1
+; 64: sbbq
+; 64: cmpq
+; 64: xorl
+ %not.tobool = icmp eq i32 undef, 0 ; <i1> [#uses=2]
+ %cond = sext i1 %not.tobool to i32 ; <i32> [#uses=1]
+ %conv = sext i1 %not.tobool to i64 ; <i64> [#uses=1]
+ %add13 = add i64 0, %conv ; <i64> [#uses=1]
+ %cmp = icmp ult i64 undef, %add13 ; <i1> [#uses=1]
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ %xor27 = xor i32 undef, %cond ; <i32> [#uses=0]
+ ret i32 0
+}
diff --git a/test/CodeGen/X86/sse3.ll b/test/CodeGen/X86/sse3.ll
index 5550d26..b2af7c9 100644
--- a/test/CodeGen/X86/sse3.ll
+++ b/test/CodeGen/X86/sse3.ll
@@ -63,10 +63,10 @@ define <8 x i16> @t4(<8 x i16> %A, <8 x i16> %B) nounwind {
ret <8 x i16> %tmp
; X64: t4:
; X64: pextrw $7, %xmm0, %eax
-; X64: pshufhw $100, %xmm0, %xmm1
-; X64: pinsrw $1, %eax, %xmm1
+; X64: pshufhw $100, %xmm0, %xmm2
+; X64: pinsrw $1, %eax, %xmm2
; X64: pextrw $1, %xmm0, %eax
-; X64: movaps %xmm1, %xmm0
+; X64: movaps %xmm2, %xmm0
; X64: pinsrw $4, %eax, %xmm0
; X64: ret
}
diff --git a/test/CodeGen/X86/stack-color-with-reg.ll b/test/CodeGen/X86/stack-color-with-reg.ll
index 7d85818..42e7a39 100644
--- a/test/CodeGen/X86/stack-color-with-reg.ll
+++ b/test/CodeGen/X86/stack-color-with-reg.ll
@@ -1,5 +1,5 @@
; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -relocation-model=pic -disable-fp-elim -color-ss-with-regs -stats -info-output-file - > %t
-; RUN: grep stackcoloring %t | grep "stack slot refs replaced with reg refs" | grep 14
+; RUN: grep stackcoloring %t | grep "stack slot refs replaced with reg refs" | grep 8
type { [62 x %struct.Bitvec*] } ; type %0
type { i8* } ; type %1
diff --git a/test/CodeGen/X86/stdcall.ll b/test/CodeGen/X86/stdcall.ll
new file mode 100644
index 0000000..70204bc
--- /dev/null
+++ b/test/CodeGen/X86/stdcall.ll
@@ -0,0 +1,16 @@
+; RUN: llc < %s | FileCheck %s
+; PR5851
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-mingw32"
+
+%0 = type { void (...)* }
+
+@B = global %0 { void (...)* bitcast (void ()* @MyFunc to void (...)*) }, align 4
+; CHECK: _B:
+; CHECK: .long _MyFunc@0
+
+define internal x86_stdcallcc void @MyFunc() nounwind {
+entry:
+ ret void
+}
diff --git a/test/CodeGen/Generic/switch-crit-edge-constant.ll b/test/CodeGen/X86/switch-crit-edge-constant.ll
index 1f2ab0d..1f2ab0d 100644
--- a/test/CodeGen/Generic/switch-crit-edge-constant.ll
+++ b/test/CodeGen/X86/switch-crit-edge-constant.ll
diff --git a/test/CodeGen/X86/tailcall1.ll b/test/CodeGen/X86/tailcall1.ll
index 42f8cdd..f7ff5d5 100644
--- a/test/CodeGen/X86/tailcall1.ll
+++ b/test/CodeGen/X86/tailcall1.ll
@@ -1,11 +1,14 @@
; RUN: llc < %s -march=x86 -tailcallopt | grep TAILCALL | count 5
+; With -tailcallopt, CodeGen guarantees a tail call optimization
+; for all of these.
+
declare fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4)
define fastcc i32 @tailcaller(i32 %in1, i32 %in2) nounwind {
entry:
- %tmp11 = tail call fastcc i32 @tailcallee(i32 %in1, i32 %in2, i32 %in1, i32 %in2)
- ret i32 %tmp11
+ %tmp11 = tail call fastcc i32 @tailcallee(i32 %in1, i32 %in2, i32 %in1, i32 %in2)
+ ret i32 %tmp11
}
declare fastcc i8* @alias_callee()
diff --git a/test/CodeGen/X86/tailcall2.ll b/test/CodeGen/X86/tailcall2.ll
new file mode 100644
index 0000000..80bab61
--- /dev/null
+++ b/test/CodeGen/X86/tailcall2.ll
@@ -0,0 +1,197 @@
+; RUN: llc < %s -march=x86 -asm-verbose=false | FileCheck %s -check-prefix=32
+; RUN: llc < %s -march=x86-64 -asm-verbose=false | FileCheck %s -check-prefix=64
+
+define void @t1(i32 %x) nounwind ssp {
+entry:
+; 32: t1:
+; 32: jmp {{_?}}foo
+
+; 64: t1:
+; 64: jmp {{_?}}foo
+ tail call void @foo() nounwind
+ ret void
+}
+
+declare void @foo()
+
+define void @t2() nounwind ssp {
+entry:
+; 32: t2:
+; 32: jmp {{_?}}foo2
+
+; 64: t2:
+; 64: jmp {{_?}}foo2
+ %0 = tail call i32 @foo2() nounwind
+ ret void
+}
+
+declare i32 @foo2()
+
+define void @t3() nounwind ssp {
+entry:
+; 32: t3:
+; 32: jmp {{_?}}foo3
+
+; 64: t3:
+; 64: jmp {{_?}}foo3
+ %0 = tail call i32 @foo3() nounwind
+ ret void
+}
+
+declare i32 @foo3()
+
+define void @t4(void (i32)* nocapture %x) nounwind ssp {
+entry:
+; 32: t4:
+; 32: call *
+; FIXME: gcc can generate a tailcall for this. But it's tricky.
+
+; 64: t4:
+; 64-NOT: call
+; 64: jmpq *
+ tail call void %x(i32 0) nounwind
+ ret void
+}
+
+define void @t5(void ()* nocapture %x) nounwind ssp {
+entry:
+; 32: t5:
+; 32-NOT: call
+; 32: jmpl *
+
+; 64: t5:
+; 64-NOT: call
+; 64: jmpq *
+ tail call void %x() nounwind
+ ret void
+}
+
+define i32 @t6(i32 %x) nounwind ssp {
+entry:
+; 32: t6:
+; 32: call {{_?}}t6
+; 32: jmp {{_?}}bar
+
+; 64: t6:
+; 64: jmp {{_?}}t6
+; 64: jmp {{_?}}bar
+ %0 = icmp slt i32 %x, 10
+ br i1 %0, label %bb, label %bb1
+
+bb:
+ %1 = add nsw i32 %x, -1
+ %2 = tail call i32 @t6(i32 %1) nounwind ssp
+ ret i32 %2
+
+bb1:
+ %3 = tail call i32 @bar(i32 %x) nounwind
+ ret i32 %3
+}
+
+declare i32 @bar(i32)
+
+define i32 @t7(i32 %a, i32 %b, i32 %c) nounwind ssp {
+entry:
+; 32: t7:
+; 32: jmp {{_?}}bar2
+
+; 64: t7:
+; 64: jmp {{_?}}bar2
+ %0 = tail call i32 @bar2(i32 %a, i32 %b, i32 %c) nounwind
+ ret i32 %0
+}
+
+declare i32 @bar2(i32, i32, i32)
+
+define signext i16 @t8() nounwind ssp {
+entry:
+; 32: t8:
+; 32: call {{_?}}bar3
+
+; 64: t8:
+; 64: callq {{_?}}bar3
+ %0 = tail call signext i16 @bar3() nounwind ; <i16> [#uses=1]
+ ret i16 %0
+}
+
+declare signext i16 @bar3()
+
+define signext i16 @t9(i32 (i32)* nocapture %x) nounwind ssp {
+entry:
+; 32: t9:
+; 32: call *
+
+; 64: t9:
+; 64: callq *
+ %0 = bitcast i32 (i32)* %x to i16 (i32)*
+ %1 = tail call signext i16 %0(i32 0) nounwind
+ ret i16 %1
+}
+
+define void @t10() nounwind ssp {
+entry:
+; 32: t10:
+; 32: call
+
+; 64: t10:
+; 64: callq
+ %0 = tail call i32 @foo4() noreturn nounwind
+ unreachable
+}
+
+declare i32 @foo4()
+
+define i32 @t11(i32 %x, i32 %y, i32 %z.0, i32 %z.1, i32 %z.2) nounwind ssp {
+; In 32-bit mode, it's emitting a bunch of dead loads that are not being
+; eliminated currently.
+
+; 32: t11:
+; 32-NOT: subl ${{[0-9]+}}, %esp
+; 32: jne
+; 32-NOT: movl
+; 32-NOT: addl ${{[0-9]+}}, %esp
+; 32: jmp {{_?}}foo5
+
+; 64: t11:
+; 64-NOT: subq ${{[0-9]+}}, %esp
+; 64-NOT: addq ${{[0-9]+}}, %esp
+; 64: jmp {{_?}}foo5
+entry:
+ %0 = icmp eq i32 %x, 0
+ br i1 %0, label %bb6, label %bb
+
+bb:
+ %1 = tail call i32 @foo5(i32 %x, i32 %y, i32 %z.0, i32 %z.1, i32 %z.2) nounwind
+ ret i32 %1
+
+bb6:
+ ret i32 0
+}
+
+declare i32 @foo5(i32, i32, i32, i32, i32)
+
+%struct.t = type { i32, i32, i32, i32, i32 }
+
+define i32 @t12(i32 %x, i32 %y, %struct.t* byval align 4 %z) nounwind ssp {
+; 32: t12:
+; 32-NOT: subl ${{[0-9]+}}, %esp
+; 32-NOT: addl ${{[0-9]+}}, %esp
+; 32: jmp {{_?}}foo6
+
+; 64: t12:
+; 64-NOT: subq ${{[0-9]+}}, %esp
+; 64-NOT: addq ${{[0-9]+}}, %esp
+; 64: jmp {{_?}}foo6
+entry:
+ %0 = icmp eq i32 %x, 0
+ br i1 %0, label %bb2, label %bb
+
+bb:
+ %1 = tail call i32 @foo6(i32 %x, i32 %y, %struct.t* byval align 4 %z) nounwind
+ ret i32 %1
+
+bb2:
+ ret i32 0
+}
+
+declare i32 @foo6(i32, i32, %struct.t* byval align 4)
diff --git a/test/CodeGen/X86/tailcallfp2.ll b/test/CodeGen/X86/tailcallfp2.ll
index be4f96c..3841f51 100644
--- a/test/CodeGen/X86/tailcallfp2.ll
+++ b/test/CodeGen/X86/tailcallfp2.ll
@@ -2,7 +2,7 @@
declare i32 @putchar(i32)
-define fastcc i32 @checktail(i32 %x, i32* %f, i32 %g) {
+define fastcc i32 @checktail(i32 %x, i32* %f, i32 %g) nounwind {
%tmp1 = icmp sgt i32 %x, 0
br i1 %tmp1, label %if-then, label %if-else
@@ -18,8 +18,8 @@ if-else:
}
-define i32 @main() {
+define i32 @main() nounwind {
%f = bitcast i32 (i32, i32*, i32)* @checktail to i32*
%res = tail call fastcc i32 @checktail( i32 10, i32* %f,i32 10)
ret i32 %res
-} \ No newline at end of file
+}
diff --git a/test/CodeGen/X86/twoaddr-coalesce.ll b/test/CodeGen/X86/twoaddr-coalesce.ll
index d0e13f6..4c37225 100644
--- a/test/CodeGen/X86/twoaddr-coalesce.ll
+++ b/test/CodeGen/X86/twoaddr-coalesce.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=x86 | grep mov | count 5
+; RUN: llc < %s -march=x86 | grep mov | count 4
; rdar://6523745
@"\01LC" = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1]
diff --git a/test/CodeGen/X86/vsplit-and.ll b/test/CodeGen/X86/vsplit-and.ll
new file mode 100644
index 0000000..a247c6e
--- /dev/null
+++ b/test/CodeGen/X86/vsplit-and.ll
@@ -0,0 +1,22 @@
+; RUN: llc < %s -march=x86 -disable-mmx | FileCheck %s
+
+
+define void @t(<2 x i64>* %dst, <2 x i64> %src1, <2 x i64> %src2) nounwind readonly {
+; CHECK: andb
+ %cmp1 = icmp ne <2 x i64> %src1, zeroinitializer
+ %cmp2 = icmp ne <2 x i64> %src2, zeroinitializer
+ %t1 = and <2 x i1> %cmp1, %cmp2
+ %t2 = sext <2 x i1> %t1 to <2 x i64>
+ store <2 x i64> %t2, <2 x i64>* %dst
+ ret void
+}
+
+define void @t2(<3 x i64>* %dst, <3 x i64> %src1, <3 x i64> %src2) nounwind readonly {
+; CHECK: andb
+ %cmp1 = icmp ne <3 x i64> %src1, zeroinitializer
+ %cmp2 = icmp ne <3 x i64> %src2, zeroinitializer
+ %t1 = and <3 x i1> %cmp1, %cmp2
+ %t2 = sext <3 x i1> %t1 to <3 x i64>
+ store <3 x i64> %t2, <3 x i64>* %dst
+ ret void
+}
diff --git a/test/CodeGen/X86/widen_cast-2.ll b/test/CodeGen/X86/widen_cast-2.ll
index e5d2c6a..1e626a2 100644
--- a/test/CodeGen/X86/widen_cast-2.ll
+++ b/test/CodeGen/X86/widen_cast-2.ll
@@ -2,10 +2,8 @@
; CHECK: pextrd
; CHECK: pextrd
; CHECK: movd
-; CHECK: pextrd
-; CHECK: pextrd
-; CHECK: pextrd
-; CHECK: movd
+; CHECK: movaps
+
; bitcast v14i16 to v7i32
diff --git a/test/CodeGen/X86/widen_load-1.ll b/test/CodeGen/X86/widen_load-1.ll
index 8a970bf..d397645 100644
--- a/test/CodeGen/X86/widen_load-1.ll
+++ b/test/CodeGen/X86/widen_load-1.ll
@@ -3,7 +3,7 @@
; This load should be before the call, not after.
-; CHECK: movq compl+128(%rip), %xmm0
+; CHECK: movaps compl+128(%rip), %xmm0
; CHECK: movaps %xmm0, (%rsp)
; CHECK: callq killcommon
diff --git a/test/CodeGen/X86/widen_load-2.ll b/test/CodeGen/X86/widen_load-2.ll
new file mode 100644
index 0000000..11383fa
--- /dev/null
+++ b/test/CodeGen/X86/widen_load-2.ll
@@ -0,0 +1,155 @@
+; RUN: llc < %s -o - -march=x86-64 -mattr=+sse42 -disable-mmx | FileCheck %s
+
+; Test based on pr5626 to load/store
+;
+
+%i32vec3 = type <3 x i32>
+define void @add3i32(%i32vec3* sret %ret, %i32vec3* %ap, %i32vec3* %bp) {
+; CHECK: movaps
+; CHECK: paddd
+; CHECK: pextrd
+; CHECK: movq
+ %a = load %i32vec3* %ap, align 16
+ %b = load %i32vec3* %bp, align 16
+ %x = add %i32vec3 %a, %b
+ store %i32vec3 %x, %i32vec3* %ret, align 16
+ ret void
+}
+
+define void @add3i32_2(%i32vec3* sret %ret, %i32vec3* %ap, %i32vec3* %bp) {
+; CHECK: movq
+; CHECK: pinsrd
+; CHECK: movq
+; CHECK: pinsrd
+; CHECK: paddd
+; CHECK: pextrd
+; CHECK: movq
+ %a = load %i32vec3* %ap
+ %b = load %i32vec3* %bp
+ %x = add %i32vec3 %a, %b
+ store %i32vec3 %x, %i32vec3* %ret
+ ret void
+}
+
+%i32vec7 = type <7 x i32>
+define void @add7i32(%i32vec7* sret %ret, %i32vec7* %ap, %i32vec7* %bp) {
+; CHECK: movaps
+; CHECK: movaps
+; CHECK: paddd
+; CHECK: paddd
+; CHECK: pextrd
+; CHECK: movq
+; CHECK: movaps
+ %a = load %i32vec7* %ap, align 16
+ %b = load %i32vec7* %bp, align 16
+ %x = add %i32vec7 %a, %b
+ store %i32vec7 %x, %i32vec7* %ret, align 16
+ ret void
+}
+
+%i32vec12 = type <12 x i32>
+define void @add12i32(%i32vec12* sret %ret, %i32vec12* %ap, %i32vec12* %bp) {
+; CHECK: movaps
+; CHECK: movaps
+; CHECK: movaps
+; CHECK: paddd
+; CHECK: paddd
+; CHECK: paddd
+; CHECK: movaps
+; CHECK: movaps
+; CHECK: movaps
+ %a = load %i32vec12* %ap, align 16
+ %b = load %i32vec12* %bp, align 16
+ %x = add %i32vec12 %a, %b
+ store %i32vec12 %x, %i32vec12* %ret, align 16
+ ret void
+}
+
+
+%i16vec3 = type <3 x i16>
+define void @add3i16(%i16vec3* nocapture sret %ret, %i16vec3* %ap, %i16vec3* %bp) nounwind {
+; CHECK: movaps
+; CHECK: paddw
+; CHECK: movd
+; CHECK: pextrw
+ %a = load %i16vec3* %ap, align 16
+ %b = load %i16vec3* %bp, align 16
+ %x = add %i16vec3 %a, %b
+ store %i16vec3 %x, %i16vec3* %ret, align 16
+ ret void
+}
+
+%i16vec4 = type <4 x i16>
+define void @add4i16(%i16vec4* nocapture sret %ret, %i16vec4* %ap, %i16vec4* %bp) nounwind {
+; CHECK: movaps
+; CHECK: paddw
+; CHECK: movq
+ %a = load %i16vec4* %ap, align 16
+ %b = load %i16vec4* %bp, align 16
+ %x = add %i16vec4 %a, %b
+ store %i16vec4 %x, %i16vec4* %ret, align 16
+ ret void
+}
+
+%i16vec12 = type <12 x i16>
+define void @add12i16(%i16vec12* nocapture sret %ret, %i16vec12* %ap, %i16vec12* %bp) nounwind {
+; CHECK: movaps
+; CHECK: movaps
+; CHECK: paddw
+; CHECK: paddw
+; CHECK: movq
+; CHECK: movaps
+ %a = load %i16vec12* %ap, align 16
+ %b = load %i16vec12* %bp, align 16
+ %x = add %i16vec12 %a, %b
+ store %i16vec12 %x, %i16vec12* %ret, align 16
+ ret void
+}
+
+%i16vec18 = type <18 x i16>
+define void @add18i16(%i16vec18* nocapture sret %ret, %i16vec18* %ap, %i16vec18* %bp) nounwind {
+; CHECK: movaps
+; CHECK: movaps
+; CHECK: movaps
+; CHECK: paddw
+; CHECK: paddw
+; CHECK: paddw
+; CHECK: movd
+; CHECK: movaps
+; CHECK: movaps
+ %a = load %i16vec18* %ap, align 16
+ %b = load %i16vec18* %bp, align 16
+ %x = add %i16vec18 %a, %b
+ store %i16vec18 %x, %i16vec18* %ret, align 16
+ ret void
+}
+
+
+%i8vec3 = type <3 x i8>
+define void @add3i8(%i8vec3* nocapture sret %ret, %i8vec3* %ap, %i8vec3* %bp) nounwind {
+; CHECK: movaps
+; CHECK: paddb
+; CHECK: pextrb
+; CHECK: movb
+ %a = load %i8vec3* %ap, align 16
+ %b = load %i8vec3* %bp, align 16
+ %x = add %i8vec3 %a, %b
+ store %i8vec3 %x, %i8vec3* %ret, align 16
+ ret void
+}
+
+%i8vec31 = type <31 x i8>
+define void @add31i8(%i8vec31* nocapture sret %ret, %i8vec31* %ap, %i8vec31* %bp) nounwind {
+; CHECK: movaps
+; CHECK: movaps
+; CHECK: paddb
+; CHECK: paddb
+; CHECK: movq
+; CHECK: pextrb
+; CHECK: pextrw
+ %a = load %i8vec31* %ap, align 16
+ %b = load %i8vec31* %bp, align 16
+ %x = add %i8vec31 %a, %b
+ store %i8vec31 %x, %i8vec31* %ret, align 16
+ ret void
+} \ No newline at end of file
diff --git a/test/CodeGen/X86/zext-trunc.ll b/test/CodeGen/X86/zext-trunc.ll
new file mode 100644
index 0000000..b9ffbe8
--- /dev/null
+++ b/test/CodeGen/X86/zext-trunc.ll
@@ -0,0 +1,13 @@
+; RUN: llc < %s -march=x86-64 | FileCheck %s
+; rdar://7570931
+
+define i64 @foo(i64 %a, i64 %b) nounwind {
+; CHECK: foo:
+; CHECK: leal
+; CHECK-NOT: movl
+; CHECK: ret
+ %c = add i64 %a, %b
+ %d = trunc i64 %c to i32
+ %e = zext i32 %d to i64
+ ret i64 %e
+}
diff --git a/test/CodeGen/XCore/ashr.ll b/test/CodeGen/XCore/ashr.ll
index d585e8b..d99808f 100644
--- a/test/CodeGen/XCore/ashr.ll
+++ b/test/CodeGen/XCore/ashr.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=xcore | FileCheck %s
+; RUN: llc < %s -march=xcore -asm-verbose=0 | FileCheck %s
define i32 @ashr(i32 %a, i32 %b) {
%1 = ashr i32 %a, %b
ret i32 %1
diff --git a/test/DebugInfo/2010-01-18-DbgValue.ll b/test/DebugInfo/2010-01-18-DbgValue.ll
new file mode 100644
index 0000000..ff97b18
--- /dev/null
+++ b/test/DebugInfo/2010-01-18-DbgValue.ll
@@ -0,0 +1,55 @@
+; RUN: llc -O0 < %s | FileCheck %s
+; ModuleID = 'try.c'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
+target triple = "i386-apple-darwin9.8"
+; Currently, dbg.declare generates a DEBUG_VALUE comment. Eventually it will
+; generate DWARF and this test will need to be modified or removed.
+
+@Y = common global i32 0 ; <i32*> [#uses=1]
+
+define i32 @test() nounwind {
+entry:
+; CHECK: DEBUG_VALUE:
+ %retval = alloca i32 ; <i32*> [#uses=2]
+ %X = alloca i32 ; <i32*> [#uses=5]
+ %0 = alloca i32 ; <i32*> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ call void @llvm.dbg.declare(metadata !{i32* %X}, metadata !3), !dbg !7
+ store i32 4, i32* %X, align 4, !dbg !8
+ %1 = load i32* %X, align 4, !dbg !9 ; <i32> [#uses=1]
+ call void @use(i32 %1) nounwind, !dbg !9
+ %2 = load i32* @Y, align 4, !dbg !10 ; <i32> [#uses=1]
+ %3 = add nsw i32 %2, 2, !dbg !10 ; <i32> [#uses=1]
+ store i32 %3, i32* %X, align 4, !dbg !10
+ %4 = load i32* %X, align 4, !dbg !11 ; <i32> [#uses=1]
+ call void @use(i32 %4) nounwind, !dbg !11
+ %5 = load i32* %X, align 4, !dbg !12 ; <i32> [#uses=1]
+ store i32 %5, i32* %0, align 4, !dbg !12
+ %6 = load i32* %0, align 4, !dbg !12 ; <i32> [#uses=1]
+ store i32 %6, i32* %retval, align 4, !dbg !12
+ br label %return, !dbg !12
+
+return: ; preds = %entry
+ %retval1 = load i32* %retval, !dbg !12 ; <i32> [#uses=1]
+ ret i32 %retval1, !dbg !12
+}
+
+declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
+
+declare void @use(i32)
+
+!llvm.dbg.gv = !{!0}
+
+!0 = metadata !{i32 458804, i32 0, metadata !1, metadata !"Y", metadata !"Y", metadata !"Y", metadata !1, i32 2, metadata !2, i1 false, i1 true, i32* @Y} ; [ DW_TAG_variable ]
+!1 = metadata !{i32 458769, i32 0, i32 1, metadata !"try.c", metadata !"/Volumes/MacOS9/tests/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
+!2 = metadata !{i32 458788, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
+!3 = metadata !{i32 459008, metadata !4, metadata !"X", metadata !1, i32 4, metadata !2} ; [ DW_TAG_auto_variable ]
+!4 = metadata !{i32 458798, i32 0, metadata !1, metadata !"", metadata !"", metadata !"test", metadata !1, i32 3, metadata !5, i1 false, i1 true, i32 0, i32 0, null} ; [ DW_TAG_subprogram ]
+!5 = metadata !{i32 458773, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !6, i32 0} ; [ DW_TAG_subroutine_type ]
+!6 = metadata !{metadata !2}
+!7 = metadata !{i32 3, i32 0, metadata !4, null}
+!8 = metadata !{i32 4, i32 0, metadata !4, null}
+!9 = metadata !{i32 5, i32 0, metadata !4, null}
+!10 = metadata !{i32 6, i32 0, metadata !4, null}
+!11 = metadata !{i32 7, i32 0, metadata !4, null}
+!12 = metadata !{i32 8, i32 0, metadata !4, null}
diff --git a/test/DebugInfo/2010-02-01-DbgValueCrash.ll b/test/DebugInfo/2010-02-01-DbgValueCrash.ll
new file mode 100644
index 0000000..70103e5
--- /dev/null
+++ b/test/DebugInfo/2010-02-01-DbgValueCrash.ll
@@ -0,0 +1,34 @@
+; RUN: llc -O1 < %s
+; ModuleID = 'pr6157.bc'
+target triple = "x86_64-unknown-linux-gnu"
+; formerly crashed in SelectionDAGBuilder
+
+%tart.reflect.ComplexType = type { double, double }
+
+@.type.SwitchStmtTest = constant %tart.reflect.ComplexType { double 3.0, double 2.0 }
+
+define i32 @"main(tart.core.String[])->int32"(i32 %args) {
+entry:
+ tail call void @llvm.dbg.value(metadata !14, i64 0, metadata !8)
+ tail call void @"tart.reflect.ComplexType.create->tart.core.Object"(%tart.reflect.ComplexType* @.type.SwitchStmtTest) ; <%tart.core.Object*> [#uses=2]
+ ret i32 3
+}
+
+declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
+declare void @"tart.reflect.ComplexType.create->tart.core.Object"(%tart.reflect.ComplexType*) nounwind readnone
+
+!0 = metadata !{i32 458769, i32 0, i32 1, metadata !"sm.c", metadata !"/Volumes/MacOS9/tests/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
+!1 = metadata !{i32 458790, metadata !0, metadata !"", metadata !0, i32 0, i64 192, i64 64, i64 0, i32 0, metadata !2} ; [ DW_TAG_const_type ]
+!2 = metadata !{i32 458771, metadata !0, metadata !"C", metadata !0, i32 1, i64 192, i64 64, i64 0, i32 0, null, metadata !3, i32 0, null} ; [ DW_TAG_structure_type ]
+!3 = metadata !{metadata !4, metadata !6, metadata !7}
+!4 = metadata !{i32 458765, metadata !2, metadata !"x", metadata !0, i32 1, i64 64, i64 64, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ]
+!5 = metadata !{i32 458788, metadata !0, metadata !"double", metadata !0, i32 0, i64 64, i64 64, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ]
+!6 = metadata !{i32 458765, metadata !2, metadata !"y", metadata !0, i32 1, i64 64, i64 64, i64 64, i32 0, metadata !5} ; [ DW_TAG_member ]
+!7 = metadata !{i32 458765, metadata !2, metadata !"z", metadata !0, i32 1, i64 64, i64 64, i64 128, i32 0, metadata !5} ; [ DW_TAG_member ]
+!8 = metadata !{i32 459008, metadata !9, metadata !"t", metadata !0, i32 5, metadata !2} ; [ DW_TAG_auto_variable ]
+!9 = metadata !{i32 458763, metadata !10} ; [ DW_TAG_lexical_block ]
+!10 = metadata !{i32 458798, i32 0, metadata !0, metadata !"foo", metadata !"foo", metadata !"foo", metadata !0, i32 4, metadata !11, i1 false, i1 true, i32 0, i32 0, null} ; [ DW_TAG_subprogram ]
+!11 = metadata !{i32 458773, metadata !0, metadata !"", metadata !0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !12, i32 0, null} ; [ DW_TAG_subroutine_type ]
+!12 = metadata !{metadata !13}
+!13 = metadata !{i32 458788, metadata !0, metadata !"int", metadata !0, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
+!14 = metadata !{%tart.reflect.ComplexType* @.type.SwitchStmtTest}
diff --git a/test/Feature/alignment.ll b/test/Feature/alignment.ll
index 409efeb..ef35a13 100644
--- a/test/Feature/alignment.ll
+++ b/test/Feature/alignment.ll
@@ -19,3 +19,7 @@ define i32* @test2() {
ret i32* %X
}
+define void @test3() alignstack(16) {
+ ret void
+}
+
diff --git a/test/Feature/unions.ll b/test/Feature/unions.ll
new file mode 100644
index 0000000..9d6c36b
--- /dev/null
+++ b/test/Feature/unions.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llvm-dis > %t1.ll
+; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
+; RUN: diff %t1.ll %t2.ll
+
+%union.anon = type union { i8, i32, float }
+
+@union1 = constant union { i32, i8 } { i32 4 }
+@union2 = constant union { i32, i8 } insertvalue(union { i32, i8 } undef, i32 4, 0)
+
+define void @"Unions" () {
+ ret void
+}
diff --git a/test/FrontendC++/2006-11-06-StackTrace.cpp b/test/FrontendC++/2006-11-06-StackTrace.cpp
index 3732cb9..b79c0bf 100644
--- a/test/FrontendC++/2006-11-06-StackTrace.cpp
+++ b/test/FrontendC++/2006-11-06-StackTrace.cpp
@@ -5,14 +5,14 @@
// RUN: %compile_c %t.s -o %t.o
// RUN: %link %t.o -o %t.exe
// RUN: echo {break DeepStack::deepest\nrun 17\nwhere\n} > %t.in
-// RUN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | \
-// RUN: grep {#0 DeepStack::deepest.*(this=.*,.*x=33)}
-// RUN: gdb -q -batch -n -x %t.in %t.exe | \
-// RUN: grep {#7 0x.* in main.*(argc=\[12\],.*argv=.*)}
+// RN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | \
+// RN: grep {#0 DeepStack::deepest.*(this=.*,.*x=33)}
+// RN: gdb -q -batch -n -x %t.in %t.exe | \
+// RN: grep {#7 0x.* in main.*(argc=\[12\],.*argv=.*)}
// Only works on ppc (but not apple-darwin9), x86 and x86_64. Should
// generalize?
-// XFAIL: alpha,arm,powerpc-apple-darwin9
+// XAIL: alpha,arm,powerpc-apple-darwin9
#include <stdlib.h>
diff --git a/test/FrontendC++/2006-11-30-Pubnames.cpp b/test/FrontendC++/2006-11-30-Pubnames.cpp
index 3a08b3c..239d3f5 100644
--- a/test/FrontendC++/2006-11-30-Pubnames.cpp
+++ b/test/FrontendC++/2006-11-30-Pubnames.cpp
@@ -8,9 +8,7 @@
// RUN: echo {break main\nrun\np Pubnames::pubname} > %t.in
// RUN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | grep {\$1 = 10}
//
-// XFAIL: alpha,arm,powerpc-apple-darwin
-// FIXME: This doesn't work for PPC Darwin because we turned off debugging on
-// that platform.
+// XFAIL: alpha,arm
struct Pubnames {
static int pubname;
diff --git a/test/FrontendC++/2010-02-08-NamespaceVar.cpp b/test/FrontendC++/2010-02-08-NamespaceVar.cpp
new file mode 100644
index 0000000..cd8247a
--- /dev/null
+++ b/test/FrontendC++/2010-02-08-NamespaceVar.cpp
@@ -0,0 +1,16 @@
+// RUN: %llvmgxx -S %s -o - | grep cX
+
+namespace C {
+ int c = 1;
+ namespace {
+ int cX = 6;
+ void marker2() {
+ cX;
+ }
+ }
+}
+
+int main() {
+ C::marker2();
+ return 0;
+}
diff --git a/test/FrontendC/2003-12-14-ExternInlineSupport.c b/test/FrontendC/2003-12-14-ExternInlineSupport.c
index fb92ec7..510d1f8 100644
--- a/test/FrontendC/2003-12-14-ExternInlineSupport.c
+++ b/test/FrontendC/2003-12-14-ExternInlineSupport.c
@@ -1,3 +1,3 @@
-// RUN: %llvmgcc -xc %s -c -o - | llvm-dis | not grep dead_function
+// RUN: %llvmgcc -Os -xc %s -c -o - | llvm-dis | not grep dead_function
extern __inline__ void dead_function() {}
diff --git a/test/FrontendC/2007-02-16-WritableStrings.c b/test/FrontendC/2007-02-16-WritableStrings.c
index 811e330..0f281ce 100644
--- a/test/FrontendC/2007-02-16-WritableStrings.c
+++ b/test/FrontendC/2007-02-16-WritableStrings.c
@@ -1,7 +1,7 @@
// Test the -fwritable-strings option.
// RUN: %llvmgcc -O3 -S -o - -emit-llvm -fwritable-strings %s | \
-// RUN: grep {private global}
+// RUN: grep {internal global}
// RUN: %llvmgcc -O3 -S -o - -emit-llvm %s | grep {private constant}
char *X = "foo";
diff --git a/test/FrontendC/2009-02-17-BitField-dbg.c b/test/FrontendC/2009-02-17-BitField-dbg.c
index 3effd02..80ccc4a 100644
--- a/test/FrontendC/2009-02-17-BitField-dbg.c
+++ b/test/FrontendC/2009-02-17-BitField-dbg.c
@@ -6,9 +6,6 @@
// RUN: gdb -q -batch -n -x %t2 2009-02-17-BitField-dbg.o | \
// RUN: tee 2009-02-17-BitField-dbg.out | grep "int a : 4"
//
-// XFAIL: powerpc-apple-darwin
-// FIXME: This doesn't work for PPC Darwin because we turned off debugging on
-// that platform.
struct {
int a:4;
diff --git a/test/FrontendC/2010-01-13-MemBarrier.c b/test/FrontendC/2010-01-13-MemBarrier.c
index 53d0081..8fcd522 100644
--- a/test/FrontendC/2010-01-13-MemBarrier.c
+++ b/test/FrontendC/2010-01-13-MemBarrier.c
@@ -1,5 +1,5 @@
// RUN: %llvmgcc %s -S -emit-llvm -o - | FileCheck %s
-// XFAIL: sparc,powerpc
+// XFAIL: sparc
// rdar://7536390
unsigned t(unsigned *ptr, unsigned val) {
diff --git a/test/FrontendC/2010-02-10-PointerName.c b/test/FrontendC/2010-02-10-PointerName.c
new file mode 100644
index 0000000..7880fa8
--- /dev/null
+++ b/test/FrontendC/2010-02-10-PointerName.c
@@ -0,0 +1,7 @@
+// RUN: %llvmgcc %s -S -g -o - | grep DW_TAG_pointer_type | grep -v char
+
+char i = 1;
+void foo() {
+ char *cp = &i;
+}
+
diff --git a/test/FrontendObjC/2010-02-01-utf16-with-null.m b/test/FrontendObjC/2010-02-01-utf16-with-null.m
new file mode 100644
index 0000000..86e4637
--- /dev/null
+++ b/test/FrontendObjC/2010-02-01-utf16-with-null.m
@@ -0,0 +1,5 @@
+/* RUN: %llvmgcc -w -x objective-c -S %s -o - | not grep {__ustring}
+ rdar://7589850 */
+
+void *P = @"good\0bye";
+
diff --git a/test/FrontendObjC/2010-02-11-fwritable-stringsBug.m b/test/FrontendObjC/2010-02-11-fwritable-stringsBug.m
new file mode 100644
index 0000000..13e1631
--- /dev/null
+++ b/test/FrontendObjC/2010-02-11-fwritable-stringsBug.m
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc -x objective-c -fwritable-strings -S %s -o - | FileCheck %s
+// CHECK: @.str = private constant
+// CHECK: @.str1 = internal global
+
+// rdar://7634471
+
+@class NSString;
+
+@interface A
+- (void)foo:(NSString*)msg;
+- (void)bar:(const char*)msg;
+@end
+
+void func(A *a) {
+ [a foo:@"Hello world!"];
+ [a bar:"Goodbye world!"];
+}
diff --git a/test/LLVMC/MultiplePluginPriorities.td b/test/LLVMC/MultiplePluginPriorities.td
index 721b7cc..f108641 100644
--- a/test/LLVMC/MultiplePluginPriorities.td
+++ b/test/LLVMC/MultiplePluginPriorities.td
@@ -1,6 +1,9 @@
// Check that multiple plugin priorities are not allowed.
// RUN: ignore tblgen -I %p/../../include --gen-llvmc %s |& grep "More than one 'PluginPriority' instance found"
+// Disable for Darwin PPC: <rdar://problem/7598390>
+// XFAIL: powerpc-apple-darwin
+
include "llvm/CompilerDriver/Common.td"
def Graph : CompilationGraph<[]>;
diff --git a/test/MC/AsmParser/X86/dg.exp b/test/MC/AsmParser/X86/dg.exp
index 629a147..ec87b69 100644
--- a/test/MC/AsmParser/X86/dg.exp
+++ b/test/MC/AsmParser/X86/dg.exp
@@ -1,5 +1,5 @@
load_lib llvm.exp
if { [llvm_supports_target X86] } {
- RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
+ RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp,s}]]
}
diff --git a/test/MC/AsmParser/X86/x86_32-bit.s b/test/MC/AsmParser/X86/x86_32-bit.s
new file mode 100644
index 0000000..90e97be
--- /dev/null
+++ b/test/MC/AsmParser/X86/x86_32-bit.s
@@ -0,0 +1,1630 @@
+// RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+
+// CHECK: movb $127, 3735928559(%ebx,%ecx,8)
+ movb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movw $31438, 3735928559(%ebx,%ecx,8)
+ movw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movl $2063514302, 3735928559(%ebx,%ecx,8)
+ movl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movl $324478056, 3735928559(%ebx,%ecx,8)
+ movl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movsbl 3735928559(%ebx,%ecx,8), %ecx
+ movsbl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movswl 3735928559(%ebx,%ecx,8), %ecx
+ movswl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movzbl 3735928559(%ebx,%ecx,8), %ecx # NOREX
+ movzbl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movzwl 3735928559(%ebx,%ecx,8), %ecx
+ movzwl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: pushl 3735928559(%ebx,%ecx,8)
+ pushl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: popl 3735928559(%ebx,%ecx,8)
+ popl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: lahf
+ lahf
+
+// CHECK: sahf
+ sahf
+
+// CHECK: addb $254, 3735928559(%ebx,%ecx,8)
+ addb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addb $127, 3735928559(%ebx,%ecx,8)
+ addb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addw $31438, 3735928559(%ebx,%ecx,8)
+ addw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addl $2063514302, 3735928559(%ebx,%ecx,8)
+ addl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addl $324478056, 3735928559(%ebx,%ecx,8)
+ addl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: incl 3735928559(%ebx,%ecx,8)
+ incl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subb $254, 3735928559(%ebx,%ecx,8)
+ subb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subb $127, 3735928559(%ebx,%ecx,8)
+ subb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subw $31438, 3735928559(%ebx,%ecx,8)
+ subw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subl $2063514302, 3735928559(%ebx,%ecx,8)
+ subl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subl $324478056, 3735928559(%ebx,%ecx,8)
+ subl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: decl 3735928559(%ebx,%ecx,8)
+ decl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbw $31438, 3735928559(%ebx,%ecx,8)
+ sbbw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbl $2063514302, 3735928559(%ebx,%ecx,8)
+ sbbl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbl $324478056, 3735928559(%ebx,%ecx,8)
+ sbbl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpb $254, 3735928559(%ebx,%ecx,8)
+ cmpb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpb $127, 3735928559(%ebx,%ecx,8)
+ cmpb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpw $31438, 3735928559(%ebx,%ecx,8)
+ cmpw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpl $2063514302, 3735928559(%ebx,%ecx,8)
+ cmpl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpl $324478056, 3735928559(%ebx,%ecx,8)
+ cmpl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testb $127, 3735928559(%ebx,%ecx,8)
+ testb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testw $31438, 3735928559(%ebx,%ecx,8)
+ testw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testl $2063514302, 3735928559(%ebx,%ecx,8)
+ testl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testl $324478056, 3735928559(%ebx,%ecx,8)
+ testl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andb $254, 3735928559(%ebx,%ecx,8)
+ andb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andb $127, 3735928559(%ebx,%ecx,8)
+ andb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andw $31438, 3735928559(%ebx,%ecx,8)
+ andw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andl $2063514302, 3735928559(%ebx,%ecx,8)
+ andl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andl $324478056, 3735928559(%ebx,%ecx,8)
+ andl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orb $254, 3735928559(%ebx,%ecx,8)
+ orb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orb $127, 3735928559(%ebx,%ecx,8)
+ orb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orw $31438, 3735928559(%ebx,%ecx,8)
+ orw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orl $2063514302, 3735928559(%ebx,%ecx,8)
+ orl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orl $324478056, 3735928559(%ebx,%ecx,8)
+ orl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorb $254, 3735928559(%ebx,%ecx,8)
+ xorb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorb $127, 3735928559(%ebx,%ecx,8)
+ xorb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorw $31438, 3735928559(%ebx,%ecx,8)
+ xorw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorl $2063514302, 3735928559(%ebx,%ecx,8)
+ xorl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorl $324478056, 3735928559(%ebx,%ecx,8)
+ xorl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcb $254, 3735928559(%ebx,%ecx,8)
+ adcb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcb $127, 3735928559(%ebx,%ecx,8)
+ adcb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcw $31438, 3735928559(%ebx,%ecx,8)
+ adcw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcl $2063514302, 3735928559(%ebx,%ecx,8)
+ adcl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcl $324478056, 3735928559(%ebx,%ecx,8)
+ adcl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: negl 3735928559(%ebx,%ecx,8)
+ negl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: notl 3735928559(%ebx,%ecx,8)
+ notl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cbtw
+ cbtw
+
+// CHECK: cwtl
+ cwtl
+
+// CHECK: cwtd
+ cwtd
+
+// CHECK: cltd
+ cltd
+
+// CHECK: mull 3735928559(%ebx,%ecx,8)
+ mull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: imull 3735928559(%ebx,%ecx,8)
+ imull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: divl 3735928559(%ebx,%ecx,8)
+ divl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: idivl 3735928559(%ebx,%ecx,8)
+ idivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: roll $0, 3735928559(%ebx,%ecx,8)
+ roll $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rolb $127, 3735928559(%ebx,%ecx,8)
+ rolb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: roll 3735928559(%ebx,%ecx,8)
+ roll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorl $0, 3735928559(%ebx,%ecx,8)
+ rorl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorb $127, 3735928559(%ebx,%ecx,8)
+ rorb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorl 3735928559(%ebx,%ecx,8)
+ rorl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shll $0, 3735928559(%ebx,%ecx,8)
+ shll $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlb $127, 3735928559(%ebx,%ecx,8)
+ shlb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shll 3735928559(%ebx,%ecx,8)
+ shll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrl $0, 3735928559(%ebx,%ecx,8)
+ shrl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrb $127, 3735928559(%ebx,%ecx,8)
+ shrb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrl 3735928559(%ebx,%ecx,8)
+ shrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarl $0, 3735928559(%ebx,%ecx,8)
+ sarl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarb $127, 3735928559(%ebx,%ecx,8)
+ sarb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarl 3735928559(%ebx,%ecx,8)
+ sarl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: call *%ecx
+ call *%ecx
+
+// CHECK: call *3735928559(%ebx,%ecx,8)
+ call *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: call *3735928559(%ebx,%ecx,8)
+ call *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: jmp *3735928559(%ebx,%ecx,8) # TAILCALL
+ jmp *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: jmp *3735928559(%ebx,%ecx,8) # TAILCALL
+ jmp *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ljmpl *3735928559(%ebx,%ecx,8)
+ ljmpl *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: lret
+ lret
+
+// CHECK: leave
+ leave
+
+// CHECK: seto %bl
+ seto %bl
+
+// CHECK: seto 3735928559(%ebx,%ecx,8)
+ seto 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setno %bl
+ setno %bl
+
+// CHECK: setno 3735928559(%ebx,%ecx,8)
+ setno 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setb %bl
+ setb %bl
+
+// CHECK: setb 3735928559(%ebx,%ecx,8)
+ setb 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setae %bl
+ setae %bl
+
+// CHECK: setae 3735928559(%ebx,%ecx,8)
+ setae 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sete %bl
+ sete %bl
+
+// CHECK: sete 3735928559(%ebx,%ecx,8)
+ sete 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setne %bl
+ setne %bl
+
+// CHECK: setne 3735928559(%ebx,%ecx,8)
+ setne 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setbe %bl
+ setbe %bl
+
+// CHECK: setbe 3735928559(%ebx,%ecx,8)
+ setbe 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: seta %bl
+ seta %bl
+
+// CHECK: seta 3735928559(%ebx,%ecx,8)
+ seta 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sets %bl
+ sets %bl
+
+// CHECK: sets 3735928559(%ebx,%ecx,8)
+ sets 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setns %bl
+ setns %bl
+
+// CHECK: setns 3735928559(%ebx,%ecx,8)
+ setns 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setp %bl
+ setp %bl
+
+// CHECK: setp 3735928559(%ebx,%ecx,8)
+ setp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setnp %bl
+ setnp %bl
+
+// CHECK: setnp 3735928559(%ebx,%ecx,8)
+ setnp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setl %bl
+ setl %bl
+
+// CHECK: setl 3735928559(%ebx,%ecx,8)
+ setl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setge %bl
+ setge %bl
+
+// CHECK: setge 3735928559(%ebx,%ecx,8)
+ setge 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setle %bl
+ setle %bl
+
+// CHECK: setle 3735928559(%ebx,%ecx,8)
+ setle 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setg %bl
+ setg %bl
+
+// CHECK: setg 3735928559(%ebx,%ecx,8)
+ setg 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: nopl 3735928559(%ebx,%ecx,8)
+ nopl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: nop
+ nop
+
+// CHECK: fldl 3735928559(%ebx,%ecx,8)
+ fldl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fildl 3735928559(%ebx,%ecx,8)
+ fildl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fildll 3735928559(%ebx,%ecx,8)
+ fildll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fldt 3735928559(%ebx,%ecx,8)
+ fldt 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fbld 3735928559(%ebx,%ecx,8)
+ fbld 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstl 3735928559(%ebx,%ecx,8)
+ fstl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistl 3735928559(%ebx,%ecx,8)
+ fistl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstpl 3735928559(%ebx,%ecx,8)
+ fstpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistpl 3735928559(%ebx,%ecx,8)
+ fistpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistpll 3735928559(%ebx,%ecx,8)
+ fistpll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstpt 3735928559(%ebx,%ecx,8)
+ fstpt 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fbstp 3735928559(%ebx,%ecx,8)
+ fbstp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ficoml 3735928559(%ebx,%ecx,8)
+ ficoml 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ficompl 3735928559(%ebx,%ecx,8)
+ ficompl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fucompp
+ fucompp
+
+// CHECK: ftst
+ ftst
+
+// CHECK: fld1
+ fld1
+
+// CHECK: fldz
+ fldz
+
+// CHECK: faddl 3735928559(%ebx,%ecx,8)
+ faddl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fiaddl 3735928559(%ebx,%ecx,8)
+ fiaddl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fsubl 3735928559(%ebx,%ecx,8)
+ fsubl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisubl 3735928559(%ebx,%ecx,8)
+ fisubl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fsubrl 3735928559(%ebx,%ecx,8)
+ fsubrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisubrl 3735928559(%ebx,%ecx,8)
+ fisubrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fmull 3735928559(%ebx,%ecx,8)
+ fmull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fimull 3735928559(%ebx,%ecx,8)
+ fimull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fdivl 3735928559(%ebx,%ecx,8)
+ fdivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fidivl 3735928559(%ebx,%ecx,8)
+ fidivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fdivrl 3735928559(%ebx,%ecx,8)
+ fdivrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fidivrl 3735928559(%ebx,%ecx,8)
+ fidivrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fsqrt
+ fsqrt
+
+// CHECK: fsin
+ fsin
+
+// CHECK: fcos
+ fcos
+
+// CHECK: fchs
+ fchs
+
+// CHECK: fabs
+ fabs
+
+// CHECK: fldcw 3735928559(%ebx,%ecx,8)
+ fldcw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fnstcw 3735928559(%ebx,%ecx,8)
+ fnstcw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rdtsc
+ rdtsc
+
+// CHECK: sysenter
+ sysenter
+
+// CHECK: sysexit
+ sysexit
+
+// CHECK: ud2
+ ud2
+
+// CHECK: movnti %ecx, 3735928559(%ebx,%ecx,8)
+ movnti %ecx,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: clflush 3735928559(%ebx,%ecx,8)
+ clflush 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: emms
+ emms
+
+// CHECK: movd %ecx, %mm3
+ movd %ecx,%mm3
+
+// CHECK: movd 3735928559(%ebx,%ecx,8), %mm3
+ movd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: movd %ecx, %xmm5
+ movd %ecx,%xmm5
+
+// CHECK: movd 3735928559(%ebx,%ecx,8), %xmm5
+ movd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movd %xmm5, %ecx
+ movd %xmm5,%ecx
+
+// CHECK: movd %xmm5, 3735928559(%ebx,%ecx,8)
+ movd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movq 3735928559(%ebx,%ecx,8), %mm3
+ movq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: movq %mm3, %mm3
+ movq %mm3,%mm3
+
+// CHECK: movq %mm3, %mm3
+ movq %mm3,%mm3
+
+// CHECK: movq %xmm5, %xmm5
+ movq %xmm5,%xmm5
+
+// CHECK: movq %xmm5, %xmm5
+ movq %xmm5,%xmm5
+
+// CHECK: packssdw %mm3, %mm3
+ packssdw %mm3,%mm3
+
+// CHECK: packssdw %xmm5, %xmm5
+ packssdw %xmm5,%xmm5
+
+// CHECK: packsswb %mm3, %mm3
+ packsswb %mm3,%mm3
+
+// CHECK: packsswb %xmm5, %xmm5
+ packsswb %xmm5,%xmm5
+
+// CHECK: packuswb %mm3, %mm3
+ packuswb %mm3,%mm3
+
+// CHECK: packuswb %xmm5, %xmm5
+ packuswb %xmm5,%xmm5
+
+// CHECK: paddb %mm3, %mm3
+ paddb %mm3,%mm3
+
+// CHECK: paddb %xmm5, %xmm5
+ paddb %xmm5,%xmm5
+
+// CHECK: paddw %mm3, %mm3
+ paddw %mm3,%mm3
+
+// CHECK: paddw %xmm5, %xmm5
+ paddw %xmm5,%xmm5
+
+// CHECK: paddd %mm3, %mm3
+ paddd %mm3,%mm3
+
+// CHECK: paddd %xmm5, %xmm5
+ paddd %xmm5,%xmm5
+
+// CHECK: paddq %mm3, %mm3
+ paddq %mm3,%mm3
+
+// CHECK: paddq %xmm5, %xmm5
+ paddq %xmm5,%xmm5
+
+// CHECK: paddsb %mm3, %mm3
+ paddsb %mm3,%mm3
+
+// CHECK: paddsb %xmm5, %xmm5
+ paddsb %xmm5,%xmm5
+
+// CHECK: paddsw %mm3, %mm3
+ paddsw %mm3,%mm3
+
+// CHECK: paddsw %xmm5, %xmm5
+ paddsw %xmm5,%xmm5
+
+// CHECK: paddusb %mm3, %mm3
+ paddusb %mm3,%mm3
+
+// CHECK: paddusb %xmm5, %xmm5
+ paddusb %xmm5,%xmm5
+
+// CHECK: paddusw %mm3, %mm3
+ paddusw %mm3,%mm3
+
+// CHECK: paddusw %xmm5, %xmm5
+ paddusw %xmm5,%xmm5
+
+// CHECK: pand %mm3, %mm3
+ pand %mm3,%mm3
+
+// CHECK: pand %xmm5, %xmm5
+ pand %xmm5,%xmm5
+
+// CHECK: pandn %mm3, %mm3
+ pandn %mm3,%mm3
+
+// CHECK: pandn %xmm5, %xmm5
+ pandn %xmm5,%xmm5
+
+// CHECK: pcmpeqb %mm3, %mm3
+ pcmpeqb %mm3,%mm3
+
+// CHECK: pcmpeqb %xmm5, %xmm5
+ pcmpeqb %xmm5,%xmm5
+
+// CHECK: pcmpeqw %mm3, %mm3
+ pcmpeqw %mm3,%mm3
+
+// CHECK: pcmpeqw %xmm5, %xmm5
+ pcmpeqw %xmm5,%xmm5
+
+// CHECK: pcmpeqd %mm3, %mm3
+ pcmpeqd %mm3,%mm3
+
+// CHECK: pcmpeqd %xmm5, %xmm5
+ pcmpeqd %xmm5,%xmm5
+
+// CHECK: pcmpgtb %mm3, %mm3
+ pcmpgtb %mm3,%mm3
+
+// CHECK: pcmpgtb %xmm5, %xmm5
+ pcmpgtb %xmm5,%xmm5
+
+// CHECK: pcmpgtw %mm3, %mm3
+ pcmpgtw %mm3,%mm3
+
+// CHECK: pcmpgtw %xmm5, %xmm5
+ pcmpgtw %xmm5,%xmm5
+
+// CHECK: pcmpgtd %mm3, %mm3
+ pcmpgtd %mm3,%mm3
+
+// CHECK: pcmpgtd %xmm5, %xmm5
+ pcmpgtd %xmm5,%xmm5
+
+// CHECK: pmaddwd %mm3, %mm3
+ pmaddwd %mm3,%mm3
+
+// CHECK: pmaddwd %xmm5, %xmm5
+ pmaddwd %xmm5,%xmm5
+
+// CHECK: pmulhw %mm3, %mm3
+ pmulhw %mm3,%mm3
+
+// CHECK: pmulhw %xmm5, %xmm5
+ pmulhw %xmm5,%xmm5
+
+// CHECK: pmullw %mm3, %mm3
+ pmullw %mm3,%mm3
+
+// CHECK: pmullw %xmm5, %xmm5
+ pmullw %xmm5,%xmm5
+
+// CHECK: por %mm3, %mm3
+ por %mm3,%mm3
+
+// CHECK: por %xmm5, %xmm5
+ por %xmm5,%xmm5
+
+// CHECK: psllw %mm3, %mm3
+ psllw %mm3,%mm3
+
+// CHECK: psllw %xmm5, %xmm5
+ psllw %xmm5,%xmm5
+
+// CHECK: psllw $127, %mm3
+ psllw $0x7f,%mm3
+
+// CHECK: psllw $127, %xmm5
+ psllw $0x7f,%xmm5
+
+// CHECK: pslld %mm3, %mm3
+ pslld %mm3,%mm3
+
+// CHECK: pslld %xmm5, %xmm5
+ pslld %xmm5,%xmm5
+
+// CHECK: pslld $127, %mm3
+ pslld $0x7f,%mm3
+
+// CHECK: pslld $127, %xmm5
+ pslld $0x7f,%xmm5
+
+// CHECK: psllq %mm3, %mm3
+ psllq %mm3,%mm3
+
+// CHECK: psllq %xmm5, %xmm5
+ psllq %xmm5,%xmm5
+
+// CHECK: psllq $127, %mm3
+ psllq $0x7f,%mm3
+
+// CHECK: psllq $127, %xmm5
+ psllq $0x7f,%xmm5
+
+// CHECK: psraw %mm3, %mm3
+ psraw %mm3,%mm3
+
+// CHECK: psraw %xmm5, %xmm5
+ psraw %xmm5,%xmm5
+
+// CHECK: psraw $127, %mm3
+ psraw $0x7f,%mm3
+
+// CHECK: psraw $127, %xmm5
+ psraw $0x7f,%xmm5
+
+// CHECK: psrad %mm3, %mm3
+ psrad %mm3,%mm3
+
+// CHECK: psrad %xmm5, %xmm5
+ psrad %xmm5,%xmm5
+
+// CHECK: psrad $127, %mm3
+ psrad $0x7f,%mm3
+
+// CHECK: psrad $127, %xmm5
+ psrad $0x7f,%xmm5
+
+// CHECK: psrlw %mm3, %mm3
+ psrlw %mm3,%mm3
+
+// CHECK: psrlw %xmm5, %xmm5
+ psrlw %xmm5,%xmm5
+
+// CHECK: psrlw $127, %mm3
+ psrlw $0x7f,%mm3
+
+// CHECK: psrlw $127, %xmm5
+ psrlw $0x7f,%xmm5
+
+// CHECK: psrld %mm3, %mm3
+ psrld %mm3,%mm3
+
+// CHECK: psrld %xmm5, %xmm5
+ psrld %xmm5,%xmm5
+
+// CHECK: psrld $127, %mm3
+ psrld $0x7f,%mm3
+
+// CHECK: psrld $127, %xmm5
+ psrld $0x7f,%xmm5
+
+// CHECK: psrlq %mm3, %mm3
+ psrlq %mm3,%mm3
+
+// CHECK: psrlq %xmm5, %xmm5
+ psrlq %xmm5,%xmm5
+
+// CHECK: psrlq $127, %mm3
+ psrlq $0x7f,%mm3
+
+// CHECK: psrlq $127, %xmm5
+ psrlq $0x7f,%xmm5
+
+// CHECK: psubb %mm3, %mm3
+ psubb %mm3,%mm3
+
+// CHECK: psubb %xmm5, %xmm5
+ psubb %xmm5,%xmm5
+
+// CHECK: psubw %mm3, %mm3
+ psubw %mm3,%mm3
+
+// CHECK: psubw %xmm5, %xmm5
+ psubw %xmm5,%xmm5
+
+// CHECK: psubd %mm3, %mm3
+ psubd %mm3,%mm3
+
+// CHECK: psubd %xmm5, %xmm5
+ psubd %xmm5,%xmm5
+
+// CHECK: psubq %mm3, %mm3
+ psubq %mm3,%mm3
+
+// CHECK: psubq %xmm5, %xmm5
+ psubq %xmm5,%xmm5
+
+// CHECK: psubsb %mm3, %mm3
+ psubsb %mm3,%mm3
+
+// CHECK: psubsb %xmm5, %xmm5
+ psubsb %xmm5,%xmm5
+
+// CHECK: psubsw %mm3, %mm3
+ psubsw %mm3,%mm3
+
+// CHECK: psubsw %xmm5, %xmm5
+ psubsw %xmm5,%xmm5
+
+// CHECK: psubusb %mm3, %mm3
+ psubusb %mm3,%mm3
+
+// CHECK: psubusb %xmm5, %xmm5
+ psubusb %xmm5,%xmm5
+
+// CHECK: psubusw %mm3, %mm3
+ psubusw %mm3,%mm3
+
+// CHECK: psubusw %xmm5, %xmm5
+ psubusw %xmm5,%xmm5
+
+// CHECK: punpckhbw %mm3, %mm3
+ punpckhbw %mm3,%mm3
+
+// CHECK: punpckhbw %xmm5, %xmm5
+ punpckhbw %xmm5,%xmm5
+
+// CHECK: punpckhwd %mm3, %mm3
+ punpckhwd %mm3,%mm3
+
+// CHECK: punpckhwd %xmm5, %xmm5
+ punpckhwd %xmm5,%xmm5
+
+// CHECK: punpckhdq %mm3, %mm3
+ punpckhdq %mm3,%mm3
+
+// CHECK: punpckhdq %xmm5, %xmm5
+ punpckhdq %xmm5,%xmm5
+
+// CHECK: punpcklbw %mm3, %mm3
+ punpcklbw %mm3,%mm3
+
+// CHECK: punpcklbw %xmm5, %xmm5
+ punpcklbw %xmm5,%xmm5
+
+// CHECK: punpcklwd %mm3, %mm3
+ punpcklwd %mm3,%mm3
+
+// CHECK: punpcklwd %xmm5, %xmm5
+ punpcklwd %xmm5,%xmm5
+
+// CHECK: punpckldq %mm3, %mm3
+ punpckldq %mm3,%mm3
+
+// CHECK: punpckldq %xmm5, %xmm5
+ punpckldq %xmm5,%xmm5
+
+// CHECK: pxor %mm3, %mm3
+ pxor %mm3,%mm3
+
+// CHECK: pxor %xmm5, %xmm5
+ pxor %xmm5,%xmm5
+
+// CHECK: addps %xmm5, %xmm5
+ addps %xmm5,%xmm5
+
+// CHECK: addss %xmm5, %xmm5
+ addss %xmm5,%xmm5
+
+// CHECK: andnps %xmm5, %xmm5
+ andnps %xmm5,%xmm5
+
+// CHECK: andps %xmm5, %xmm5
+ andps %xmm5,%xmm5
+
+// CHECK: cvtpi2ps 3735928559(%ebx,%ecx,8), %xmm5
+ cvtpi2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpi2ps %mm3, %xmm5
+ cvtpi2ps %mm3,%xmm5
+
+// CHECK: cvtps2pi 3735928559(%ebx,%ecx,8), %mm3
+ cvtps2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvtps2pi %xmm5, %mm3
+ cvtps2pi %xmm5,%mm3
+
+// CHECK: cvtsi2ss %ecx, %xmm5
+ cvtsi2ss %ecx,%xmm5
+
+// CHECK: cvtsi2ss 3735928559(%ebx,%ecx,8), %xmm5
+ cvtsi2ss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvttps2pi 3735928559(%ebx,%ecx,8), %mm3
+ cvttps2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvttps2pi %xmm5, %mm3
+ cvttps2pi %xmm5,%mm3
+
+// CHECK: cvttss2si 3735928559(%ebx,%ecx,8), %ecx
+ cvttss2si 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: cvttss2si %xmm5, %ecx
+ cvttss2si %xmm5,%ecx
+
+// CHECK: divps %xmm5, %xmm5
+ divps %xmm5,%xmm5
+
+// CHECK: divss %xmm5, %xmm5
+ divss %xmm5,%xmm5
+
+// CHECK: ldmxcsr 3735928559(%ebx,%ecx,8)
+ ldmxcsr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: maskmovq %mm3, %mm3
+ maskmovq %mm3,%mm3
+
+// CHECK: maxps %xmm5, %xmm5
+ maxps %xmm5,%xmm5
+
+// CHECK: maxss %xmm5, %xmm5
+ maxss %xmm5,%xmm5
+
+// CHECK: minps %xmm5, %xmm5
+ minps %xmm5,%xmm5
+
+// CHECK: minss %xmm5, %xmm5
+ minss %xmm5,%xmm5
+
+// CHECK: movaps 3735928559(%ebx,%ecx,8), %xmm5
+ movaps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movaps %xmm5, %xmm5
+ movaps %xmm5,%xmm5
+
+// CHECK: movaps %xmm5, 3735928559(%ebx,%ecx,8)
+ movaps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movaps %xmm5, %xmm5
+ movaps %xmm5,%xmm5
+
+// CHECK: movhlps %xmm5, %xmm5
+ movhlps %xmm5,%xmm5
+
+// CHECK: movhps %xmm5, 3735928559(%ebx,%ecx,8)
+ movhps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movlhps %xmm5, %xmm5
+ movlhps %xmm5,%xmm5
+
+// CHECK: movlps %xmm5, 3735928559(%ebx,%ecx,8)
+ movlps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movmskps %xmm5, %ecx
+ movmskps %xmm5,%ecx
+
+// CHECK: movntps %xmm5, 3735928559(%ebx,%ecx,8)
+ movntps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntq %mm3, 3735928559(%ebx,%ecx,8)
+ movntq %mm3,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntdq %xmm5, 3735928559(%ebx,%ecx,8)
+ movntdq %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movss 3735928559(%ebx,%ecx,8), %xmm5
+ movss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movss %xmm5, %xmm5
+ movss %xmm5,%xmm5
+
+// CHECK: movss %xmm5, 3735928559(%ebx,%ecx,8)
+ movss %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movss %xmm5, %xmm5
+ movss %xmm5,%xmm5
+
+// CHECK: movups 3735928559(%ebx,%ecx,8), %xmm5
+ movups 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movups %xmm5, %xmm5
+ movups %xmm5,%xmm5
+
+// CHECK: movups %xmm5, 3735928559(%ebx,%ecx,8)
+ movups %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movups %xmm5, %xmm5
+ movups %xmm5,%xmm5
+
+// CHECK: mulps %xmm5, %xmm5
+ mulps %xmm5,%xmm5
+
+// CHECK: mulss %xmm5, %xmm5
+ mulss %xmm5,%xmm5
+
+// CHECK: orps %xmm5, %xmm5
+ orps %xmm5,%xmm5
+
+// CHECK: pavgb %mm3, %mm3
+ pavgb %mm3,%mm3
+
+// CHECK: pavgb %xmm5, %xmm5
+ pavgb %xmm5,%xmm5
+
+// CHECK: pavgw %mm3, %mm3
+ pavgw %mm3,%mm3
+
+// CHECK: pavgw %xmm5, %xmm5
+ pavgw %xmm5,%xmm5
+
+// CHECK: pmaxsw %mm3, %mm3
+ pmaxsw %mm3,%mm3
+
+// CHECK: pmaxsw %xmm5, %xmm5
+ pmaxsw %xmm5,%xmm5
+
+// CHECK: pmaxub %mm3, %mm3
+ pmaxub %mm3,%mm3
+
+// CHECK: pmaxub %xmm5, %xmm5
+ pmaxub %xmm5,%xmm5
+
+// CHECK: pminsw %mm3, %mm3
+ pminsw %mm3,%mm3
+
+// CHECK: pminsw %xmm5, %xmm5
+ pminsw %xmm5,%xmm5
+
+// CHECK: pminub %mm3, %mm3
+ pminub %mm3,%mm3
+
+// CHECK: pminub %xmm5, %xmm5
+ pminub %xmm5,%xmm5
+
+// CHECK: pmovmskb %mm3, %ecx
+ pmovmskb %mm3,%ecx
+
+// CHECK: pmovmskb %xmm5, %ecx
+ pmovmskb %xmm5,%ecx
+
+// CHECK: pmulhuw %mm3, %mm3
+ pmulhuw %mm3,%mm3
+
+// CHECK: pmulhuw %xmm5, %xmm5
+ pmulhuw %xmm5,%xmm5
+
+// CHECK: prefetchnta 3735928559(%ebx,%ecx,8)
+ prefetchnta 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht0 3735928559(%ebx,%ecx,8)
+ prefetcht0 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht1 3735928559(%ebx,%ecx,8)
+ prefetcht1 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht2 3735928559(%ebx,%ecx,8)
+ prefetcht2 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: psadbw %mm3, %mm3
+ psadbw %mm3,%mm3
+
+// CHECK: psadbw %xmm5, %xmm5
+ psadbw %xmm5,%xmm5
+
+// CHECK: rcpps 3735928559(%ebx,%ecx,8), %xmm5
+ rcpps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rcpps %xmm5, %xmm5
+ rcpps %xmm5,%xmm5
+
+// CHECK: rcpss 3735928559(%ebx,%ecx,8), %xmm5
+ rcpss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rcpss %xmm5, %xmm5
+ rcpss %xmm5,%xmm5
+
+// CHECK: rsqrtps 3735928559(%ebx,%ecx,8), %xmm5
+ rsqrtps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rsqrtps %xmm5, %xmm5
+ rsqrtps %xmm5,%xmm5
+
+// CHECK: rsqrtss 3735928559(%ebx,%ecx,8), %xmm5
+ rsqrtss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rsqrtss %xmm5, %xmm5
+ rsqrtss %xmm5,%xmm5
+
+// CHECK: sqrtps 3735928559(%ebx,%ecx,8), %xmm5
+ sqrtps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtps %xmm5, %xmm5
+ sqrtps %xmm5,%xmm5
+
+// CHECK: sqrtss 3735928559(%ebx,%ecx,8), %xmm5
+ sqrtss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtss %xmm5, %xmm5
+ sqrtss %xmm5,%xmm5
+
+// CHECK: stmxcsr 3735928559(%ebx,%ecx,8)
+ stmxcsr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subps %xmm5, %xmm5
+ subps %xmm5,%xmm5
+
+// CHECK: subss %xmm5, %xmm5
+ subss %xmm5,%xmm5
+
+// CHECK: ucomiss 3735928559(%ebx,%ecx,8), %xmm5
+ ucomiss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ucomiss %xmm5, %xmm5
+ ucomiss %xmm5,%xmm5
+
+// CHECK: unpckhps %xmm5, %xmm5
+ unpckhps %xmm5,%xmm5
+
+// CHECK: unpcklps %xmm5, %xmm5
+ unpcklps %xmm5,%xmm5
+
+// CHECK: xorps %xmm5, %xmm5
+ xorps %xmm5,%xmm5
+
+// CHECK: addpd %xmm5, %xmm5
+ addpd %xmm5,%xmm5
+
+// CHECK: addsd %xmm5, %xmm5
+ addsd %xmm5,%xmm5
+
+// CHECK: andnpd %xmm5, %xmm5
+ andnpd %xmm5,%xmm5
+
+// CHECK: andpd %xmm5, %xmm5
+ andpd %xmm5,%xmm5
+
+// CHECK: comisd 3735928559(%ebx,%ecx,8), %xmm5
+ comisd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: comisd %xmm5, %xmm5
+ comisd %xmm5,%xmm5
+
+// CHECK: cvtpi2pd 3735928559(%ebx,%ecx,8), %xmm5
+ cvtpi2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpi2pd %mm3, %xmm5
+ cvtpi2pd %mm3,%xmm5
+
+// CHECK: cvtsi2sd %ecx, %xmm5
+ cvtsi2sd %ecx,%xmm5
+
+// CHECK: cvtsi2sd 3735928559(%ebx,%ecx,8), %xmm5
+ cvtsi2sd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divpd %xmm5, %xmm5
+ divpd %xmm5,%xmm5
+
+// CHECK: divsd %xmm5, %xmm5
+ divsd %xmm5,%xmm5
+
+// CHECK: maxpd %xmm5, %xmm5
+ maxpd %xmm5,%xmm5
+
+// CHECK: maxsd %xmm5, %xmm5
+ maxsd %xmm5,%xmm5
+
+// CHECK: minpd %xmm5, %xmm5
+ minpd %xmm5,%xmm5
+
+// CHECK: minsd %xmm5, %xmm5
+ minsd %xmm5,%xmm5
+
+// CHECK: movapd 3735928559(%ebx,%ecx,8), %xmm5
+ movapd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movapd %xmm5, %xmm5
+ movapd %xmm5,%xmm5
+
+// CHECK: movapd %xmm5, 3735928559(%ebx,%ecx,8)
+ movapd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movapd %xmm5, %xmm5
+ movapd %xmm5,%xmm5
+
+// CHECK: movhpd %xmm5, 3735928559(%ebx,%ecx,8)
+ movhpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movlpd %xmm5, 3735928559(%ebx,%ecx,8)
+ movlpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movmskpd %xmm5, %ecx
+ movmskpd %xmm5,%ecx
+
+// CHECK: movntpd %xmm5, 3735928559(%ebx,%ecx,8)
+ movntpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movsd 3735928559(%ebx,%ecx,8), %xmm5
+ movsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movsd %xmm5, %xmm5
+ movsd %xmm5,%xmm5
+
+// CHECK: movsd %xmm5, 3735928559(%ebx,%ecx,8)
+ movsd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movsd %xmm5, %xmm5
+ movsd %xmm5,%xmm5
+
+// CHECK: movupd 3735928559(%ebx,%ecx,8), %xmm5
+ movupd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movupd %xmm5, %xmm5
+ movupd %xmm5,%xmm5
+
+// CHECK: movupd %xmm5, 3735928559(%ebx,%ecx,8)
+ movupd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movupd %xmm5, %xmm5
+ movupd %xmm5,%xmm5
+
+// CHECK: mulpd %xmm5, %xmm5
+ mulpd %xmm5,%xmm5
+
+// CHECK: mulsd %xmm5, %xmm5
+ mulsd %xmm5,%xmm5
+
+// CHECK: orpd %xmm5, %xmm5
+ orpd %xmm5,%xmm5
+
+// CHECK: sqrtpd 3735928559(%ebx,%ecx,8), %xmm5
+ sqrtpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtpd %xmm5, %xmm5
+ sqrtpd %xmm5,%xmm5
+
+// CHECK: sqrtsd 3735928559(%ebx,%ecx,8), %xmm5
+ sqrtsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtsd %xmm5, %xmm5
+ sqrtsd %xmm5,%xmm5
+
+// CHECK: subpd %xmm5, %xmm5
+ subpd %xmm5,%xmm5
+
+// CHECK: subsd %xmm5, %xmm5
+ subsd %xmm5,%xmm5
+
+// CHECK: ucomisd 3735928559(%ebx,%ecx,8), %xmm5
+ ucomisd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ucomisd %xmm5, %xmm5
+ ucomisd %xmm5,%xmm5
+
+// CHECK: unpckhpd %xmm5, %xmm5
+ unpckhpd %xmm5,%xmm5
+
+// CHECK: unpcklpd %xmm5, %xmm5
+ unpcklpd %xmm5,%xmm5
+
+// CHECK: xorpd %xmm5, %xmm5
+ xorpd %xmm5,%xmm5
+
+// CHECK: cvtdq2pd 3735928559(%ebx,%ecx,8), %xmm5
+ cvtdq2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtdq2pd %xmm5, %xmm5
+ cvtdq2pd %xmm5,%xmm5
+
+// CHECK: cvtpd2dq 3735928559(%ebx,%ecx,8), %xmm5
+ cvtpd2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpd2dq %xmm5, %xmm5
+ cvtpd2dq %xmm5,%xmm5
+
+// CHECK: cvtdq2ps 3735928559(%ebx,%ecx,8), %xmm5
+ cvtdq2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtdq2ps %xmm5, %xmm5
+ cvtdq2ps %xmm5,%xmm5
+
+// CHECK: cvtpd2pi 3735928559(%ebx,%ecx,8), %mm3
+ cvtpd2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvtpd2pi %xmm5, %mm3
+ cvtpd2pi %xmm5,%mm3
+
+// CHECK: cvtps2dq 3735928559(%ebx,%ecx,8), %xmm5
+ cvtps2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtps2dq %xmm5, %xmm5
+ cvtps2dq %xmm5,%xmm5
+
+// CHECK: cvtsd2ss 3735928559(%ebx,%ecx,8), %xmm5
+ cvtsd2ss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtsd2ss %xmm5, %xmm5
+ cvtsd2ss %xmm5,%xmm5
+
+// CHECK: cvtss2sd 3735928559(%ebx,%ecx,8), %xmm5
+ cvtss2sd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtss2sd %xmm5, %xmm5
+ cvtss2sd %xmm5,%xmm5
+
+// CHECK: cvttpd2pi 3735928559(%ebx,%ecx,8), %mm3
+ cvttpd2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvttpd2pi %xmm5, %mm3
+ cvttpd2pi %xmm5,%mm3
+
+// CHECK: cvttsd2si 3735928559(%ebx,%ecx,8), %ecx
+ cvttsd2si 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: cvttsd2si %xmm5, %ecx
+ cvttsd2si %xmm5,%ecx
+
+// CHECK: maskmovdqu %xmm5, %xmm5
+ maskmovdqu %xmm5,%xmm5
+
+// CHECK: movdqa 3735928559(%ebx,%ecx,8), %xmm5
+ movdqa 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movdqa %xmm5, %xmm5
+ movdqa %xmm5,%xmm5
+
+// CHECK: movdqa %xmm5, 3735928559(%ebx,%ecx,8)
+ movdqa %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movdqa %xmm5, %xmm5
+ movdqa %xmm5,%xmm5
+
+// CHECK: movdqu 3735928559(%ebx,%ecx,8), %xmm5
+ movdqu 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movdqu %xmm5, 3735928559(%ebx,%ecx,8)
+ movdqu %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movdq2q %xmm5, %mm3
+ movdq2q %xmm5,%mm3
+
+// CHECK: movq2dq %mm3, %xmm5
+ movq2dq %mm3,%xmm5
+
+// CHECK: pmuludq %mm3, %mm3
+ pmuludq %mm3,%mm3
+
+// CHECK: pmuludq %xmm5, %xmm5
+ pmuludq %xmm5,%xmm5
+
+// CHECK: pslldq $127, %xmm5
+ pslldq $0x7f,%xmm5
+
+// CHECK: psrldq $127, %xmm5
+ psrldq $0x7f,%xmm5
+
+// CHECK: punpckhqdq %xmm5, %xmm5
+ punpckhqdq %xmm5,%xmm5
+
+// CHECK: punpcklqdq %xmm5, %xmm5
+ punpcklqdq %xmm5,%xmm5
+
+// CHECK: addsubpd %xmm5, %xmm5
+ addsubpd %xmm5,%xmm5
+
+// CHECK: addsubps %xmm5, %xmm5
+ addsubps %xmm5,%xmm5
+
+// CHECK: haddpd %xmm5, %xmm5
+ haddpd %xmm5,%xmm5
+
+// CHECK: haddps %xmm5, %xmm5
+ haddps %xmm5,%xmm5
+
+// CHECK: hsubpd %xmm5, %xmm5
+ hsubpd %xmm5,%xmm5
+
+// CHECK: hsubps %xmm5, %xmm5
+ hsubps %xmm5,%xmm5
+
+// CHECK: lddqu 3735928559(%ebx,%ecx,8), %xmm5
+ lddqu 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movddup 3735928559(%ebx,%ecx,8), %xmm5
+ movddup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movddup %xmm5, %xmm5
+ movddup %xmm5,%xmm5
+
+// CHECK: movshdup 3735928559(%ebx,%ecx,8), %xmm5
+ movshdup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movshdup %xmm5, %xmm5
+ movshdup %xmm5,%xmm5
+
+// CHECK: movsldup 3735928559(%ebx,%ecx,8), %xmm5
+ movsldup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movsldup %xmm5, %xmm5
+ movsldup %xmm5,%xmm5
+
+// CHECK: phaddw %mm3, %mm3
+ phaddw %mm3,%mm3
+
+// CHECK: phaddw %xmm5, %xmm5
+ phaddw %xmm5,%xmm5
+
+// CHECK: phaddd %mm3, %mm3
+ phaddd %mm3,%mm3
+
+// CHECK: phaddd %xmm5, %xmm5
+ phaddd %xmm5,%xmm5
+
+// CHECK: phaddsw %mm3, %mm3
+ phaddsw %mm3,%mm3
+
+// CHECK: phaddsw %xmm5, %xmm5
+ phaddsw %xmm5,%xmm5
+
+// CHECK: phsubw %mm3, %mm3
+ phsubw %mm3,%mm3
+
+// CHECK: phsubw %xmm5, %xmm5
+ phsubw %xmm5,%xmm5
+
+// CHECK: phsubd %mm3, %mm3
+ phsubd %mm3,%mm3
+
+// CHECK: phsubd %xmm5, %xmm5
+ phsubd %xmm5,%xmm5
+
+// CHECK: phsubsw %mm3, %mm3
+ phsubsw %mm3,%mm3
+
+// CHECK: phsubsw %xmm5, %xmm5
+ phsubsw %xmm5,%xmm5
+
+// CHECK: pmaddubsw %mm3, %mm3
+ pmaddubsw %mm3,%mm3
+
+// CHECK: pmaddubsw %xmm5, %xmm5
+ pmaddubsw %xmm5,%xmm5
+
+// CHECK: pmulhrsw %mm3, %mm3
+ pmulhrsw %mm3,%mm3
+
+// CHECK: pmulhrsw %xmm5, %xmm5
+ pmulhrsw %xmm5,%xmm5
+
+// CHECK: pshufb %mm3, %mm3
+ pshufb %mm3,%mm3
+
+// CHECK: pshufb %xmm5, %xmm5
+ pshufb %xmm5,%xmm5
+
+// CHECK: psignb %mm3, %mm3
+ psignb %mm3,%mm3
+
+// CHECK: psignb %xmm5, %xmm5
+ psignb %xmm5,%xmm5
+
+// CHECK: psignw %mm3, %mm3
+ psignw %mm3,%mm3
+
+// CHECK: psignw %xmm5, %xmm5
+ psignw %xmm5,%xmm5
+
+// CHECK: psignd %mm3, %mm3
+ psignd %mm3,%mm3
+
+// CHECK: psignd %xmm5, %xmm5
+ psignd %xmm5,%xmm5
+
+// CHECK: pabsb 3735928559(%ebx,%ecx,8), %mm3
+ pabsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsb %mm3, %mm3
+ pabsb %mm3,%mm3
+
+// CHECK: pabsb 3735928559(%ebx,%ecx,8), %xmm5
+ pabsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsb %xmm5, %xmm5
+ pabsb %xmm5,%xmm5
+
+// CHECK: pabsw 3735928559(%ebx,%ecx,8), %mm3
+ pabsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsw %mm3, %mm3
+ pabsw %mm3,%mm3
+
+// CHECK: pabsw 3735928559(%ebx,%ecx,8), %xmm5
+ pabsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsw %xmm5, %xmm5
+ pabsw %xmm5,%xmm5
+
+// CHECK: pabsd 3735928559(%ebx,%ecx,8), %mm3
+ pabsd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsd %mm3, %mm3
+ pabsd %mm3,%mm3
+
+// CHECK: pabsd 3735928559(%ebx,%ecx,8), %xmm5
+ pabsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsd %xmm5, %xmm5
+ pabsd %xmm5,%xmm5
+
+// CHECK: femms
+ femms
+
+// CHECK: packusdw %xmm5, %xmm5
+ packusdw %xmm5,%xmm5
+
+// CHECK: pcmpeqq %xmm5, %xmm5
+ pcmpeqq %xmm5,%xmm5
+
+// CHECK: phminposuw 3735928559(%ebx,%ecx,8), %xmm5
+ phminposuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phminposuw %xmm5, %xmm5
+ phminposuw %xmm5,%xmm5
+
+// CHECK: pmaxsb %xmm5, %xmm5
+ pmaxsb %xmm5,%xmm5
+
+// CHECK: pmaxsd %xmm5, %xmm5
+ pmaxsd %xmm5,%xmm5
+
+// CHECK: pmaxud %xmm5, %xmm5
+ pmaxud %xmm5,%xmm5
+
+// CHECK: pmaxuw %xmm5, %xmm5
+ pmaxuw %xmm5,%xmm5
+
+// CHECK: pminsb %xmm5, %xmm5
+ pminsb %xmm5,%xmm5
+
+// CHECK: pminsd %xmm5, %xmm5
+ pminsd %xmm5,%xmm5
+
+// CHECK: pminud %xmm5, %xmm5
+ pminud %xmm5,%xmm5
+
+// CHECK: pminuw %xmm5, %xmm5
+ pminuw %xmm5,%xmm5
+
+// CHECK: pmovsxbw 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbw %xmm5, %xmm5
+ pmovsxbw %xmm5,%xmm5
+
+// CHECK: pmovsxbd 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxbd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbd %xmm5, %xmm5
+ pmovsxbd %xmm5,%xmm5
+
+// CHECK: pmovsxbq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxbq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbq %xmm5, %xmm5
+ pmovsxbq %xmm5,%xmm5
+
+// CHECK: pmovsxwd 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxwd %xmm5, %xmm5
+ pmovsxwd %xmm5,%xmm5
+
+// CHECK: pmovsxwq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxwq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxwq %xmm5, %xmm5
+ pmovsxwq %xmm5,%xmm5
+
+// CHECK: pmovsxdq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxdq %xmm5, %xmm5
+ pmovsxdq %xmm5,%xmm5
+
+// CHECK: pmovzxbw 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbw %xmm5, %xmm5
+ pmovzxbw %xmm5,%xmm5
+
+// CHECK: pmovzxbd 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxbd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbd %xmm5, %xmm5
+ pmovzxbd %xmm5,%xmm5
+
+// CHECK: pmovzxbq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxbq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbq %xmm5, %xmm5
+ pmovzxbq %xmm5,%xmm5
+
+// CHECK: pmovzxwd 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxwd %xmm5, %xmm5
+ pmovzxwd %xmm5,%xmm5
+
+// CHECK: pmovzxwq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxwq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxwq %xmm5, %xmm5
+ pmovzxwq %xmm5,%xmm5
+
+// CHECK: pmovzxdq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxdq %xmm5, %xmm5
+ pmovzxdq %xmm5,%xmm5
+
+// CHECK: pmuldq %xmm5, %xmm5
+ pmuldq %xmm5,%xmm5
+
+// CHECK: pmulld %xmm5, %xmm5
+ pmulld %xmm5,%xmm5
+
+// CHECK: ptest 3735928559(%ebx,%ecx,8), %xmm5
+ ptest 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ptest %xmm5, %xmm5
+ ptest %xmm5,%xmm5
+
+// CHECK: pcmpgtq %xmm5, %xmm5
+ pcmpgtq %xmm5,%xmm5
diff --git a/test/MC/AsmParser/X86/x86_32-bit_cat.s b/test/MC/AsmParser/X86/x86_32-bit_cat.s
new file mode 100644
index 0000000..f0c7804
--- /dev/null
+++ b/test/MC/AsmParser/X86/x86_32-bit_cat.s
@@ -0,0 +1,7809 @@
+// This is the current set of tests that can pass though llvm-mc as it were a
+// logical cat(1) and then reassemble to the same instruction. All of these
+// will not yet encode correctly. The subset that will encode correctly are in
+// the file x86_32-encoding.s (and other tests that encode are in x86_32-bit.s).
+
+// RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+
+// CHECK: movb $127, 3735928559(%ebx,%ecx,8)
+ movb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movb $127, 69
+ movb $0x7f,0x45
+
+// CHECK: movb $127, 32493
+ movb $0x7f,0x7eed
+
+// CHECK: movb $127, 3133065982
+ movb $0x7f,0xbabecafe
+
+// CHECK: movb $127, 305419896
+ movb $0x7f,0x12345678
+
+// CHECK: movw $31438, 3735928559(%ebx,%ecx,8)
+ movw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movw $31438, 69
+ movw $0x7ace,0x45
+
+// CHECK: movw $31438, 32493
+ movw $0x7ace,0x7eed
+
+// CHECK: movw $31438, 3133065982
+ movw $0x7ace,0xbabecafe
+
+// CHECK: movw $31438, 305419896
+ movw $0x7ace,0x12345678
+
+// CHECK: movl $2063514302, 3735928559(%ebx,%ecx,8)
+ movl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movl $2063514302, 69
+ movl $0x7afebabe,0x45
+
+// CHECK: movl $2063514302, 32493
+ movl $0x7afebabe,0x7eed
+
+// CHECK: movl $2063514302, 3133065982
+ movl $0x7afebabe,0xbabecafe
+
+// CHECK: movl $2063514302, 305419896
+ movl $0x7afebabe,0x12345678
+
+// CHECK: movl $324478056, 3735928559(%ebx,%ecx,8)
+ movl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movl $324478056, 69
+ movl $0x13572468,0x45
+
+// CHECK: movl $324478056, 32493
+ movl $0x13572468,0x7eed
+
+// CHECK: movl $324478056, 3133065982
+ movl $0x13572468,0xbabecafe
+
+// CHECK: movl $324478056, 305419896
+ movl $0x13572468,0x12345678
+
+// CHECK: movsbl 3735928559(%ebx,%ecx,8), %ecx
+ movsbl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movsbl 69, %ecx
+ movsbl 0x45,%ecx
+
+// CHECK: movsbl 32493, %ecx
+ movsbl 0x7eed,%ecx
+
+// CHECK: movsbl 3133065982, %ecx
+ movsbl 0xbabecafe,%ecx
+
+// CHECK: movsbl 305419896, %ecx
+ movsbl 0x12345678,%ecx
+
+// CHECK: movsbw 3735928559(%ebx,%ecx,8), %bx
+ movsbw 0xdeadbeef(%ebx,%ecx,8),%bx
+
+// CHECK: movsbw 69, %bx
+ movsbw 0x45,%bx
+
+// CHECK: movsbw 32493, %bx
+ movsbw 0x7eed,%bx
+
+// CHECK: movsbw 3133065982, %bx
+ movsbw 0xbabecafe,%bx
+
+// CHECK: movsbw 305419896, %bx
+ movsbw 0x12345678,%bx
+
+// CHECK: movswl 3735928559(%ebx,%ecx,8), %ecx
+ movswl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movswl 69, %ecx
+ movswl 0x45,%ecx
+
+// CHECK: movswl 32493, %ecx
+ movswl 0x7eed,%ecx
+
+// CHECK: movswl 3133065982, %ecx
+ movswl 0xbabecafe,%ecx
+
+// CHECK: movswl 305419896, %ecx
+ movswl 0x12345678,%ecx
+
+// CHECK: movzbl 3735928559(%ebx,%ecx,8), %ecx # NOREX
+ movzbl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movzbl 69, %ecx # NOREX
+ movzbl 0x45,%ecx
+
+// CHECK: movzbl 32493, %ecx # NOREX
+ movzbl 0x7eed,%ecx
+
+// CHECK: movzbl 3133065982, %ecx # NOREX
+ movzbl 0xbabecafe,%ecx
+
+// CHECK: movzbl 305419896, %ecx # NOREX
+ movzbl 0x12345678,%ecx
+
+// CHECK: movzbw 3735928559(%ebx,%ecx,8), %bx
+ movzbw 0xdeadbeef(%ebx,%ecx,8),%bx
+
+// CHECK: movzbw 69, %bx
+ movzbw 0x45,%bx
+
+// CHECK: movzbw 32493, %bx
+ movzbw 0x7eed,%bx
+
+// CHECK: movzbw 3133065982, %bx
+ movzbw 0xbabecafe,%bx
+
+// CHECK: movzbw 305419896, %bx
+ movzbw 0x12345678,%bx
+
+// CHECK: movzwl 3735928559(%ebx,%ecx,8), %ecx
+ movzwl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movzwl 69, %ecx
+ movzwl 0x45,%ecx
+
+// CHECK: movzwl 32493, %ecx
+ movzwl 0x7eed,%ecx
+
+// CHECK: movzwl 3133065982, %ecx
+ movzwl 0xbabecafe,%ecx
+
+// CHECK: movzwl 305419896, %ecx
+ movzwl 0x12345678,%ecx
+
+// CHECK: pushw 32493
+ pushw 0x7eed
+
+// CHECK: popw 32493
+ popw 0x7eed
+
+// CHECK: clc
+ clc
+
+// CHECK: cld
+ cld
+
+// CHECK: cli
+ cli
+
+// CHECK: clts
+ clts
+
+// CHECK: cmc
+ cmc
+
+// CHECK: lahf
+ lahf
+
+// CHECK: sahf
+ sahf
+
+// CHECK: stc
+ stc
+
+// CHECK: std
+ std
+
+// CHECK: sti
+ sti
+
+// CHECK: addb $254, 3735928559(%ebx,%ecx,8)
+ addb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addb $254, 69
+ addb $0xfe,0x45
+
+// CHECK: addb $254, 32493
+ addb $0xfe,0x7eed
+
+// CHECK: addb $254, 3133065982
+ addb $0xfe,0xbabecafe
+
+// CHECK: addb $254, 305419896
+ addb $0xfe,0x12345678
+
+// CHECK: addb $127, 3735928559(%ebx,%ecx,8)
+ addb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addb $127, 69
+ addb $0x7f,0x45
+
+// CHECK: addb $127, 32493
+ addb $0x7f,0x7eed
+
+// CHECK: addb $127, 3133065982
+ addb $0x7f,0xbabecafe
+
+// CHECK: addb $127, 305419896
+ addb $0x7f,0x12345678
+
+// CHECK: addw $31438, 3735928559(%ebx,%ecx,8)
+ addw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addw $31438, 69
+ addw $0x7ace,0x45
+
+// CHECK: addw $31438, 32493
+ addw $0x7ace,0x7eed
+
+// CHECK: addw $31438, 3133065982
+ addw $0x7ace,0xbabecafe
+
+// CHECK: addw $31438, 305419896
+ addw $0x7ace,0x12345678
+
+// CHECK: addl $2063514302, 3735928559(%ebx,%ecx,8)
+ addl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addl $2063514302, 69
+ addl $0x7afebabe,0x45
+
+// CHECK: addl $2063514302, 32493
+ addl $0x7afebabe,0x7eed
+
+// CHECK: addl $2063514302, 3133065982
+ addl $0x7afebabe,0xbabecafe
+
+// CHECK: addl $2063514302, 305419896
+ addl $0x7afebabe,0x12345678
+
+// CHECK: addl $324478056, 3735928559(%ebx,%ecx,8)
+ addl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addl $324478056, 69
+ addl $0x13572468,0x45
+
+// CHECK: addl $324478056, 32493
+ addl $0x13572468,0x7eed
+
+// CHECK: addl $324478056, 3133065982
+ addl $0x13572468,0xbabecafe
+
+// CHECK: addl $324478056, 305419896
+ addl $0x13572468,0x12345678
+
+// CHECK: incl 3735928559(%ebx,%ecx,8)
+ incl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: incw 32493
+ incw 0x7eed
+
+// CHECK: incl 3133065982
+ incl 0xbabecafe
+
+// CHECK: incl 305419896
+ incl 0x12345678
+
+// CHECK: subb $254, 3735928559(%ebx,%ecx,8)
+ subb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subb $254, 69
+ subb $0xfe,0x45
+
+// CHECK: subb $254, 32493
+ subb $0xfe,0x7eed
+
+// CHECK: subb $254, 3133065982
+ subb $0xfe,0xbabecafe
+
+// CHECK: subb $254, 305419896
+ subb $0xfe,0x12345678
+
+// CHECK: subb $127, 3735928559(%ebx,%ecx,8)
+ subb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subb $127, 69
+ subb $0x7f,0x45
+
+// CHECK: subb $127, 32493
+ subb $0x7f,0x7eed
+
+// CHECK: subb $127, 3133065982
+ subb $0x7f,0xbabecafe
+
+// CHECK: subb $127, 305419896
+ subb $0x7f,0x12345678
+
+// CHECK: subw $31438, 3735928559(%ebx,%ecx,8)
+ subw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subw $31438, 69
+ subw $0x7ace,0x45
+
+// CHECK: subw $31438, 32493
+ subw $0x7ace,0x7eed
+
+// CHECK: subw $31438, 3133065982
+ subw $0x7ace,0xbabecafe
+
+// CHECK: subw $31438, 305419896
+ subw $0x7ace,0x12345678
+
+// CHECK: subl $2063514302, 3735928559(%ebx,%ecx,8)
+ subl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subl $2063514302, 69
+ subl $0x7afebabe,0x45
+
+// CHECK: subl $2063514302, 32493
+ subl $0x7afebabe,0x7eed
+
+// CHECK: subl $2063514302, 3133065982
+ subl $0x7afebabe,0xbabecafe
+
+// CHECK: subl $2063514302, 305419896
+ subl $0x7afebabe,0x12345678
+
+// CHECK: subl $324478056, 3735928559(%ebx,%ecx,8)
+ subl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subl $324478056, 69
+ subl $0x13572468,0x45
+
+// CHECK: subl $324478056, 32493
+ subl $0x13572468,0x7eed
+
+// CHECK: subl $324478056, 3133065982
+ subl $0x13572468,0xbabecafe
+
+// CHECK: subl $324478056, 305419896
+ subl $0x13572468,0x12345678
+
+// CHECK: decl 3735928559(%ebx,%ecx,8)
+ decl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: decw 32493
+ decw 0x7eed
+
+// CHECK: decl 3133065982
+ decl 0xbabecafe
+
+// CHECK: decl 305419896
+ decl 0x12345678
+
+// CHECK: sbbb $254, 3735928559(%ebx,%ecx,8)
+ sbbb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbb $254, 69
+ sbbb $0xfe,0x45
+
+// CHECK: sbbb $254, 32493
+ sbbb $0xfe,0x7eed
+
+// CHECK: sbbb $254, 3133065982
+ sbbb $0xfe,0xbabecafe
+
+// CHECK: sbbb $254, 305419896
+ sbbb $0xfe,0x12345678
+
+// CHECK: sbbb $127, 3735928559(%ebx,%ecx,8)
+ sbbb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbb $127, 69
+ sbbb $0x7f,0x45
+
+// CHECK: sbbb $127, 32493
+ sbbb $0x7f,0x7eed
+
+// CHECK: sbbb $127, 3133065982
+ sbbb $0x7f,0xbabecafe
+
+// CHECK: sbbb $127, 305419896
+ sbbb $0x7f,0x12345678
+
+// CHECK: sbbw $31438, 3735928559(%ebx,%ecx,8)
+ sbbw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbw $31438, 69
+ sbbw $0x7ace,0x45
+
+// CHECK: sbbw $31438, 32493
+ sbbw $0x7ace,0x7eed
+
+// CHECK: sbbw $31438, 3133065982
+ sbbw $0x7ace,0xbabecafe
+
+// CHECK: sbbw $31438, 305419896
+ sbbw $0x7ace,0x12345678
+
+// CHECK: sbbl $2063514302, 3735928559(%ebx,%ecx,8)
+ sbbl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbl $2063514302, 69
+ sbbl $0x7afebabe,0x45
+
+// CHECK: sbbl $2063514302, 32493
+ sbbl $0x7afebabe,0x7eed
+
+// CHECK: sbbl $2063514302, 3133065982
+ sbbl $0x7afebabe,0xbabecafe
+
+// CHECK: sbbl $2063514302, 305419896
+ sbbl $0x7afebabe,0x12345678
+
+// CHECK: sbbl $324478056, 3735928559(%ebx,%ecx,8)
+ sbbl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbl $324478056, 69
+ sbbl $0x13572468,0x45
+
+// CHECK: sbbl $324478056, 32493
+ sbbl $0x13572468,0x7eed
+
+// CHECK: sbbl $324478056, 3133065982
+ sbbl $0x13572468,0xbabecafe
+
+// CHECK: sbbl $324478056, 305419896
+ sbbl $0x13572468,0x12345678
+
+// CHECK: cmpb $254, 3735928559(%ebx,%ecx,8)
+ cmpb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpb $254, 69
+ cmpb $0xfe,0x45
+
+// CHECK: cmpb $254, 32493
+ cmpb $0xfe,0x7eed
+
+// CHECK: cmpb $254, 3133065982
+ cmpb $0xfe,0xbabecafe
+
+// CHECK: cmpb $254, 305419896
+ cmpb $0xfe,0x12345678
+
+// CHECK: cmpb $127, 3735928559(%ebx,%ecx,8)
+ cmpb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpb $127, 69
+ cmpb $0x7f,0x45
+
+// CHECK: cmpb $127, 32493
+ cmpb $0x7f,0x7eed
+
+// CHECK: cmpb $127, 3133065982
+ cmpb $0x7f,0xbabecafe
+
+// CHECK: cmpb $127, 305419896
+ cmpb $0x7f,0x12345678
+
+// CHECK: cmpw $31438, 3735928559(%ebx,%ecx,8)
+ cmpw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpw $31438, 69
+ cmpw $0x7ace,0x45
+
+// CHECK: cmpw $31438, 32493
+ cmpw $0x7ace,0x7eed
+
+// CHECK: cmpw $31438, 3133065982
+ cmpw $0x7ace,0xbabecafe
+
+// CHECK: cmpw $31438, 305419896
+ cmpw $0x7ace,0x12345678
+
+// CHECK: cmpl $2063514302, 3735928559(%ebx,%ecx,8)
+ cmpl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpl $2063514302, 69
+ cmpl $0x7afebabe,0x45
+
+// CHECK: cmpl $2063514302, 32493
+ cmpl $0x7afebabe,0x7eed
+
+// CHECK: cmpl $2063514302, 3133065982
+ cmpl $0x7afebabe,0xbabecafe
+
+// CHECK: cmpl $2063514302, 305419896
+ cmpl $0x7afebabe,0x12345678
+
+// CHECK: cmpl $324478056, 3735928559(%ebx,%ecx,8)
+ cmpl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpl $324478056, 69
+ cmpl $0x13572468,0x45
+
+// CHECK: cmpl $324478056, 32493
+ cmpl $0x13572468,0x7eed
+
+// CHECK: cmpl $324478056, 3133065982
+ cmpl $0x13572468,0xbabecafe
+
+// CHECK: cmpl $324478056, 305419896
+ cmpl $0x13572468,0x12345678
+
+// CHECK: testb $127, 3735928559(%ebx,%ecx,8)
+ testb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testb $127, 69
+ testb $0x7f,0x45
+
+// CHECK: testb $127, 32493
+ testb $0x7f,0x7eed
+
+// CHECK: testb $127, 3133065982
+ testb $0x7f,0xbabecafe
+
+// CHECK: testb $127, 305419896
+ testb $0x7f,0x12345678
+
+// CHECK: testw $31438, 3735928559(%ebx,%ecx,8)
+ testw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testw $31438, 69
+ testw $0x7ace,0x45
+
+// CHECK: testw $31438, 32493
+ testw $0x7ace,0x7eed
+
+// CHECK: testw $31438, 3133065982
+ testw $0x7ace,0xbabecafe
+
+// CHECK: testw $31438, 305419896
+ testw $0x7ace,0x12345678
+
+// CHECK: testl $2063514302, 3735928559(%ebx,%ecx,8)
+ testl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testl $2063514302, 69
+ testl $0x7afebabe,0x45
+
+// CHECK: testl $2063514302, 32493
+ testl $0x7afebabe,0x7eed
+
+// CHECK: testl $2063514302, 3133065982
+ testl $0x7afebabe,0xbabecafe
+
+// CHECK: testl $2063514302, 305419896
+ testl $0x7afebabe,0x12345678
+
+// CHECK: testl $324478056, 3735928559(%ebx,%ecx,8)
+ testl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testl $324478056, 69
+ testl $0x13572468,0x45
+
+// CHECK: testl $324478056, 32493
+ testl $0x13572468,0x7eed
+
+// CHECK: testl $324478056, 3133065982
+ testl $0x13572468,0xbabecafe
+
+// CHECK: testl $324478056, 305419896
+ testl $0x13572468,0x12345678
+
+// CHECK: andb $254, 3735928559(%ebx,%ecx,8)
+ andb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andb $254, 69
+ andb $0xfe,0x45
+
+// CHECK: andb $254, 32493
+ andb $0xfe,0x7eed
+
+// CHECK: andb $254, 3133065982
+ andb $0xfe,0xbabecafe
+
+// CHECK: andb $254, 305419896
+ andb $0xfe,0x12345678
+
+// CHECK: andb $127, 3735928559(%ebx,%ecx,8)
+ andb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andb $127, 69
+ andb $0x7f,0x45
+
+// CHECK: andb $127, 32493
+ andb $0x7f,0x7eed
+
+// CHECK: andb $127, 3133065982
+ andb $0x7f,0xbabecafe
+
+// CHECK: andb $127, 305419896
+ andb $0x7f,0x12345678
+
+// CHECK: andw $31438, 3735928559(%ebx,%ecx,8)
+ andw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andw $31438, 69
+ andw $0x7ace,0x45
+
+// CHECK: andw $31438, 32493
+ andw $0x7ace,0x7eed
+
+// CHECK: andw $31438, 3133065982
+ andw $0x7ace,0xbabecafe
+
+// CHECK: andw $31438, 305419896
+ andw $0x7ace,0x12345678
+
+// CHECK: andl $2063514302, 3735928559(%ebx,%ecx,8)
+ andl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andl $2063514302, 69
+ andl $0x7afebabe,0x45
+
+// CHECK: andl $2063514302, 32493
+ andl $0x7afebabe,0x7eed
+
+// CHECK: andl $2063514302, 3133065982
+ andl $0x7afebabe,0xbabecafe
+
+// CHECK: andl $2063514302, 305419896
+ andl $0x7afebabe,0x12345678
+
+// CHECK: andl $324478056, 3735928559(%ebx,%ecx,8)
+ andl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andl $324478056, 69
+ andl $0x13572468,0x45
+
+// CHECK: andl $324478056, 32493
+ andl $0x13572468,0x7eed
+
+// CHECK: andl $324478056, 3133065982
+ andl $0x13572468,0xbabecafe
+
+// CHECK: andl $324478056, 305419896
+ andl $0x13572468,0x12345678
+
+// CHECK: orb $254, 3735928559(%ebx,%ecx,8)
+ orb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orb $254, 69
+ orb $0xfe,0x45
+
+// CHECK: orb $254, 32493
+ orb $0xfe,0x7eed
+
+// CHECK: orb $254, 3133065982
+ orb $0xfe,0xbabecafe
+
+// CHECK: orb $254, 305419896
+ orb $0xfe,0x12345678
+
+// CHECK: orb $127, 3735928559(%ebx,%ecx,8)
+ orb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orb $127, 69
+ orb $0x7f,0x45
+
+// CHECK: orb $127, 32493
+ orb $0x7f,0x7eed
+
+// CHECK: orb $127, 3133065982
+ orb $0x7f,0xbabecafe
+
+// CHECK: orb $127, 305419896
+ orb $0x7f,0x12345678
+
+// CHECK: orw $31438, 3735928559(%ebx,%ecx,8)
+ orw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orw $31438, 69
+ orw $0x7ace,0x45
+
+// CHECK: orw $31438, 32493
+ orw $0x7ace,0x7eed
+
+// CHECK: orw $31438, 3133065982
+ orw $0x7ace,0xbabecafe
+
+// CHECK: orw $31438, 305419896
+ orw $0x7ace,0x12345678
+
+// CHECK: orl $2063514302, 3735928559(%ebx,%ecx,8)
+ orl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orl $2063514302, 69
+ orl $0x7afebabe,0x45
+
+// CHECK: orl $2063514302, 32493
+ orl $0x7afebabe,0x7eed
+
+// CHECK: orl $2063514302, 3133065982
+ orl $0x7afebabe,0xbabecafe
+
+// CHECK: orl $2063514302, 305419896
+ orl $0x7afebabe,0x12345678
+
+// CHECK: orl $324478056, 3735928559(%ebx,%ecx,8)
+ orl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orl $324478056, 69
+ orl $0x13572468,0x45
+
+// CHECK: orl $324478056, 32493
+ orl $0x13572468,0x7eed
+
+// CHECK: orl $324478056, 3133065982
+ orl $0x13572468,0xbabecafe
+
+// CHECK: orl $324478056, 305419896
+ orl $0x13572468,0x12345678
+
+// CHECK: xorb $254, 3735928559(%ebx,%ecx,8)
+ xorb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorb $254, 69
+ xorb $0xfe,0x45
+
+// CHECK: xorb $254, 32493
+ xorb $0xfe,0x7eed
+
+// CHECK: xorb $254, 3133065982
+ xorb $0xfe,0xbabecafe
+
+// CHECK: xorb $254, 305419896
+ xorb $0xfe,0x12345678
+
+// CHECK: xorb $127, 3735928559(%ebx,%ecx,8)
+ xorb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorb $127, 69
+ xorb $0x7f,0x45
+
+// CHECK: xorb $127, 32493
+ xorb $0x7f,0x7eed
+
+// CHECK: xorb $127, 3133065982
+ xorb $0x7f,0xbabecafe
+
+// CHECK: xorb $127, 305419896
+ xorb $0x7f,0x12345678
+
+// CHECK: xorw $31438, 3735928559(%ebx,%ecx,8)
+ xorw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorw $31438, 69
+ xorw $0x7ace,0x45
+
+// CHECK: xorw $31438, 32493
+ xorw $0x7ace,0x7eed
+
+// CHECK: xorw $31438, 3133065982
+ xorw $0x7ace,0xbabecafe
+
+// CHECK: xorw $31438, 305419896
+ xorw $0x7ace,0x12345678
+
+// CHECK: xorl $2063514302, 3735928559(%ebx,%ecx,8)
+ xorl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorl $2063514302, 69
+ xorl $0x7afebabe,0x45
+
+// CHECK: xorl $2063514302, 32493
+ xorl $0x7afebabe,0x7eed
+
+// CHECK: xorl $2063514302, 3133065982
+ xorl $0x7afebabe,0xbabecafe
+
+// CHECK: xorl $2063514302, 305419896
+ xorl $0x7afebabe,0x12345678
+
+// CHECK: xorl $324478056, 3735928559(%ebx,%ecx,8)
+ xorl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorl $324478056, 69
+ xorl $0x13572468,0x45
+
+// CHECK: xorl $324478056, 32493
+ xorl $0x13572468,0x7eed
+
+// CHECK: xorl $324478056, 3133065982
+ xorl $0x13572468,0xbabecafe
+
+// CHECK: xorl $324478056, 305419896
+ xorl $0x13572468,0x12345678
+
+// CHECK: adcb $254, 3735928559(%ebx,%ecx,8)
+ adcb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcb $254, 69
+ adcb $0xfe,0x45
+
+// CHECK: adcb $254, 32493
+ adcb $0xfe,0x7eed
+
+// CHECK: adcb $254, 3133065982
+ adcb $0xfe,0xbabecafe
+
+// CHECK: adcb $254, 305419896
+ adcb $0xfe,0x12345678
+
+// CHECK: adcb $127, 3735928559(%ebx,%ecx,8)
+ adcb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcb $127, 69
+ adcb $0x7f,0x45
+
+// CHECK: adcb $127, 32493
+ adcb $0x7f,0x7eed
+
+// CHECK: adcb $127, 3133065982
+ adcb $0x7f,0xbabecafe
+
+// CHECK: adcb $127, 305419896
+ adcb $0x7f,0x12345678
+
+// CHECK: adcw $31438, 3735928559(%ebx,%ecx,8)
+ adcw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcw $31438, 69
+ adcw $0x7ace,0x45
+
+// CHECK: adcw $31438, 32493
+ adcw $0x7ace,0x7eed
+
+// CHECK: adcw $31438, 3133065982
+ adcw $0x7ace,0xbabecafe
+
+// CHECK: adcw $31438, 305419896
+ adcw $0x7ace,0x12345678
+
+// CHECK: adcl $2063514302, 3735928559(%ebx,%ecx,8)
+ adcl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcl $2063514302, 69
+ adcl $0x7afebabe,0x45
+
+// CHECK: adcl $2063514302, 32493
+ adcl $0x7afebabe,0x7eed
+
+// CHECK: adcl $2063514302, 3133065982
+ adcl $0x7afebabe,0xbabecafe
+
+// CHECK: adcl $2063514302, 305419896
+ adcl $0x7afebabe,0x12345678
+
+// CHECK: adcl $324478056, 3735928559(%ebx,%ecx,8)
+ adcl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcl $324478056, 69
+ adcl $0x13572468,0x45
+
+// CHECK: adcl $324478056, 32493
+ adcl $0x13572468,0x7eed
+
+// CHECK: adcl $324478056, 3133065982
+ adcl $0x13572468,0xbabecafe
+
+// CHECK: adcl $324478056, 305419896
+ adcl $0x13572468,0x12345678
+
+// CHECK: negl 3735928559(%ebx,%ecx,8)
+ negl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: negw 32493
+ negw 0x7eed
+
+// CHECK: negl 3133065982
+ negl 0xbabecafe
+
+// CHECK: negl 305419896
+ negl 0x12345678
+
+// CHECK: notl 3735928559(%ebx,%ecx,8)
+ notl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: notw 32493
+ notw 0x7eed
+
+// CHECK: notl 3133065982
+ notl 0xbabecafe
+
+// CHECK: notl 305419896
+ notl 0x12345678
+
+// CHECK: cbtw
+ cbtw
+
+// CHECK: cwtl
+ cwtl
+
+// CHECK: cwtd
+ cwtd
+
+// CHECK: cltd
+ cltd
+
+// CHECK: mull 3735928559(%ebx,%ecx,8)
+ mull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: mulw 32493
+ mulw 0x7eed
+
+// CHECK: mull 3133065982
+ mull 0xbabecafe
+
+// CHECK: mull 305419896
+ mull 0x12345678
+
+// CHECK: imull 3735928559(%ebx,%ecx,8)
+ imull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: imulw 32493
+ imulw 0x7eed
+
+// CHECK: imull 3133065982
+ imull 0xbabecafe
+
+// CHECK: imull 305419896
+ imull 0x12345678
+
+// CHECK: divl 3735928559(%ebx,%ecx,8)
+ divl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: divw 32493
+ divw 0x7eed
+
+// CHECK: divl 3133065982
+ divl 0xbabecafe
+
+// CHECK: divl 305419896
+ divl 0x12345678
+
+// CHECK: idivl 3735928559(%ebx,%ecx,8)
+ idivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: idivw 32493
+ idivw 0x7eed
+
+// CHECK: idivl 3133065982
+ idivl 0xbabecafe
+
+// CHECK: idivl 305419896
+ idivl 0x12345678
+
+// CHECK: roll $0, 3735928559(%ebx,%ecx,8)
+ roll $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: roll $0, 69
+ roll $0,0x45
+
+// CHECK: roll $0, 32493
+ roll $0,0x7eed
+
+// CHECK: roll $0, 3133065982
+ roll $0,0xbabecafe
+
+// CHECK: roll $0, 305419896
+ roll $0,0x12345678
+
+// CHECK: rolb $127, 3735928559(%ebx,%ecx,8)
+ rolb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rolb $127, 69
+ rolb $0x7f,0x45
+
+// CHECK: rolb $127, 32493
+ rolb $0x7f,0x7eed
+
+// CHECK: rolb $127, 3133065982
+ rolb $0x7f,0xbabecafe
+
+// CHECK: rolb $127, 305419896
+ rolb $0x7f,0x12345678
+
+// CHECK: roll 3735928559(%ebx,%ecx,8)
+ roll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rolw 32493
+ rolw 0x7eed
+
+// CHECK: roll 3133065982
+ roll 0xbabecafe
+
+// CHECK: roll 305419896
+ roll 0x12345678
+
+// CHECK: rorl $0, 3735928559(%ebx,%ecx,8)
+ rorl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorl $0, 69
+ rorl $0,0x45
+
+// CHECK: rorl $0, 32493
+ rorl $0,0x7eed
+
+// CHECK: rorl $0, 3133065982
+ rorl $0,0xbabecafe
+
+// CHECK: rorl $0, 305419896
+ rorl $0,0x12345678
+
+// CHECK: rorb $127, 3735928559(%ebx,%ecx,8)
+ rorb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorb $127, 69
+ rorb $0x7f,0x45
+
+// CHECK: rorb $127, 32493
+ rorb $0x7f,0x7eed
+
+// CHECK: rorb $127, 3133065982
+ rorb $0x7f,0xbabecafe
+
+// CHECK: rorb $127, 305419896
+ rorb $0x7f,0x12345678
+
+// CHECK: rorl 3735928559(%ebx,%ecx,8)
+ rorl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorw 32493
+ rorw 0x7eed
+
+// CHECK: rorl 3133065982
+ rorl 0xbabecafe
+
+// CHECK: rorl 305419896
+ rorl 0x12345678
+
+// CHECK: rcll $0, 3735928559(%ebx,%ecx,8)
+ rcll $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rcll $0, 69
+ rcll $0,0x45
+
+// CHECK: rcll $0, 32493
+ rcll $0,0x7eed
+
+// CHECK: rcll $0, 3133065982
+ rcll $0,0xbabecafe
+
+// CHECK: rcll $0, 305419896
+ rcll $0,0x12345678
+
+// CHECK: rclb $127, 3735928559(%ebx,%ecx,8)
+ rclb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rclb $127, 69
+ rclb $0x7f,0x45
+
+// CHECK: rclb $127, 32493
+ rclb $0x7f,0x7eed
+
+// CHECK: rclb $127, 3133065982
+ rclb $0x7f,0xbabecafe
+
+// CHECK: rclb $127, 305419896
+ rclb $0x7f,0x12345678
+
+// CHECK: rcrl $0, 3735928559(%ebx,%ecx,8)
+ rcrl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rcrl $0, 69
+ rcrl $0,0x45
+
+// CHECK: rcrl $0, 32493
+ rcrl $0,0x7eed
+
+// CHECK: rcrl $0, 3133065982
+ rcrl $0,0xbabecafe
+
+// CHECK: rcrl $0, 305419896
+ rcrl $0,0x12345678
+
+// CHECK: rcrb $127, 3735928559(%ebx,%ecx,8)
+ rcrb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rcrb $127, 69
+ rcrb $0x7f,0x45
+
+// CHECK: rcrb $127, 32493
+ rcrb $0x7f,0x7eed
+
+// CHECK: rcrb $127, 3133065982
+ rcrb $0x7f,0xbabecafe
+
+// CHECK: rcrb $127, 305419896
+ rcrb $0x7f,0x12345678
+
+// CHECK: shll $0, 3735928559(%ebx,%ecx,8)
+ sall $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shll $0, 69
+ sall $0,0x45
+
+// CHECK: shll $0, 32493
+ sall $0,0x7eed
+
+// CHECK: shll $0, 3133065982
+ sall $0,0xbabecafe
+
+// CHECK: shll $0, 305419896
+ sall $0,0x12345678
+
+// CHECK: shlb $127, 3735928559(%ebx,%ecx,8)
+ salb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlb $127, 69
+ salb $0x7f,0x45
+
+// CHECK: shlb $127, 32493
+ salb $0x7f,0x7eed
+
+// CHECK: shlb $127, 3133065982
+ salb $0x7f,0xbabecafe
+
+// CHECK: shlb $127, 305419896
+ salb $0x7f,0x12345678
+
+// CHECK: shll 3735928559(%ebx,%ecx,8)
+ sall 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlw 32493
+ salw 0x7eed
+
+// CHECK: shll 3133065982
+ sall 0xbabecafe
+
+// CHECK: shll 305419896
+ sall 0x12345678
+
+// CHECK: shll $0, 3735928559(%ebx,%ecx,8)
+ shll $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shll $0, 69
+ shll $0,0x45
+
+// CHECK: shll $0, 32493
+ shll $0,0x7eed
+
+// CHECK: shll $0, 3133065982
+ shll $0,0xbabecafe
+
+// CHECK: shll $0, 305419896
+ shll $0,0x12345678
+
+// CHECK: shlb $127, 3735928559(%ebx,%ecx,8)
+ shlb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlb $127, 69
+ shlb $0x7f,0x45
+
+// CHECK: shlb $127, 32493
+ shlb $0x7f,0x7eed
+
+// CHECK: shlb $127, 3133065982
+ shlb $0x7f,0xbabecafe
+
+// CHECK: shlb $127, 305419896
+ shlb $0x7f,0x12345678
+
+// CHECK: shll 3735928559(%ebx,%ecx,8)
+ shll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlw 32493
+ shlw 0x7eed
+
+// CHECK: shll 3133065982
+ shll 0xbabecafe
+
+// CHECK: shll 305419896
+ shll 0x12345678
+
+// CHECK: shrl $0, 3735928559(%ebx,%ecx,8)
+ shrl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrl $0, 69
+ shrl $0,0x45
+
+// CHECK: shrl $0, 32493
+ shrl $0,0x7eed
+
+// CHECK: shrl $0, 3133065982
+ shrl $0,0xbabecafe
+
+// CHECK: shrl $0, 305419896
+ shrl $0,0x12345678
+
+// CHECK: shrb $127, 3735928559(%ebx,%ecx,8)
+ shrb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrb $127, 69
+ shrb $0x7f,0x45
+
+// CHECK: shrb $127, 32493
+ shrb $0x7f,0x7eed
+
+// CHECK: shrb $127, 3133065982
+ shrb $0x7f,0xbabecafe
+
+// CHECK: shrb $127, 305419896
+ shrb $0x7f,0x12345678
+
+// CHECK: shrl 3735928559(%ebx,%ecx,8)
+ shrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrw 32493
+ shrw 0x7eed
+
+// CHECK: shrl 3133065982
+ shrl 0xbabecafe
+
+// CHECK: shrl 305419896
+ shrl 0x12345678
+
+// CHECK: sarl $0, 3735928559(%ebx,%ecx,8)
+ sarl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarl $0, 69
+ sarl $0,0x45
+
+// CHECK: sarl $0, 32493
+ sarl $0,0x7eed
+
+// CHECK: sarl $0, 3133065982
+ sarl $0,0xbabecafe
+
+// CHECK: sarl $0, 305419896
+ sarl $0,0x12345678
+
+// CHECK: sarb $127, 3735928559(%ebx,%ecx,8)
+ sarb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarb $127, 69
+ sarb $0x7f,0x45
+
+// CHECK: sarb $127, 32493
+ sarb $0x7f,0x7eed
+
+// CHECK: sarb $127, 3133065982
+ sarb $0x7f,0xbabecafe
+
+// CHECK: sarb $127, 305419896
+ sarb $0x7f,0x12345678
+
+// CHECK: sarl 3735928559(%ebx,%ecx,8)
+ sarl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarw 32493
+ sarw 0x7eed
+
+// CHECK: sarl 3133065982
+ sarl 0xbabecafe
+
+// CHECK: sarl 305419896
+ sarl 0x12345678
+
+// CHECK: call 3133065982
+ call 0xbabecafe
+
+// CHECK: call *3735928559(%ebx,%ecx,8)
+ call *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: call 3133065982
+ call 0xbabecafe
+
+// CHECK: call 305419896
+ call 0x12345678
+
+// CHECK: call *3135175374
+ call *0xbadeface
+
+// CHECK: call *3735928559(%ebx,%ecx,8)
+ call *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: call 32493
+ call 0x7eed
+
+// CHECK: call 3133065982
+ call 0xbabecafe
+
+// CHECK: call 305419896
+ call 0x12345678
+
+// CHECK: call *3135175374
+ call *0xbadeface
+
+// CHECK: lcallw *32493
+ lcallw *0x7eed
+
+// CHECK: jmp 32493
+ jmp 0x7eed
+
+// CHECK: jmp 3133065982
+ jmp 0xbabecafe
+
+// CHECK: jmp 305419896
+ jmp 0x12345678
+
+// CHECK: jmp -77129852792157442
+ jmp 0xfeedfacebabecafe
+
+// CHECK: jmp *3735928559(%ebx,%ecx,8)
+ jmp *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: jmp 32493
+ jmp 0x7eed
+
+// CHECK: jmp 3133065982
+ jmp 0xbabecafe
+
+// CHECK: jmp 305419896
+ jmp 0x12345678
+
+// CHECK: jmp *3135175374
+ jmp *0xbadeface
+
+// CHECK: jmp *3735928559(%ebx,%ecx,8)
+ jmp *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: jmp 32493
+ jmp 0x7eed
+
+// CHECK: jmp 3133065982
+ jmp 0xbabecafe
+
+// CHECK: jmp 305419896
+ jmp 0x12345678
+
+// CHECK: jmp *3135175374
+ jmp *0xbadeface
+
+// CHECK: ljmpl *3735928559(%ebx,%ecx,8)
+ ljmpl *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ljmpw *32493
+ ljmpw *0x7eed
+
+// CHECK: ljmpl *3133065982
+ ljmpl *0xbabecafe
+
+// CHECK: ljmpl *305419896
+ ljmpl *0x12345678
+
+// CHECK: ret
+ ret
+
+// CHECK: lret
+ lret
+
+// CHECK: enter $31438, $127
+ enter $0x7ace,$0x7f
+
+// CHECK: leave
+ leave
+
+// CHECK: jo 32493
+ jo 0x7eed
+
+// CHECK: jo 3133065982
+ jo 0xbabecafe
+
+// CHECK: jo 305419896
+ jo 0x12345678
+
+// CHECK: jo -77129852792157442
+ jo 0xfeedfacebabecafe
+
+// CHECK: jno 32493
+ jno 0x7eed
+
+// CHECK: jno 3133065982
+ jno 0xbabecafe
+
+// CHECK: jno 305419896
+ jno 0x12345678
+
+// CHECK: jno -77129852792157442
+ jno 0xfeedfacebabecafe
+
+// CHECK: jb 32493
+ jb 0x7eed
+
+// CHECK: jb 3133065982
+ jb 0xbabecafe
+
+// CHECK: jb 305419896
+ jb 0x12345678
+
+// CHECK: jb -77129852792157442
+ jb 0xfeedfacebabecafe
+
+// CHECK: jae 32493
+ jae 0x7eed
+
+// CHECK: jae 3133065982
+ jae 0xbabecafe
+
+// CHECK: jae 305419896
+ jae 0x12345678
+
+// CHECK: jae -77129852792157442
+ jae 0xfeedfacebabecafe
+
+// CHECK: je 32493
+ je 0x7eed
+
+// CHECK: je 3133065982
+ je 0xbabecafe
+
+// CHECK: je 305419896
+ je 0x12345678
+
+// CHECK: je -77129852792157442
+ je 0xfeedfacebabecafe
+
+// CHECK: jne 32493
+ jne 0x7eed
+
+// CHECK: jne 3133065982
+ jne 0xbabecafe
+
+// CHECK: jne 305419896
+ jne 0x12345678
+
+// CHECK: jne -77129852792157442
+ jne 0xfeedfacebabecafe
+
+// CHECK: jbe 32493
+ jbe 0x7eed
+
+// CHECK: jbe 3133065982
+ jbe 0xbabecafe
+
+// CHECK: jbe 305419896
+ jbe 0x12345678
+
+// CHECK: jbe -77129852792157442
+ jbe 0xfeedfacebabecafe
+
+// CHECK: ja 32493
+ ja 0x7eed
+
+// CHECK: ja 3133065982
+ ja 0xbabecafe
+
+// CHECK: ja 305419896
+ ja 0x12345678
+
+// CHECK: ja -77129852792157442
+ ja 0xfeedfacebabecafe
+
+// CHECK: js 32493
+ js 0x7eed
+
+// CHECK: js 3133065982
+ js 0xbabecafe
+
+// CHECK: js 305419896
+ js 0x12345678
+
+// CHECK: js -77129852792157442
+ js 0xfeedfacebabecafe
+
+// CHECK: jns 32493
+ jns 0x7eed
+
+// CHECK: jns 3133065982
+ jns 0xbabecafe
+
+// CHECK: jns 305419896
+ jns 0x12345678
+
+// CHECK: jns -77129852792157442
+ jns 0xfeedfacebabecafe
+
+// CHECK: jp 32493
+ jp 0x7eed
+
+// CHECK: jp 3133065982
+ jp 0xbabecafe
+
+// CHECK: jp 305419896
+ jp 0x12345678
+
+// CHECK: jp -77129852792157442
+ jp 0xfeedfacebabecafe
+
+// CHECK: jnp 32493
+ jnp 0x7eed
+
+// CHECK: jnp 3133065982
+ jnp 0xbabecafe
+
+// CHECK: jnp 305419896
+ jnp 0x12345678
+
+// CHECK: jnp -77129852792157442
+ jnp 0xfeedfacebabecafe
+
+// CHECK: jl 32493
+ jl 0x7eed
+
+// CHECK: jl 3133065982
+ jl 0xbabecafe
+
+// CHECK: jl 305419896
+ jl 0x12345678
+
+// CHECK: jl -77129852792157442
+ jl 0xfeedfacebabecafe
+
+// CHECK: jge 32493
+ jge 0x7eed
+
+// CHECK: jge 3133065982
+ jge 0xbabecafe
+
+// CHECK: jge 305419896
+ jge 0x12345678
+
+// CHECK: jge -77129852792157442
+ jge 0xfeedfacebabecafe
+
+// CHECK: jle 32493
+ jle 0x7eed
+
+// CHECK: jle 3133065982
+ jle 0xbabecafe
+
+// CHECK: jle 305419896
+ jle 0x12345678
+
+// CHECK: jle -77129852792157442
+ jle 0xfeedfacebabecafe
+
+// CHECK: jg 32493
+ jg 0x7eed
+
+// CHECK: jg 3133065982
+ jg 0xbabecafe
+
+// CHECK: jg 305419896
+ jg 0x12345678
+
+// CHECK: jg -77129852792157442
+ jg 0xfeedfacebabecafe
+
+// CHECK: seto %bl
+ seto %bl
+
+// CHECK: seto 3735928559(%ebx,%ecx,8)
+ seto 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: seto 32493
+ seto 0x7eed
+
+// CHECK: seto 3133065982
+ seto 0xbabecafe
+
+// CHECK: seto 305419896
+ seto 0x12345678
+
+// CHECK: setno %bl
+ setno %bl
+
+// CHECK: setno 3735928559(%ebx,%ecx,8)
+ setno 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setno 32493
+ setno 0x7eed
+
+// CHECK: setno 3133065982
+ setno 0xbabecafe
+
+// CHECK: setno 305419896
+ setno 0x12345678
+
+// CHECK: setb %bl
+ setb %bl
+
+// CHECK: setb 3735928559(%ebx,%ecx,8)
+ setb 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setb 32493
+ setb 0x7eed
+
+// CHECK: setb 3133065982
+ setb 0xbabecafe
+
+// CHECK: setb 305419896
+ setb 0x12345678
+
+// CHECK: setae %bl
+ setae %bl
+
+// CHECK: setae 3735928559(%ebx,%ecx,8)
+ setae 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setae 32493
+ setae 0x7eed
+
+// CHECK: setae 3133065982
+ setae 0xbabecafe
+
+// CHECK: setae 305419896
+ setae 0x12345678
+
+// CHECK: sete %bl
+ sete %bl
+
+// CHECK: sete 3735928559(%ebx,%ecx,8)
+ sete 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sete 32493
+ sete 0x7eed
+
+// CHECK: sete 3133065982
+ sete 0xbabecafe
+
+// CHECK: sete 305419896
+ sete 0x12345678
+
+// CHECK: setne %bl
+ setne %bl
+
+// CHECK: setne 3735928559(%ebx,%ecx,8)
+ setne 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setne 32493
+ setne 0x7eed
+
+// CHECK: setne 3133065982
+ setne 0xbabecafe
+
+// CHECK: setne 305419896
+ setne 0x12345678
+
+// CHECK: setbe %bl
+ setbe %bl
+
+// CHECK: setbe 3735928559(%ebx,%ecx,8)
+ setbe 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setbe 32493
+ setbe 0x7eed
+
+// CHECK: setbe 3133065982
+ setbe 0xbabecafe
+
+// CHECK: setbe 305419896
+ setbe 0x12345678
+
+// CHECK: seta %bl
+ seta %bl
+
+// CHECK: seta 3735928559(%ebx,%ecx,8)
+ seta 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: seta 32493
+ seta 0x7eed
+
+// CHECK: seta 3133065982
+ seta 0xbabecafe
+
+// CHECK: seta 305419896
+ seta 0x12345678
+
+// CHECK: sets %bl
+ sets %bl
+
+// CHECK: sets 3735928559(%ebx,%ecx,8)
+ sets 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sets 32493
+ sets 0x7eed
+
+// CHECK: sets 3133065982
+ sets 0xbabecafe
+
+// CHECK: sets 305419896
+ sets 0x12345678
+
+// CHECK: setns %bl
+ setns %bl
+
+// CHECK: setns 3735928559(%ebx,%ecx,8)
+ setns 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setns 32493
+ setns 0x7eed
+
+// CHECK: setns 3133065982
+ setns 0xbabecafe
+
+// CHECK: setns 305419896
+ setns 0x12345678
+
+// CHECK: setp %bl
+ setp %bl
+
+// CHECK: setp 3735928559(%ebx,%ecx,8)
+ setp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setp 32493
+ setp 0x7eed
+
+// CHECK: setp 3133065982
+ setp 0xbabecafe
+
+// CHECK: setp 305419896
+ setp 0x12345678
+
+// CHECK: setnp %bl
+ setnp %bl
+
+// CHECK: setnp 3735928559(%ebx,%ecx,8)
+ setnp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setnp 32493
+ setnp 0x7eed
+
+// CHECK: setnp 3133065982
+ setnp 0xbabecafe
+
+// CHECK: setnp 305419896
+ setnp 0x12345678
+
+// CHECK: setl %bl
+ setl %bl
+
+// CHECK: setl 3735928559(%ebx,%ecx,8)
+ setl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setl 32493
+ setl 0x7eed
+
+// CHECK: setl 3133065982
+ setl 0xbabecafe
+
+// CHECK: setl 305419896
+ setl 0x12345678
+
+// CHECK: setge %bl
+ setge %bl
+
+// CHECK: setge 3735928559(%ebx,%ecx,8)
+ setge 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setge 32493
+ setge 0x7eed
+
+// CHECK: setge 3133065982
+ setge 0xbabecafe
+
+// CHECK: setge 305419896
+ setge 0x12345678
+
+// CHECK: setle %bl
+ setle %bl
+
+// CHECK: setle 3735928559(%ebx,%ecx,8)
+ setle 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setle 32493
+ setle 0x7eed
+
+// CHECK: setle 3133065982
+ setle 0xbabecafe
+
+// CHECK: setle 305419896
+ setle 0x12345678
+
+// CHECK: setg %bl
+ setg %bl
+
+// CHECK: setg 3735928559(%ebx,%ecx,8)
+ setg 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setg 32493
+ setg 0x7eed
+
+// CHECK: setg 3133065982
+ setg 0xbabecafe
+
+// CHECK: setg 305419896
+ setg 0x12345678
+
+// CHECK: int $127
+ int $0x7f
+
+// CHECK: rsm
+ rsm
+
+// CHECK: hlt
+ hlt
+
+// CHECK: nopl 3735928559(%ebx,%ecx,8)
+ nopl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: nopw 32493
+ nopw 0x7eed
+
+// CHECK: nopl 3133065982
+ nopl 0xbabecafe
+
+// CHECK: nopl 305419896
+ nopl 0x12345678
+
+// CHECK: nop
+ nop
+
+// CHECK: lldtw 32493
+ lldtw 0x7eed
+
+// CHECK: lmsww 32493
+ lmsww 0x7eed
+
+// CHECK: ltrw 32493
+ ltrw 0x7eed
+
+// CHECK: sldtw 32493
+ sldtw 0x7eed
+
+// CHECK: smsww 32493
+ smsww 0x7eed
+
+// CHECK: strw 32493
+ strw 0x7eed
+
+// CHECK: verr %bx
+ verr %bx
+
+// CHECK: verr 3735928559(%ebx,%ecx,8)
+ verr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: verr 3133065982
+ verr 0xbabecafe
+
+// CHECK: verr 305419896
+ verr 0x12345678
+
+// CHECK: verw %bx
+ verw %bx
+
+// CHECK: verw 3735928559(%ebx,%ecx,8)
+ verw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: verw 3133065982
+ verw 0xbabecafe
+
+// CHECK: verw 305419896
+ verw 0x12345678
+
+// CHECK: fld %st(2)
+ fld %st(2)
+
+// CHECK: fldl 3735928559(%ebx,%ecx,8)
+ fldl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fldl 3133065982
+ fldl 0xbabecafe
+
+// CHECK: fldl 305419896
+ fldl 0x12345678
+
+// CHECK: fld %st(2)
+ fld %st(2)
+
+// CHECK: fildl 3735928559(%ebx,%ecx,8)
+ fildl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fildl 3133065982
+ fildl 0xbabecafe
+
+// CHECK: fildl 305419896
+ fildl 0x12345678
+
+// CHECK: fildll 3735928559(%ebx,%ecx,8)
+ fildll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fildll 32493
+ fildll 0x7eed
+
+// CHECK: fildll 3133065982
+ fildll 0xbabecafe
+
+// CHECK: fildll 305419896
+ fildll 0x12345678
+
+// CHECK: fldt 3735928559(%ebx,%ecx,8)
+ fldt 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fldt 32493
+ fldt 0x7eed
+
+// CHECK: fldt 3133065982
+ fldt 0xbabecafe
+
+// CHECK: fldt 305419896
+ fldt 0x12345678
+
+// CHECK: fbld 3735928559(%ebx,%ecx,8)
+ fbld 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fbld 32493
+ fbld 0x7eed
+
+// CHECK: fbld 3133065982
+ fbld 0xbabecafe
+
+// CHECK: fbld 305419896
+ fbld 0x12345678
+
+// CHECK: fst %st(2)
+ fst %st(2)
+
+// CHECK: fstl 3735928559(%ebx,%ecx,8)
+ fstl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstl 3133065982
+ fstl 0xbabecafe
+
+// CHECK: fstl 305419896
+ fstl 0x12345678
+
+// CHECK: fst %st(2)
+ fst %st(2)
+
+// CHECK: fistl 3735928559(%ebx,%ecx,8)
+ fistl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistl 3133065982
+ fistl 0xbabecafe
+
+// CHECK: fistl 305419896
+ fistl 0x12345678
+
+// CHECK: fstp %st(2)
+ fstp %st(2)
+
+// CHECK: fstpl 3735928559(%ebx,%ecx,8)
+ fstpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstpl 3133065982
+ fstpl 0xbabecafe
+
+// CHECK: fstpl 305419896
+ fstpl 0x12345678
+
+// CHECK: fstp %st(2)
+ fstp %st(2)
+
+// CHECK: fistpl 3735928559(%ebx,%ecx,8)
+ fistpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistpl 3133065982
+ fistpl 0xbabecafe
+
+// CHECK: fistpl 305419896
+ fistpl 0x12345678
+
+// CHECK: fistpll 3735928559(%ebx,%ecx,8)
+ fistpll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistpll 32493
+ fistpll 0x7eed
+
+// CHECK: fistpll 3133065982
+ fistpll 0xbabecafe
+
+// CHECK: fistpll 305419896
+ fistpll 0x12345678
+
+// CHECK: fstpt 3735928559(%ebx,%ecx,8)
+ fstpt 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstpt 32493
+ fstpt 0x7eed
+
+// CHECK: fstpt 3133065982
+ fstpt 0xbabecafe
+
+// CHECK: fstpt 305419896
+ fstpt 0x12345678
+
+// CHECK: fbstp 3735928559(%ebx,%ecx,8)
+ fbstp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fbstp 32493
+ fbstp 0x7eed
+
+// CHECK: fbstp 3133065982
+ fbstp 0xbabecafe
+
+// CHECK: fbstp 305419896
+ fbstp 0x12345678
+
+// CHECK: fxch %st(2)
+ fxch %st(2)
+
+// CHECK: fcom %st(2)
+ fcom %st(2)
+
+// CHECK: fcoml 3735928559(%ebx,%ecx,8)
+ fcoml 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fcoml 3133065982
+ fcoml 0xbabecafe
+
+// CHECK: fcoml 305419896
+ fcoml 0x12345678
+
+// CHECK: fcom %st(2)
+ fcom %st(2)
+
+// CHECK: ficoml 3735928559(%ebx,%ecx,8)
+ ficoml 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ficoml 3133065982
+ ficoml 0xbabecafe
+
+// CHECK: ficoml 305419896
+ ficoml 0x12345678
+
+// CHECK: fcomp %st(2)
+ fcomp %st(2)
+
+// CHECK: fcompl 3735928559(%ebx,%ecx,8)
+ fcompl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fcompl 3133065982
+ fcompl 0xbabecafe
+
+// CHECK: fcompl 305419896
+ fcompl 0x12345678
+
+// CHECK: fcomp %st(2)
+ fcomp %st(2)
+
+// CHECK: ficompl 3735928559(%ebx,%ecx,8)
+ ficompl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ficompl 3133065982
+ ficompl 0xbabecafe
+
+// CHECK: ficompl 305419896
+ ficompl 0x12345678
+
+// CHECK: fcompp
+ fcompp
+
+// CHECK: fucom %st(2)
+ fucom %st(2)
+
+// CHECK: fucomp %st(2)
+ fucomp %st(2)
+
+// CHECK: fucompp
+ fucompp
+
+// CHECK: ftst
+ ftst
+
+// CHECK: fxam
+ fxam
+
+// CHECK: fld1
+ fld1
+
+// CHECK: fldl2t
+ fldl2t
+
+// CHECK: fldl2e
+ fldl2e
+
+// CHECK: fldpi
+ fldpi
+
+// CHECK: fldlg2
+ fldlg2
+
+// CHECK: fldln2
+ fldln2
+
+// CHECK: fldz
+ fldz
+
+// CHECK: fadd %st(2)
+ fadd %st(2)
+
+// CHECK: faddl 3735928559(%ebx,%ecx,8)
+ faddl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: faddl 3133065982
+ faddl 0xbabecafe
+
+// CHECK: faddl 305419896
+ faddl 0x12345678
+
+// CHECK: fiaddl 3735928559(%ebx,%ecx,8)
+ fiaddl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fiaddl 3133065982
+ fiaddl 0xbabecafe
+
+// CHECK: fiaddl 305419896
+ fiaddl 0x12345678
+
+// CHECK: faddp %st(2)
+ faddp %st(2)
+
+// CHECK: fsub %st(2)
+ fsub %st(2)
+
+// CHECK: fsubl 3735928559(%ebx,%ecx,8)
+ fsubl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fsubl 3133065982
+ fsubl 0xbabecafe
+
+// CHECK: fsubl 305419896
+ fsubl 0x12345678
+
+// CHECK: fisubl 3735928559(%ebx,%ecx,8)
+ fisubl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisubl 3133065982
+ fisubl 0xbabecafe
+
+// CHECK: fisubl 305419896
+ fisubl 0x12345678
+
+// CHECK: fsubp %st(2)
+ fsubp %st(2)
+
+// CHECK: fsubr %st(2)
+ fsubr %st(2)
+
+// CHECK: fsubrl 3735928559(%ebx,%ecx,8)
+ fsubrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fsubrl 3133065982
+ fsubrl 0xbabecafe
+
+// CHECK: fsubrl 305419896
+ fsubrl 0x12345678
+
+// CHECK: fisubrl 3735928559(%ebx,%ecx,8)
+ fisubrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisubrl 3133065982
+ fisubrl 0xbabecafe
+
+// CHECK: fisubrl 305419896
+ fisubrl 0x12345678
+
+// CHECK: fsubrp %st(2)
+ fsubrp %st(2)
+
+// CHECK: fmul %st(2)
+ fmul %st(2)
+
+// CHECK: fmull 3735928559(%ebx,%ecx,8)
+ fmull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fmull 3133065982
+ fmull 0xbabecafe
+
+// CHECK: fmull 305419896
+ fmull 0x12345678
+
+// CHECK: fimull 3735928559(%ebx,%ecx,8)
+ fimull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fimull 3133065982
+ fimull 0xbabecafe
+
+// CHECK: fimull 305419896
+ fimull 0x12345678
+
+// CHECK: fmulp %st(2)
+ fmulp %st(2)
+
+// CHECK: fdiv %st(2)
+ fdiv %st(2)
+
+// CHECK: fdivl 3735928559(%ebx,%ecx,8)
+ fdivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fdivl 3133065982
+ fdivl 0xbabecafe
+
+// CHECK: fdivl 305419896
+ fdivl 0x12345678
+
+// CHECK: fidivl 3735928559(%ebx,%ecx,8)
+ fidivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fidivl 3133065982
+ fidivl 0xbabecafe
+
+// CHECK: fidivl 305419896
+ fidivl 0x12345678
+
+// CHECK: fdivp %st(2)
+ fdivp %st(2)
+
+// CHECK: fdivr %st(2)
+ fdivr %st(2)
+
+// CHECK: fdivrl 3735928559(%ebx,%ecx,8)
+ fdivrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fdivrl 3133065982
+ fdivrl 0xbabecafe
+
+// CHECK: fdivrl 305419896
+ fdivrl 0x12345678
+
+// CHECK: fidivrl 3735928559(%ebx,%ecx,8)
+ fidivrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fidivrl 3133065982
+ fidivrl 0xbabecafe
+
+// CHECK: fidivrl 305419896
+ fidivrl 0x12345678
+
+// CHECK: fdivrp %st(2)
+ fdivrp %st(2)
+
+// CHECK: f2xm1
+ f2xm1
+
+// CHECK: fyl2x
+ fyl2x
+
+// CHECK: fptan
+ fptan
+
+// CHECK: fpatan
+ fpatan
+
+// CHECK: fxtract
+ fxtract
+
+// CHECK: fprem1
+ fprem1
+
+// CHECK: fdecstp
+ fdecstp
+
+// CHECK: fincstp
+ fincstp
+
+// CHECK: fprem
+ fprem
+
+// CHECK: fyl2xp1
+ fyl2xp1
+
+// CHECK: fsqrt
+ fsqrt
+
+// CHECK: fsincos
+ fsincos
+
+// CHECK: frndint
+ frndint
+
+// CHECK: fscale
+ fscale
+
+// CHECK: fsin
+ fsin
+
+// CHECK: fcos
+ fcos
+
+// CHECK: fchs
+ fchs
+
+// CHECK: fabs
+ fabs
+
+// CHECK: fninit
+ fninit
+
+// CHECK: fldcw 3735928559(%ebx,%ecx,8)
+ fldcw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fldcw 3133065982
+ fldcw 0xbabecafe
+
+// CHECK: fldcw 305419896
+ fldcw 0x12345678
+
+// CHECK: fnstcw 3735928559(%ebx,%ecx,8)
+ fnstcw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fnstcw 3133065982
+ fnstcw 0xbabecafe
+
+// CHECK: fnstcw 305419896
+ fnstcw 0x12345678
+
+// CHECK: fnstsw 3735928559(%ebx,%ecx,8)
+ fnstsw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fnstsw 3133065982
+ fnstsw 0xbabecafe
+
+// CHECK: fnstsw 305419896
+ fnstsw 0x12345678
+
+// CHECK: fnclex
+ fnclex
+
+// CHECK: fnstenv 32493
+ fnstenv 0x7eed
+
+// CHECK: fldenv 32493
+ fldenv 0x7eed
+
+// CHECK: fnsave 32493
+ fnsave 0x7eed
+
+// CHECK: frstor 32493
+ frstor 0x7eed
+
+// CHECK: ffree %st(2)
+ ffree %st(2)
+
+// CHECK: fnop
+ fnop
+
+// CHECK: invd
+ invd
+
+// CHECK: wbinvd
+ wbinvd
+
+// CHECK: cpuid
+ cpuid
+
+// CHECK: wrmsr
+ wrmsr
+
+// CHECK: rdtsc
+ rdtsc
+
+// CHECK: rdmsr
+ rdmsr
+
+// CHECK: cmpxchg8b 3735928559(%ebx,%ecx,8)
+ cmpxchg8b 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpxchg8b 32493
+ cmpxchg8b 0x7eed
+
+// CHECK: cmpxchg8b 3133065982
+ cmpxchg8b 0xbabecafe
+
+// CHECK: cmpxchg8b 305419896
+ cmpxchg8b 0x12345678
+
+// CHECK: sysenter
+ sysenter
+
+// CHECK: sysexit
+ sysexit
+
+// CHECK: fxsave 3735928559(%ebx,%ecx,8)
+ fxsave 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fxsave 32493
+ fxsave 0x7eed
+
+// CHECK: fxsave 3133065982
+ fxsave 0xbabecafe
+
+// CHECK: fxsave 305419896
+ fxsave 0x12345678
+
+// CHECK: fxrstor 3735928559(%ebx,%ecx,8)
+ fxrstor 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fxrstor 32493
+ fxrstor 0x7eed
+
+// CHECK: fxrstor 3133065982
+ fxrstor 0xbabecafe
+
+// CHECK: fxrstor 305419896
+ fxrstor 0x12345678
+
+// CHECK: rdpmc
+ rdpmc
+
+// CHECK: ud2
+ ud2
+
+// CHECK: fcmovb %st(2), %st(0)
+ fcmovb %st(2),%st
+
+// CHECK: fcmove %st(2), %st(0)
+ fcmove %st(2),%st
+
+// CHECK: fcmovbe %st(2), %st(0)
+ fcmovbe %st(2),%st
+
+// CHECK: fcmovu %st(2), %st(0)
+ fcmovu %st(2),%st
+
+// CHECK: fcmovnb %st(2), %st(0)
+ fcmovnb %st(2),%st
+
+// CHECK: fcmovne %st(2), %st(0)
+ fcmovne %st(2),%st
+
+// CHECK: fcmovnbe %st(2), %st(0)
+ fcmovnbe %st(2),%st
+
+// CHECK: fcmovnu %st(2), %st(0)
+ fcmovnu %st(2),%st
+
+// CHECK: fcomi %st(2), %st(0)
+ fcomi %st(2),%st
+
+// CHECK: fucomi %st(2), %st(0)
+ fucomi %st(2),%st
+
+// CHECK: fcomip %st(2), %st(0)
+ fcomip %st(2),%st
+
+// CHECK: fucomip %st(2), %st(0)
+ fucomip %st(2),%st
+
+// CHECK: movnti %ecx, 3735928559(%ebx,%ecx,8)
+ movnti %ecx,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movnti %ecx, 69
+ movnti %ecx,0x45
+
+// CHECK: movnti %ecx, 32493
+ movnti %ecx,0x7eed
+
+// CHECK: movnti %ecx, 3133065982
+ movnti %ecx,0xbabecafe
+
+// CHECK: movnti %ecx, 305419896
+ movnti %ecx,0x12345678
+
+// CHECK: clflush 3735928559(%ebx,%ecx,8)
+ clflush 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: clflush 32493
+ clflush 0x7eed
+
+// CHECK: clflush 3133065982
+ clflush 0xbabecafe
+
+// CHECK: clflush 305419896
+ clflush 0x12345678
+
+// CHECK: lfence
+ lfence
+
+// CHECK: mfence
+ mfence
+
+// CHECK: emms
+ emms
+
+// CHECK: movd %ecx, %mm3
+ movd %ecx,%mm3
+
+// CHECK: movd 3735928559(%ebx,%ecx,8), %mm3
+ movd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: movd 69, %mm3
+ movd 0x45,%mm3
+
+// CHECK: movd 32493, %mm3
+ movd 0x7eed,%mm3
+
+// CHECK: movd 3133065982, %mm3
+ movd 0xbabecafe,%mm3
+
+// CHECK: movd 305419896, %mm3
+ movd 0x12345678,%mm3
+
+// CHECK: movd %mm3, %ecx
+ movd %mm3,%ecx
+
+// CHECK: movd %mm3, 3735928559(%ebx,%ecx,8)
+ movd %mm3,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movd %mm3, 69
+ movd %mm3,0x45
+
+// CHECK: movd %mm3, 32493
+ movd %mm3,0x7eed
+
+// CHECK: movd %mm3, 3133065982
+ movd %mm3,0xbabecafe
+
+// CHECK: movd %mm3, 305419896
+ movd %mm3,0x12345678
+
+// CHECK: movd %ecx, %xmm5
+ movd %ecx,%xmm5
+
+// CHECK: movd 3735928559(%ebx,%ecx,8), %xmm5
+ movd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movd 69, %xmm5
+ movd 0x45,%xmm5
+
+// CHECK: movd 32493, %xmm5
+ movd 0x7eed,%xmm5
+
+// CHECK: movd 3133065982, %xmm5
+ movd 0xbabecafe,%xmm5
+
+// CHECK: movd 305419896, %xmm5
+ movd 0x12345678,%xmm5
+
+// CHECK: movd %xmm5, %ecx
+ movd %xmm5,%ecx
+
+// CHECK: movd %xmm5, 3735928559(%ebx,%ecx,8)
+ movd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movd %xmm5, 69
+ movd %xmm5,0x45
+
+// CHECK: movd %xmm5, 32493
+ movd %xmm5,0x7eed
+
+// CHECK: movd %xmm5, 3133065982
+ movd %xmm5,0xbabecafe
+
+// CHECK: movd %xmm5, 305419896
+ movd %xmm5,0x12345678
+
+// CHECK: movq 3735928559(%ebx,%ecx,8), %mm3
+ movq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: movq 69, %mm3
+ movq 0x45,%mm3
+
+// CHECK: movq 32493, %mm3
+ movq 0x7eed,%mm3
+
+// CHECK: movq 3133065982, %mm3
+ movq 0xbabecafe,%mm3
+
+// CHECK: movq 305419896, %mm3
+ movq 0x12345678,%mm3
+
+// CHECK: movq %mm3, %mm3
+ movq %mm3,%mm3
+
+// CHECK: movq %mm3, 3735928559(%ebx,%ecx,8)
+ movq %mm3,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movq %mm3, 69
+ movq %mm3,0x45
+
+// CHECK: movq %mm3, 32493
+ movq %mm3,0x7eed
+
+// CHECK: movq %mm3, 3133065982
+ movq %mm3,0xbabecafe
+
+// CHECK: movq %mm3, 305419896
+ movq %mm3,0x12345678
+
+// CHECK: movq %mm3, %mm3
+ movq %mm3,%mm3
+
+// CHECK: movq 3735928559(%ebx,%ecx,8), %xmm5
+ movq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movq 69, %xmm5
+ movq 0x45,%xmm5
+
+// CHECK: movq 32493, %xmm5
+ movq 0x7eed,%xmm5
+
+// CHECK: movq 3133065982, %xmm5
+ movq 0xbabecafe,%xmm5
+
+// CHECK: movq 305419896, %xmm5
+ movq 0x12345678,%xmm5
+
+// CHECK: movq %xmm5, %xmm5
+ movq %xmm5,%xmm5
+
+// CHECK: movq %xmm5, 3735928559(%ebx,%ecx,8)
+ movq %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movq %xmm5, 69
+ movq %xmm5,0x45
+
+// CHECK: movq %xmm5, 32493
+ movq %xmm5,0x7eed
+
+// CHECK: movq %xmm5, 3133065982
+ movq %xmm5,0xbabecafe
+
+// CHECK: movq %xmm5, 305419896
+ movq %xmm5,0x12345678
+
+// CHECK: movq %xmm5, %xmm5
+ movq %xmm5,%xmm5
+
+// CHECK: packssdw 3735928559(%ebx,%ecx,8), %mm3
+ packssdw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: packssdw 69, %mm3
+ packssdw 0x45,%mm3
+
+// CHECK: packssdw 32493, %mm3
+ packssdw 0x7eed,%mm3
+
+// CHECK: packssdw 3133065982, %mm3
+ packssdw 0xbabecafe,%mm3
+
+// CHECK: packssdw 305419896, %mm3
+ packssdw 0x12345678,%mm3
+
+// CHECK: packssdw %mm3, %mm3
+ packssdw %mm3,%mm3
+
+// CHECK: packssdw 3735928559(%ebx,%ecx,8), %xmm5
+ packssdw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packssdw 69, %xmm5
+ packssdw 0x45,%xmm5
+
+// CHECK: packssdw 32493, %xmm5
+ packssdw 0x7eed,%xmm5
+
+// CHECK: packssdw 3133065982, %xmm5
+ packssdw 0xbabecafe,%xmm5
+
+// CHECK: packssdw 305419896, %xmm5
+ packssdw 0x12345678,%xmm5
+
+// CHECK: packssdw %xmm5, %xmm5
+ packssdw %xmm5,%xmm5
+
+// CHECK: packsswb 3735928559(%ebx,%ecx,8), %mm3
+ packsswb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: packsswb 69, %mm3
+ packsswb 0x45,%mm3
+
+// CHECK: packsswb 32493, %mm3
+ packsswb 0x7eed,%mm3
+
+// CHECK: packsswb 3133065982, %mm3
+ packsswb 0xbabecafe,%mm3
+
+// CHECK: packsswb 305419896, %mm3
+ packsswb 0x12345678,%mm3
+
+// CHECK: packsswb %mm3, %mm3
+ packsswb %mm3,%mm3
+
+// CHECK: packsswb 3735928559(%ebx,%ecx,8), %xmm5
+ packsswb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packsswb 69, %xmm5
+ packsswb 0x45,%xmm5
+
+// CHECK: packsswb 32493, %xmm5
+ packsswb 0x7eed,%xmm5
+
+// CHECK: packsswb 3133065982, %xmm5
+ packsswb 0xbabecafe,%xmm5
+
+// CHECK: packsswb 305419896, %xmm5
+ packsswb 0x12345678,%xmm5
+
+// CHECK: packsswb %xmm5, %xmm5
+ packsswb %xmm5,%xmm5
+
+// CHECK: packuswb 3735928559(%ebx,%ecx,8), %mm3
+ packuswb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: packuswb 69, %mm3
+ packuswb 0x45,%mm3
+
+// CHECK: packuswb 32493, %mm3
+ packuswb 0x7eed,%mm3
+
+// CHECK: packuswb 3133065982, %mm3
+ packuswb 0xbabecafe,%mm3
+
+// CHECK: packuswb 305419896, %mm3
+ packuswb 0x12345678,%mm3
+
+// CHECK: packuswb %mm3, %mm3
+ packuswb %mm3,%mm3
+
+// CHECK: packuswb 3735928559(%ebx,%ecx,8), %xmm5
+ packuswb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packuswb 69, %xmm5
+ packuswb 0x45,%xmm5
+
+// CHECK: packuswb 32493, %xmm5
+ packuswb 0x7eed,%xmm5
+
+// CHECK: packuswb 3133065982, %xmm5
+ packuswb 0xbabecafe,%xmm5
+
+// CHECK: packuswb 305419896, %xmm5
+ packuswb 0x12345678,%xmm5
+
+// CHECK: packuswb %xmm5, %xmm5
+ packuswb %xmm5,%xmm5
+
+// CHECK: paddb 3735928559(%ebx,%ecx,8), %mm3
+ paddb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddb 69, %mm3
+ paddb 0x45,%mm3
+
+// CHECK: paddb 32493, %mm3
+ paddb 0x7eed,%mm3
+
+// CHECK: paddb 3133065982, %mm3
+ paddb 0xbabecafe,%mm3
+
+// CHECK: paddb 305419896, %mm3
+ paddb 0x12345678,%mm3
+
+// CHECK: paddb %mm3, %mm3
+ paddb %mm3,%mm3
+
+// CHECK: paddb 3735928559(%ebx,%ecx,8), %xmm5
+ paddb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddb 69, %xmm5
+ paddb 0x45,%xmm5
+
+// CHECK: paddb 32493, %xmm5
+ paddb 0x7eed,%xmm5
+
+// CHECK: paddb 3133065982, %xmm5
+ paddb 0xbabecafe,%xmm5
+
+// CHECK: paddb 305419896, %xmm5
+ paddb 0x12345678,%xmm5
+
+// CHECK: paddb %xmm5, %xmm5
+ paddb %xmm5,%xmm5
+
+// CHECK: paddw 3735928559(%ebx,%ecx,8), %mm3
+ paddw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddw 69, %mm3
+ paddw 0x45,%mm3
+
+// CHECK: paddw 32493, %mm3
+ paddw 0x7eed,%mm3
+
+// CHECK: paddw 3133065982, %mm3
+ paddw 0xbabecafe,%mm3
+
+// CHECK: paddw 305419896, %mm3
+ paddw 0x12345678,%mm3
+
+// CHECK: paddw %mm3, %mm3
+ paddw %mm3,%mm3
+
+// CHECK: paddw 3735928559(%ebx,%ecx,8), %xmm5
+ paddw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddw 69, %xmm5
+ paddw 0x45,%xmm5
+
+// CHECK: paddw 32493, %xmm5
+ paddw 0x7eed,%xmm5
+
+// CHECK: paddw 3133065982, %xmm5
+ paddw 0xbabecafe,%xmm5
+
+// CHECK: paddw 305419896, %xmm5
+ paddw 0x12345678,%xmm5
+
+// CHECK: paddw %xmm5, %xmm5
+ paddw %xmm5,%xmm5
+
+// CHECK: paddd 3735928559(%ebx,%ecx,8), %mm3
+ paddd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddd 69, %mm3
+ paddd 0x45,%mm3
+
+// CHECK: paddd 32493, %mm3
+ paddd 0x7eed,%mm3
+
+// CHECK: paddd 3133065982, %mm3
+ paddd 0xbabecafe,%mm3
+
+// CHECK: paddd 305419896, %mm3
+ paddd 0x12345678,%mm3
+
+// CHECK: paddd %mm3, %mm3
+ paddd %mm3,%mm3
+
+// CHECK: paddd 3735928559(%ebx,%ecx,8), %xmm5
+ paddd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddd 69, %xmm5
+ paddd 0x45,%xmm5
+
+// CHECK: paddd 32493, %xmm5
+ paddd 0x7eed,%xmm5
+
+// CHECK: paddd 3133065982, %xmm5
+ paddd 0xbabecafe,%xmm5
+
+// CHECK: paddd 305419896, %xmm5
+ paddd 0x12345678,%xmm5
+
+// CHECK: paddd %xmm5, %xmm5
+ paddd %xmm5,%xmm5
+
+// CHECK: paddq 3735928559(%ebx,%ecx,8), %mm3
+ paddq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddq 69, %mm3
+ paddq 0x45,%mm3
+
+// CHECK: paddq 32493, %mm3
+ paddq 0x7eed,%mm3
+
+// CHECK: paddq 3133065982, %mm3
+ paddq 0xbabecafe,%mm3
+
+// CHECK: paddq 305419896, %mm3
+ paddq 0x12345678,%mm3
+
+// CHECK: paddq %mm3, %mm3
+ paddq %mm3,%mm3
+
+// CHECK: paddq 3735928559(%ebx,%ecx,8), %xmm5
+ paddq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddq 69, %xmm5
+ paddq 0x45,%xmm5
+
+// CHECK: paddq 32493, %xmm5
+ paddq 0x7eed,%xmm5
+
+// CHECK: paddq 3133065982, %xmm5
+ paddq 0xbabecafe,%xmm5
+
+// CHECK: paddq 305419896, %xmm5
+ paddq 0x12345678,%xmm5
+
+// CHECK: paddq %xmm5, %xmm5
+ paddq %xmm5,%xmm5
+
+// CHECK: paddsb 3735928559(%ebx,%ecx,8), %mm3
+ paddsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddsb 69, %mm3
+ paddsb 0x45,%mm3
+
+// CHECK: paddsb 32493, %mm3
+ paddsb 0x7eed,%mm3
+
+// CHECK: paddsb 3133065982, %mm3
+ paddsb 0xbabecafe,%mm3
+
+// CHECK: paddsb 305419896, %mm3
+ paddsb 0x12345678,%mm3
+
+// CHECK: paddsb %mm3, %mm3
+ paddsb %mm3,%mm3
+
+// CHECK: paddsb 3735928559(%ebx,%ecx,8), %xmm5
+ paddsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddsb 69, %xmm5
+ paddsb 0x45,%xmm5
+
+// CHECK: paddsb 32493, %xmm5
+ paddsb 0x7eed,%xmm5
+
+// CHECK: paddsb 3133065982, %xmm5
+ paddsb 0xbabecafe,%xmm5
+
+// CHECK: paddsb 305419896, %xmm5
+ paddsb 0x12345678,%xmm5
+
+// CHECK: paddsb %xmm5, %xmm5
+ paddsb %xmm5,%xmm5
+
+// CHECK: paddsw 3735928559(%ebx,%ecx,8), %mm3
+ paddsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddsw 69, %mm3
+ paddsw 0x45,%mm3
+
+// CHECK: paddsw 32493, %mm3
+ paddsw 0x7eed,%mm3
+
+// CHECK: paddsw 3133065982, %mm3
+ paddsw 0xbabecafe,%mm3
+
+// CHECK: paddsw 305419896, %mm3
+ paddsw 0x12345678,%mm3
+
+// CHECK: paddsw %mm3, %mm3
+ paddsw %mm3,%mm3
+
+// CHECK: paddsw 3735928559(%ebx,%ecx,8), %xmm5
+ paddsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddsw 69, %xmm5
+ paddsw 0x45,%xmm5
+
+// CHECK: paddsw 32493, %xmm5
+ paddsw 0x7eed,%xmm5
+
+// CHECK: paddsw 3133065982, %xmm5
+ paddsw 0xbabecafe,%xmm5
+
+// CHECK: paddsw 305419896, %xmm5
+ paddsw 0x12345678,%xmm5
+
+// CHECK: paddsw %xmm5, %xmm5
+ paddsw %xmm5,%xmm5
+
+// CHECK: paddusb 3735928559(%ebx,%ecx,8), %mm3
+ paddusb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddusb 69, %mm3
+ paddusb 0x45,%mm3
+
+// CHECK: paddusb 32493, %mm3
+ paddusb 0x7eed,%mm3
+
+// CHECK: paddusb 3133065982, %mm3
+ paddusb 0xbabecafe,%mm3
+
+// CHECK: paddusb 305419896, %mm3
+ paddusb 0x12345678,%mm3
+
+// CHECK: paddusb %mm3, %mm3
+ paddusb %mm3,%mm3
+
+// CHECK: paddusb 3735928559(%ebx,%ecx,8), %xmm5
+ paddusb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddusb 69, %xmm5
+ paddusb 0x45,%xmm5
+
+// CHECK: paddusb 32493, %xmm5
+ paddusb 0x7eed,%xmm5
+
+// CHECK: paddusb 3133065982, %xmm5
+ paddusb 0xbabecafe,%xmm5
+
+// CHECK: paddusb 305419896, %xmm5
+ paddusb 0x12345678,%xmm5
+
+// CHECK: paddusb %xmm5, %xmm5
+ paddusb %xmm5,%xmm5
+
+// CHECK: paddusw 3735928559(%ebx,%ecx,8), %mm3
+ paddusw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddusw 69, %mm3
+ paddusw 0x45,%mm3
+
+// CHECK: paddusw 32493, %mm3
+ paddusw 0x7eed,%mm3
+
+// CHECK: paddusw 3133065982, %mm3
+ paddusw 0xbabecafe,%mm3
+
+// CHECK: paddusw 305419896, %mm3
+ paddusw 0x12345678,%mm3
+
+// CHECK: paddusw %mm3, %mm3
+ paddusw %mm3,%mm3
+
+// CHECK: paddusw 3735928559(%ebx,%ecx,8), %xmm5
+ paddusw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddusw 69, %xmm5
+ paddusw 0x45,%xmm5
+
+// CHECK: paddusw 32493, %xmm5
+ paddusw 0x7eed,%xmm5
+
+// CHECK: paddusw 3133065982, %xmm5
+ paddusw 0xbabecafe,%xmm5
+
+// CHECK: paddusw 305419896, %xmm5
+ paddusw 0x12345678,%xmm5
+
+// CHECK: paddusw %xmm5, %xmm5
+ paddusw %xmm5,%xmm5
+
+// CHECK: pand 3735928559(%ebx,%ecx,8), %mm3
+ pand 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pand 69, %mm3
+ pand 0x45,%mm3
+
+// CHECK: pand 32493, %mm3
+ pand 0x7eed,%mm3
+
+// CHECK: pand 3133065982, %mm3
+ pand 0xbabecafe,%mm3
+
+// CHECK: pand 305419896, %mm3
+ pand 0x12345678,%mm3
+
+// CHECK: pand %mm3, %mm3
+ pand %mm3,%mm3
+
+// CHECK: pand 3735928559(%ebx,%ecx,8), %xmm5
+ pand 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pand 69, %xmm5
+ pand 0x45,%xmm5
+
+// CHECK: pand 32493, %xmm5
+ pand 0x7eed,%xmm5
+
+// CHECK: pand 3133065982, %xmm5
+ pand 0xbabecafe,%xmm5
+
+// CHECK: pand 305419896, %xmm5
+ pand 0x12345678,%xmm5
+
+// CHECK: pand %xmm5, %xmm5
+ pand %xmm5,%xmm5
+
+// CHECK: pandn 3735928559(%ebx,%ecx,8), %mm3
+ pandn 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pandn 69, %mm3
+ pandn 0x45,%mm3
+
+// CHECK: pandn 32493, %mm3
+ pandn 0x7eed,%mm3
+
+// CHECK: pandn 3133065982, %mm3
+ pandn 0xbabecafe,%mm3
+
+// CHECK: pandn 305419896, %mm3
+ pandn 0x12345678,%mm3
+
+// CHECK: pandn %mm3, %mm3
+ pandn %mm3,%mm3
+
+// CHECK: pandn 3735928559(%ebx,%ecx,8), %xmm5
+ pandn 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pandn 69, %xmm5
+ pandn 0x45,%xmm5
+
+// CHECK: pandn 32493, %xmm5
+ pandn 0x7eed,%xmm5
+
+// CHECK: pandn 3133065982, %xmm5
+ pandn 0xbabecafe,%xmm5
+
+// CHECK: pandn 305419896, %xmm5
+ pandn 0x12345678,%xmm5
+
+// CHECK: pandn %xmm5, %xmm5
+ pandn %xmm5,%xmm5
+
+// CHECK: pcmpeqb 3735928559(%ebx,%ecx,8), %mm3
+ pcmpeqb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpeqb 69, %mm3
+ pcmpeqb 0x45,%mm3
+
+// CHECK: pcmpeqb 32493, %mm3
+ pcmpeqb 0x7eed,%mm3
+
+// CHECK: pcmpeqb 3133065982, %mm3
+ pcmpeqb 0xbabecafe,%mm3
+
+// CHECK: pcmpeqb 305419896, %mm3
+ pcmpeqb 0x12345678,%mm3
+
+// CHECK: pcmpeqb %mm3, %mm3
+ pcmpeqb %mm3,%mm3
+
+// CHECK: pcmpeqb 3735928559(%ebx,%ecx,8), %xmm5
+ pcmpeqb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqb 69, %xmm5
+ pcmpeqb 0x45,%xmm5
+
+// CHECK: pcmpeqb 32493, %xmm5
+ pcmpeqb 0x7eed,%xmm5
+
+// CHECK: pcmpeqb 3133065982, %xmm5
+ pcmpeqb 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqb 305419896, %xmm5
+ pcmpeqb 0x12345678,%xmm5
+
+// CHECK: pcmpeqb %xmm5, %xmm5
+ pcmpeqb %xmm5,%xmm5
+
+// CHECK: pcmpeqw 3735928559(%ebx,%ecx,8), %mm3
+ pcmpeqw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpeqw 69, %mm3
+ pcmpeqw 0x45,%mm3
+
+// CHECK: pcmpeqw 32493, %mm3
+ pcmpeqw 0x7eed,%mm3
+
+// CHECK: pcmpeqw 3133065982, %mm3
+ pcmpeqw 0xbabecafe,%mm3
+
+// CHECK: pcmpeqw 305419896, %mm3
+ pcmpeqw 0x12345678,%mm3
+
+// CHECK: pcmpeqw %mm3, %mm3
+ pcmpeqw %mm3,%mm3
+
+// CHECK: pcmpeqw 3735928559(%ebx,%ecx,8), %xmm5
+ pcmpeqw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqw 69, %xmm5
+ pcmpeqw 0x45,%xmm5
+
+// CHECK: pcmpeqw 32493, %xmm5
+ pcmpeqw 0x7eed,%xmm5
+
+// CHECK: pcmpeqw 3133065982, %xmm5
+ pcmpeqw 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqw 305419896, %xmm5
+ pcmpeqw 0x12345678,%xmm5
+
+// CHECK: pcmpeqw %xmm5, %xmm5
+ pcmpeqw %xmm5,%xmm5
+
+// CHECK: pcmpeqd 3735928559(%ebx,%ecx,8), %mm3
+ pcmpeqd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpeqd 69, %mm3
+ pcmpeqd 0x45,%mm3
+
+// CHECK: pcmpeqd 32493, %mm3
+ pcmpeqd 0x7eed,%mm3
+
+// CHECK: pcmpeqd 3133065982, %mm3
+ pcmpeqd 0xbabecafe,%mm3
+
+// CHECK: pcmpeqd 305419896, %mm3
+ pcmpeqd 0x12345678,%mm3
+
+// CHECK: pcmpeqd %mm3, %mm3
+ pcmpeqd %mm3,%mm3
+
+// CHECK: pcmpeqd 3735928559(%ebx,%ecx,8), %xmm5
+ pcmpeqd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqd 69, %xmm5
+ pcmpeqd 0x45,%xmm5
+
+// CHECK: pcmpeqd 32493, %xmm5
+ pcmpeqd 0x7eed,%xmm5
+
+// CHECK: pcmpeqd 3133065982, %xmm5
+ pcmpeqd 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqd 305419896, %xmm5
+ pcmpeqd 0x12345678,%xmm5
+
+// CHECK: pcmpeqd %xmm5, %xmm5
+ pcmpeqd %xmm5,%xmm5
+
+// CHECK: pcmpgtb 3735928559(%ebx,%ecx,8), %mm3
+ pcmpgtb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpgtb 69, %mm3
+ pcmpgtb 0x45,%mm3
+
+// CHECK: pcmpgtb 32493, %mm3
+ pcmpgtb 0x7eed,%mm3
+
+// CHECK: pcmpgtb 3133065982, %mm3
+ pcmpgtb 0xbabecafe,%mm3
+
+// CHECK: pcmpgtb 305419896, %mm3
+ pcmpgtb 0x12345678,%mm3
+
+// CHECK: pcmpgtb %mm3, %mm3
+ pcmpgtb %mm3,%mm3
+
+// CHECK: pcmpgtb 3735928559(%ebx,%ecx,8), %xmm5
+ pcmpgtb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtb 69, %xmm5
+ pcmpgtb 0x45,%xmm5
+
+// CHECK: pcmpgtb 32493, %xmm5
+ pcmpgtb 0x7eed,%xmm5
+
+// CHECK: pcmpgtb 3133065982, %xmm5
+ pcmpgtb 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtb 305419896, %xmm5
+ pcmpgtb 0x12345678,%xmm5
+
+// CHECK: pcmpgtb %xmm5, %xmm5
+ pcmpgtb %xmm5,%xmm5
+
+// CHECK: pcmpgtw 3735928559(%ebx,%ecx,8), %mm3
+ pcmpgtw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpgtw 69, %mm3
+ pcmpgtw 0x45,%mm3
+
+// CHECK: pcmpgtw 32493, %mm3
+ pcmpgtw 0x7eed,%mm3
+
+// CHECK: pcmpgtw 3133065982, %mm3
+ pcmpgtw 0xbabecafe,%mm3
+
+// CHECK: pcmpgtw 305419896, %mm3
+ pcmpgtw 0x12345678,%mm3
+
+// CHECK: pcmpgtw %mm3, %mm3
+ pcmpgtw %mm3,%mm3
+
+// CHECK: pcmpgtw 3735928559(%ebx,%ecx,8), %xmm5
+ pcmpgtw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtw 69, %xmm5
+ pcmpgtw 0x45,%xmm5
+
+// CHECK: pcmpgtw 32493, %xmm5
+ pcmpgtw 0x7eed,%xmm5
+
+// CHECK: pcmpgtw 3133065982, %xmm5
+ pcmpgtw 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtw 305419896, %xmm5
+ pcmpgtw 0x12345678,%xmm5
+
+// CHECK: pcmpgtw %xmm5, %xmm5
+ pcmpgtw %xmm5,%xmm5
+
+// CHECK: pcmpgtd 3735928559(%ebx,%ecx,8), %mm3
+ pcmpgtd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpgtd 69, %mm3
+ pcmpgtd 0x45,%mm3
+
+// CHECK: pcmpgtd 32493, %mm3
+ pcmpgtd 0x7eed,%mm3
+
+// CHECK: pcmpgtd 3133065982, %mm3
+ pcmpgtd 0xbabecafe,%mm3
+
+// CHECK: pcmpgtd 305419896, %mm3
+ pcmpgtd 0x12345678,%mm3
+
+// CHECK: pcmpgtd %mm3, %mm3
+ pcmpgtd %mm3,%mm3
+
+// CHECK: pcmpgtd 3735928559(%ebx,%ecx,8), %xmm5
+ pcmpgtd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtd 69, %xmm5
+ pcmpgtd 0x45,%xmm5
+
+// CHECK: pcmpgtd 32493, %xmm5
+ pcmpgtd 0x7eed,%xmm5
+
+// CHECK: pcmpgtd 3133065982, %xmm5
+ pcmpgtd 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtd 305419896, %xmm5
+ pcmpgtd 0x12345678,%xmm5
+
+// CHECK: pcmpgtd %xmm5, %xmm5
+ pcmpgtd %xmm5,%xmm5
+
+// CHECK: pmaddwd 3735928559(%ebx,%ecx,8), %mm3
+ pmaddwd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaddwd 69, %mm3
+ pmaddwd 0x45,%mm3
+
+// CHECK: pmaddwd 32493, %mm3
+ pmaddwd 0x7eed,%mm3
+
+// CHECK: pmaddwd 3133065982, %mm3
+ pmaddwd 0xbabecafe,%mm3
+
+// CHECK: pmaddwd 305419896, %mm3
+ pmaddwd 0x12345678,%mm3
+
+// CHECK: pmaddwd %mm3, %mm3
+ pmaddwd %mm3,%mm3
+
+// CHECK: pmaddwd 3735928559(%ebx,%ecx,8), %xmm5
+ pmaddwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaddwd 69, %xmm5
+ pmaddwd 0x45,%xmm5
+
+// CHECK: pmaddwd 32493, %xmm5
+ pmaddwd 0x7eed,%xmm5
+
+// CHECK: pmaddwd 3133065982, %xmm5
+ pmaddwd 0xbabecafe,%xmm5
+
+// CHECK: pmaddwd 305419896, %xmm5
+ pmaddwd 0x12345678,%xmm5
+
+// CHECK: pmaddwd %xmm5, %xmm5
+ pmaddwd %xmm5,%xmm5
+
+// CHECK: pmulhw 3735928559(%ebx,%ecx,8), %mm3
+ pmulhw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmulhw 69, %mm3
+ pmulhw 0x45,%mm3
+
+// CHECK: pmulhw 32493, %mm3
+ pmulhw 0x7eed,%mm3
+
+// CHECK: pmulhw 3133065982, %mm3
+ pmulhw 0xbabecafe,%mm3
+
+// CHECK: pmulhw 305419896, %mm3
+ pmulhw 0x12345678,%mm3
+
+// CHECK: pmulhw %mm3, %mm3
+ pmulhw %mm3,%mm3
+
+// CHECK: pmulhw 3735928559(%ebx,%ecx,8), %xmm5
+ pmulhw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulhw 69, %xmm5
+ pmulhw 0x45,%xmm5
+
+// CHECK: pmulhw 32493, %xmm5
+ pmulhw 0x7eed,%xmm5
+
+// CHECK: pmulhw 3133065982, %xmm5
+ pmulhw 0xbabecafe,%xmm5
+
+// CHECK: pmulhw 305419896, %xmm5
+ pmulhw 0x12345678,%xmm5
+
+// CHECK: pmulhw %xmm5, %xmm5
+ pmulhw %xmm5,%xmm5
+
+// CHECK: pmullw 3735928559(%ebx,%ecx,8), %mm3
+ pmullw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmullw 69, %mm3
+ pmullw 0x45,%mm3
+
+// CHECK: pmullw 32493, %mm3
+ pmullw 0x7eed,%mm3
+
+// CHECK: pmullw 3133065982, %mm3
+ pmullw 0xbabecafe,%mm3
+
+// CHECK: pmullw 305419896, %mm3
+ pmullw 0x12345678,%mm3
+
+// CHECK: pmullw %mm3, %mm3
+ pmullw %mm3,%mm3
+
+// CHECK: pmullw 3735928559(%ebx,%ecx,8), %xmm5
+ pmullw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmullw 69, %xmm5
+ pmullw 0x45,%xmm5
+
+// CHECK: pmullw 32493, %xmm5
+ pmullw 0x7eed,%xmm5
+
+// CHECK: pmullw 3133065982, %xmm5
+ pmullw 0xbabecafe,%xmm5
+
+// CHECK: pmullw 305419896, %xmm5
+ pmullw 0x12345678,%xmm5
+
+// CHECK: pmullw %xmm5, %xmm5
+ pmullw %xmm5,%xmm5
+
+// CHECK: por 3735928559(%ebx,%ecx,8), %mm3
+ por 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: por 69, %mm3
+ por 0x45,%mm3
+
+// CHECK: por 32493, %mm3
+ por 0x7eed,%mm3
+
+// CHECK: por 3133065982, %mm3
+ por 0xbabecafe,%mm3
+
+// CHECK: por 305419896, %mm3
+ por 0x12345678,%mm3
+
+// CHECK: por %mm3, %mm3
+ por %mm3,%mm3
+
+// CHECK: por 3735928559(%ebx,%ecx,8), %xmm5
+ por 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: por 69, %xmm5
+ por 0x45,%xmm5
+
+// CHECK: por 32493, %xmm5
+ por 0x7eed,%xmm5
+
+// CHECK: por 3133065982, %xmm5
+ por 0xbabecafe,%xmm5
+
+// CHECK: por 305419896, %xmm5
+ por 0x12345678,%xmm5
+
+// CHECK: por %xmm5, %xmm5
+ por %xmm5,%xmm5
+
+// CHECK: psllw 3735928559(%ebx,%ecx,8), %mm3
+ psllw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psllw 69, %mm3
+ psllw 0x45,%mm3
+
+// CHECK: psllw 32493, %mm3
+ psllw 0x7eed,%mm3
+
+// CHECK: psllw 3133065982, %mm3
+ psllw 0xbabecafe,%mm3
+
+// CHECK: psllw 305419896, %mm3
+ psllw 0x12345678,%mm3
+
+// CHECK: psllw %mm3, %mm3
+ psllw %mm3,%mm3
+
+// CHECK: psllw 3735928559(%ebx,%ecx,8), %xmm5
+ psllw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psllw 69, %xmm5
+ psllw 0x45,%xmm5
+
+// CHECK: psllw 32493, %xmm5
+ psllw 0x7eed,%xmm5
+
+// CHECK: psllw 3133065982, %xmm5
+ psllw 0xbabecafe,%xmm5
+
+// CHECK: psllw 305419896, %xmm5
+ psllw 0x12345678,%xmm5
+
+// CHECK: psllw %xmm5, %xmm5
+ psllw %xmm5,%xmm5
+
+// CHECK: psllw $127, %mm3
+ psllw $0x7f,%mm3
+
+// CHECK: psllw $127, %xmm5
+ psllw $0x7f,%xmm5
+
+// CHECK: pslld 3735928559(%ebx,%ecx,8), %mm3
+ pslld 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pslld 69, %mm3
+ pslld 0x45,%mm3
+
+// CHECK: pslld 32493, %mm3
+ pslld 0x7eed,%mm3
+
+// CHECK: pslld 3133065982, %mm3
+ pslld 0xbabecafe,%mm3
+
+// CHECK: pslld 305419896, %mm3
+ pslld 0x12345678,%mm3
+
+// CHECK: pslld %mm3, %mm3
+ pslld %mm3,%mm3
+
+// CHECK: pslld 3735928559(%ebx,%ecx,8), %xmm5
+ pslld 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pslld 69, %xmm5
+ pslld 0x45,%xmm5
+
+// CHECK: pslld 32493, %xmm5
+ pslld 0x7eed,%xmm5
+
+// CHECK: pslld 3133065982, %xmm5
+ pslld 0xbabecafe,%xmm5
+
+// CHECK: pslld 305419896, %xmm5
+ pslld 0x12345678,%xmm5
+
+// CHECK: pslld %xmm5, %xmm5
+ pslld %xmm5,%xmm5
+
+// CHECK: pslld $127, %mm3
+ pslld $0x7f,%mm3
+
+// CHECK: pslld $127, %xmm5
+ pslld $0x7f,%xmm5
+
+// CHECK: psllq 3735928559(%ebx,%ecx,8), %mm3
+ psllq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psllq 69, %mm3
+ psllq 0x45,%mm3
+
+// CHECK: psllq 32493, %mm3
+ psllq 0x7eed,%mm3
+
+// CHECK: psllq 3133065982, %mm3
+ psllq 0xbabecafe,%mm3
+
+// CHECK: psllq 305419896, %mm3
+ psllq 0x12345678,%mm3
+
+// CHECK: psllq %mm3, %mm3
+ psllq %mm3,%mm3
+
+// CHECK: psllq 3735928559(%ebx,%ecx,8), %xmm5
+ psllq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psllq 69, %xmm5
+ psllq 0x45,%xmm5
+
+// CHECK: psllq 32493, %xmm5
+ psllq 0x7eed,%xmm5
+
+// CHECK: psllq 3133065982, %xmm5
+ psllq 0xbabecafe,%xmm5
+
+// CHECK: psllq 305419896, %xmm5
+ psllq 0x12345678,%xmm5
+
+// CHECK: psllq %xmm5, %xmm5
+ psllq %xmm5,%xmm5
+
+// CHECK: psllq $127, %mm3
+ psllq $0x7f,%mm3
+
+// CHECK: psllq $127, %xmm5
+ psllq $0x7f,%xmm5
+
+// CHECK: psraw 3735928559(%ebx,%ecx,8), %mm3
+ psraw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psraw 69, %mm3
+ psraw 0x45,%mm3
+
+// CHECK: psraw 32493, %mm3
+ psraw 0x7eed,%mm3
+
+// CHECK: psraw 3133065982, %mm3
+ psraw 0xbabecafe,%mm3
+
+// CHECK: psraw 305419896, %mm3
+ psraw 0x12345678,%mm3
+
+// CHECK: psraw %mm3, %mm3
+ psraw %mm3,%mm3
+
+// CHECK: psraw 3735928559(%ebx,%ecx,8), %xmm5
+ psraw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psraw 69, %xmm5
+ psraw 0x45,%xmm5
+
+// CHECK: psraw 32493, %xmm5
+ psraw 0x7eed,%xmm5
+
+// CHECK: psraw 3133065982, %xmm5
+ psraw 0xbabecafe,%xmm5
+
+// CHECK: psraw 305419896, %xmm5
+ psraw 0x12345678,%xmm5
+
+// CHECK: psraw %xmm5, %xmm5
+ psraw %xmm5,%xmm5
+
+// CHECK: psraw $127, %mm3
+ psraw $0x7f,%mm3
+
+// CHECK: psraw $127, %xmm5
+ psraw $0x7f,%xmm5
+
+// CHECK: psrad 3735928559(%ebx,%ecx,8), %mm3
+ psrad 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrad 69, %mm3
+ psrad 0x45,%mm3
+
+// CHECK: psrad 32493, %mm3
+ psrad 0x7eed,%mm3
+
+// CHECK: psrad 3133065982, %mm3
+ psrad 0xbabecafe,%mm3
+
+// CHECK: psrad 305419896, %mm3
+ psrad 0x12345678,%mm3
+
+// CHECK: psrad %mm3, %mm3
+ psrad %mm3,%mm3
+
+// CHECK: psrad 3735928559(%ebx,%ecx,8), %xmm5
+ psrad 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrad 69, %xmm5
+ psrad 0x45,%xmm5
+
+// CHECK: psrad 32493, %xmm5
+ psrad 0x7eed,%xmm5
+
+// CHECK: psrad 3133065982, %xmm5
+ psrad 0xbabecafe,%xmm5
+
+// CHECK: psrad 305419896, %xmm5
+ psrad 0x12345678,%xmm5
+
+// CHECK: psrad %xmm5, %xmm5
+ psrad %xmm5,%xmm5
+
+// CHECK: psrad $127, %mm3
+ psrad $0x7f,%mm3
+
+// CHECK: psrad $127, %xmm5
+ psrad $0x7f,%xmm5
+
+// CHECK: psrlw 3735928559(%ebx,%ecx,8), %mm3
+ psrlw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrlw 69, %mm3
+ psrlw 0x45,%mm3
+
+// CHECK: psrlw 32493, %mm3
+ psrlw 0x7eed,%mm3
+
+// CHECK: psrlw 3133065982, %mm3
+ psrlw 0xbabecafe,%mm3
+
+// CHECK: psrlw 305419896, %mm3
+ psrlw 0x12345678,%mm3
+
+// CHECK: psrlw %mm3, %mm3
+ psrlw %mm3,%mm3
+
+// CHECK: psrlw 3735928559(%ebx,%ecx,8), %xmm5
+ psrlw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrlw 69, %xmm5
+ psrlw 0x45,%xmm5
+
+// CHECK: psrlw 32493, %xmm5
+ psrlw 0x7eed,%xmm5
+
+// CHECK: psrlw 3133065982, %xmm5
+ psrlw 0xbabecafe,%xmm5
+
+// CHECK: psrlw 305419896, %xmm5
+ psrlw 0x12345678,%xmm5
+
+// CHECK: psrlw %xmm5, %xmm5
+ psrlw %xmm5,%xmm5
+
+// CHECK: psrlw $127, %mm3
+ psrlw $0x7f,%mm3
+
+// CHECK: psrlw $127, %xmm5
+ psrlw $0x7f,%xmm5
+
+// CHECK: psrld 3735928559(%ebx,%ecx,8), %mm3
+ psrld 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrld 69, %mm3
+ psrld 0x45,%mm3
+
+// CHECK: psrld 32493, %mm3
+ psrld 0x7eed,%mm3
+
+// CHECK: psrld 3133065982, %mm3
+ psrld 0xbabecafe,%mm3
+
+// CHECK: psrld 305419896, %mm3
+ psrld 0x12345678,%mm3
+
+// CHECK: psrld %mm3, %mm3
+ psrld %mm3,%mm3
+
+// CHECK: psrld 3735928559(%ebx,%ecx,8), %xmm5
+ psrld 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrld 69, %xmm5
+ psrld 0x45,%xmm5
+
+// CHECK: psrld 32493, %xmm5
+ psrld 0x7eed,%xmm5
+
+// CHECK: psrld 3133065982, %xmm5
+ psrld 0xbabecafe,%xmm5
+
+// CHECK: psrld 305419896, %xmm5
+ psrld 0x12345678,%xmm5
+
+// CHECK: psrld %xmm5, %xmm5
+ psrld %xmm5,%xmm5
+
+// CHECK: psrld $127, %mm3
+ psrld $0x7f,%mm3
+
+// CHECK: psrld $127, %xmm5
+ psrld $0x7f,%xmm5
+
+// CHECK: psrlq 3735928559(%ebx,%ecx,8), %mm3
+ psrlq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrlq 69, %mm3
+ psrlq 0x45,%mm3
+
+// CHECK: psrlq 32493, %mm3
+ psrlq 0x7eed,%mm3
+
+// CHECK: psrlq 3133065982, %mm3
+ psrlq 0xbabecafe,%mm3
+
+// CHECK: psrlq 305419896, %mm3
+ psrlq 0x12345678,%mm3
+
+// CHECK: psrlq %mm3, %mm3
+ psrlq %mm3,%mm3
+
+// CHECK: psrlq 3735928559(%ebx,%ecx,8), %xmm5
+ psrlq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrlq 69, %xmm5
+ psrlq 0x45,%xmm5
+
+// CHECK: psrlq 32493, %xmm5
+ psrlq 0x7eed,%xmm5
+
+// CHECK: psrlq 3133065982, %xmm5
+ psrlq 0xbabecafe,%xmm5
+
+// CHECK: psrlq 305419896, %xmm5
+ psrlq 0x12345678,%xmm5
+
+// CHECK: psrlq %xmm5, %xmm5
+ psrlq %xmm5,%xmm5
+
+// CHECK: psrlq $127, %mm3
+ psrlq $0x7f,%mm3
+
+// CHECK: psrlq $127, %xmm5
+ psrlq $0x7f,%xmm5
+
+// CHECK: psubb 3735928559(%ebx,%ecx,8), %mm3
+ psubb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubb 69, %mm3
+ psubb 0x45,%mm3
+
+// CHECK: psubb 32493, %mm3
+ psubb 0x7eed,%mm3
+
+// CHECK: psubb 3133065982, %mm3
+ psubb 0xbabecafe,%mm3
+
+// CHECK: psubb 305419896, %mm3
+ psubb 0x12345678,%mm3
+
+// CHECK: psubb %mm3, %mm3
+ psubb %mm3,%mm3
+
+// CHECK: psubb 3735928559(%ebx,%ecx,8), %xmm5
+ psubb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubb 69, %xmm5
+ psubb 0x45,%xmm5
+
+// CHECK: psubb 32493, %xmm5
+ psubb 0x7eed,%xmm5
+
+// CHECK: psubb 3133065982, %xmm5
+ psubb 0xbabecafe,%xmm5
+
+// CHECK: psubb 305419896, %xmm5
+ psubb 0x12345678,%xmm5
+
+// CHECK: psubb %xmm5, %xmm5
+ psubb %xmm5,%xmm5
+
+// CHECK: psubw 3735928559(%ebx,%ecx,8), %mm3
+ psubw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubw 69, %mm3
+ psubw 0x45,%mm3
+
+// CHECK: psubw 32493, %mm3
+ psubw 0x7eed,%mm3
+
+// CHECK: psubw 3133065982, %mm3
+ psubw 0xbabecafe,%mm3
+
+// CHECK: psubw 305419896, %mm3
+ psubw 0x12345678,%mm3
+
+// CHECK: psubw %mm3, %mm3
+ psubw %mm3,%mm3
+
+// CHECK: psubw 3735928559(%ebx,%ecx,8), %xmm5
+ psubw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubw 69, %xmm5
+ psubw 0x45,%xmm5
+
+// CHECK: psubw 32493, %xmm5
+ psubw 0x7eed,%xmm5
+
+// CHECK: psubw 3133065982, %xmm5
+ psubw 0xbabecafe,%xmm5
+
+// CHECK: psubw 305419896, %xmm5
+ psubw 0x12345678,%xmm5
+
+// CHECK: psubw %xmm5, %xmm5
+ psubw %xmm5,%xmm5
+
+// CHECK: psubd 3735928559(%ebx,%ecx,8), %mm3
+ psubd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubd 69, %mm3
+ psubd 0x45,%mm3
+
+// CHECK: psubd 32493, %mm3
+ psubd 0x7eed,%mm3
+
+// CHECK: psubd 3133065982, %mm3
+ psubd 0xbabecafe,%mm3
+
+// CHECK: psubd 305419896, %mm3
+ psubd 0x12345678,%mm3
+
+// CHECK: psubd %mm3, %mm3
+ psubd %mm3,%mm3
+
+// CHECK: psubd 3735928559(%ebx,%ecx,8), %xmm5
+ psubd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubd 69, %xmm5
+ psubd 0x45,%xmm5
+
+// CHECK: psubd 32493, %xmm5
+ psubd 0x7eed,%xmm5
+
+// CHECK: psubd 3133065982, %xmm5
+ psubd 0xbabecafe,%xmm5
+
+// CHECK: psubd 305419896, %xmm5
+ psubd 0x12345678,%xmm5
+
+// CHECK: psubd %xmm5, %xmm5
+ psubd %xmm5,%xmm5
+
+// CHECK: psubq 3735928559(%ebx,%ecx,8), %mm3
+ psubq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubq 69, %mm3
+ psubq 0x45,%mm3
+
+// CHECK: psubq 32493, %mm3
+ psubq 0x7eed,%mm3
+
+// CHECK: psubq 3133065982, %mm3
+ psubq 0xbabecafe,%mm3
+
+// CHECK: psubq 305419896, %mm3
+ psubq 0x12345678,%mm3
+
+// CHECK: psubq %mm3, %mm3
+ psubq %mm3,%mm3
+
+// CHECK: psubq 3735928559(%ebx,%ecx,8), %xmm5
+ psubq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubq 69, %xmm5
+ psubq 0x45,%xmm5
+
+// CHECK: psubq 32493, %xmm5
+ psubq 0x7eed,%xmm5
+
+// CHECK: psubq 3133065982, %xmm5
+ psubq 0xbabecafe,%xmm5
+
+// CHECK: psubq 305419896, %xmm5
+ psubq 0x12345678,%xmm5
+
+// CHECK: psubq %xmm5, %xmm5
+ psubq %xmm5,%xmm5
+
+// CHECK: psubsb 3735928559(%ebx,%ecx,8), %mm3
+ psubsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubsb 69, %mm3
+ psubsb 0x45,%mm3
+
+// CHECK: psubsb 32493, %mm3
+ psubsb 0x7eed,%mm3
+
+// CHECK: psubsb 3133065982, %mm3
+ psubsb 0xbabecafe,%mm3
+
+// CHECK: psubsb 305419896, %mm3
+ psubsb 0x12345678,%mm3
+
+// CHECK: psubsb %mm3, %mm3
+ psubsb %mm3,%mm3
+
+// CHECK: psubsb 3735928559(%ebx,%ecx,8), %xmm5
+ psubsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubsb 69, %xmm5
+ psubsb 0x45,%xmm5
+
+// CHECK: psubsb 32493, %xmm5
+ psubsb 0x7eed,%xmm5
+
+// CHECK: psubsb 3133065982, %xmm5
+ psubsb 0xbabecafe,%xmm5
+
+// CHECK: psubsb 305419896, %xmm5
+ psubsb 0x12345678,%xmm5
+
+// CHECK: psubsb %xmm5, %xmm5
+ psubsb %xmm5,%xmm5
+
+// CHECK: psubsw 3735928559(%ebx,%ecx,8), %mm3
+ psubsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubsw 69, %mm3
+ psubsw 0x45,%mm3
+
+// CHECK: psubsw 32493, %mm3
+ psubsw 0x7eed,%mm3
+
+// CHECK: psubsw 3133065982, %mm3
+ psubsw 0xbabecafe,%mm3
+
+// CHECK: psubsw 305419896, %mm3
+ psubsw 0x12345678,%mm3
+
+// CHECK: psubsw %mm3, %mm3
+ psubsw %mm3,%mm3
+
+// CHECK: psubsw 3735928559(%ebx,%ecx,8), %xmm5
+ psubsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubsw 69, %xmm5
+ psubsw 0x45,%xmm5
+
+// CHECK: psubsw 32493, %xmm5
+ psubsw 0x7eed,%xmm5
+
+// CHECK: psubsw 3133065982, %xmm5
+ psubsw 0xbabecafe,%xmm5
+
+// CHECK: psubsw 305419896, %xmm5
+ psubsw 0x12345678,%xmm5
+
+// CHECK: psubsw %xmm5, %xmm5
+ psubsw %xmm5,%xmm5
+
+// CHECK: psubusb 3735928559(%ebx,%ecx,8), %mm3
+ psubusb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubusb 69, %mm3
+ psubusb 0x45,%mm3
+
+// CHECK: psubusb 32493, %mm3
+ psubusb 0x7eed,%mm3
+
+// CHECK: psubusb 3133065982, %mm3
+ psubusb 0xbabecafe,%mm3
+
+// CHECK: psubusb 305419896, %mm3
+ psubusb 0x12345678,%mm3
+
+// CHECK: psubusb %mm3, %mm3
+ psubusb %mm3,%mm3
+
+// CHECK: psubusb 3735928559(%ebx,%ecx,8), %xmm5
+ psubusb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubusb 69, %xmm5
+ psubusb 0x45,%xmm5
+
+// CHECK: psubusb 32493, %xmm5
+ psubusb 0x7eed,%xmm5
+
+// CHECK: psubusb 3133065982, %xmm5
+ psubusb 0xbabecafe,%xmm5
+
+// CHECK: psubusb 305419896, %xmm5
+ psubusb 0x12345678,%xmm5
+
+// CHECK: psubusb %xmm5, %xmm5
+ psubusb %xmm5,%xmm5
+
+// CHECK: psubusw 3735928559(%ebx,%ecx,8), %mm3
+ psubusw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubusw 69, %mm3
+ psubusw 0x45,%mm3
+
+// CHECK: psubusw 32493, %mm3
+ psubusw 0x7eed,%mm3
+
+// CHECK: psubusw 3133065982, %mm3
+ psubusw 0xbabecafe,%mm3
+
+// CHECK: psubusw 305419896, %mm3
+ psubusw 0x12345678,%mm3
+
+// CHECK: psubusw %mm3, %mm3
+ psubusw %mm3,%mm3
+
+// CHECK: psubusw 3735928559(%ebx,%ecx,8), %xmm5
+ psubusw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubusw 69, %xmm5
+ psubusw 0x45,%xmm5
+
+// CHECK: psubusw 32493, %xmm5
+ psubusw 0x7eed,%xmm5
+
+// CHECK: psubusw 3133065982, %xmm5
+ psubusw 0xbabecafe,%xmm5
+
+// CHECK: psubusw 305419896, %xmm5
+ psubusw 0x12345678,%xmm5
+
+// CHECK: psubusw %xmm5, %xmm5
+ psubusw %xmm5,%xmm5
+
+// CHECK: punpckhbw 3735928559(%ebx,%ecx,8), %mm3
+ punpckhbw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckhbw 69, %mm3
+ punpckhbw 0x45,%mm3
+
+// CHECK: punpckhbw 32493, %mm3
+ punpckhbw 0x7eed,%mm3
+
+// CHECK: punpckhbw 3133065982, %mm3
+ punpckhbw 0xbabecafe,%mm3
+
+// CHECK: punpckhbw 305419896, %mm3
+ punpckhbw 0x12345678,%mm3
+
+// CHECK: punpckhbw %mm3, %mm3
+ punpckhbw %mm3,%mm3
+
+// CHECK: punpckhbw 3735928559(%ebx,%ecx,8), %xmm5
+ punpckhbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhbw 69, %xmm5
+ punpckhbw 0x45,%xmm5
+
+// CHECK: punpckhbw 32493, %xmm5
+ punpckhbw 0x7eed,%xmm5
+
+// CHECK: punpckhbw 3133065982, %xmm5
+ punpckhbw 0xbabecafe,%xmm5
+
+// CHECK: punpckhbw 305419896, %xmm5
+ punpckhbw 0x12345678,%xmm5
+
+// CHECK: punpckhbw %xmm5, %xmm5
+ punpckhbw %xmm5,%xmm5
+
+// CHECK: punpckhwd 3735928559(%ebx,%ecx,8), %mm3
+ punpckhwd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckhwd 69, %mm3
+ punpckhwd 0x45,%mm3
+
+// CHECK: punpckhwd 32493, %mm3
+ punpckhwd 0x7eed,%mm3
+
+// CHECK: punpckhwd 3133065982, %mm3
+ punpckhwd 0xbabecafe,%mm3
+
+// CHECK: punpckhwd 305419896, %mm3
+ punpckhwd 0x12345678,%mm3
+
+// CHECK: punpckhwd %mm3, %mm3
+ punpckhwd %mm3,%mm3
+
+// CHECK: punpckhwd 3735928559(%ebx,%ecx,8), %xmm5
+ punpckhwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhwd 69, %xmm5
+ punpckhwd 0x45,%xmm5
+
+// CHECK: punpckhwd 32493, %xmm5
+ punpckhwd 0x7eed,%xmm5
+
+// CHECK: punpckhwd 3133065982, %xmm5
+ punpckhwd 0xbabecafe,%xmm5
+
+// CHECK: punpckhwd 305419896, %xmm5
+ punpckhwd 0x12345678,%xmm5
+
+// CHECK: punpckhwd %xmm5, %xmm5
+ punpckhwd %xmm5,%xmm5
+
+// CHECK: punpckhdq 3735928559(%ebx,%ecx,8), %mm3
+ punpckhdq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckhdq 69, %mm3
+ punpckhdq 0x45,%mm3
+
+// CHECK: punpckhdq 32493, %mm3
+ punpckhdq 0x7eed,%mm3
+
+// CHECK: punpckhdq 3133065982, %mm3
+ punpckhdq 0xbabecafe,%mm3
+
+// CHECK: punpckhdq 305419896, %mm3
+ punpckhdq 0x12345678,%mm3
+
+// CHECK: punpckhdq %mm3, %mm3
+ punpckhdq %mm3,%mm3
+
+// CHECK: punpckhdq 3735928559(%ebx,%ecx,8), %xmm5
+ punpckhdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhdq 69, %xmm5
+ punpckhdq 0x45,%xmm5
+
+// CHECK: punpckhdq 32493, %xmm5
+ punpckhdq 0x7eed,%xmm5
+
+// CHECK: punpckhdq 3133065982, %xmm5
+ punpckhdq 0xbabecafe,%xmm5
+
+// CHECK: punpckhdq 305419896, %xmm5
+ punpckhdq 0x12345678,%xmm5
+
+// CHECK: punpckhdq %xmm5, %xmm5
+ punpckhdq %xmm5,%xmm5
+
+// CHECK: punpcklbw 3735928559(%ebx,%ecx,8), %mm3
+ punpcklbw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpcklbw 69, %mm3
+ punpcklbw 0x45,%mm3
+
+// CHECK: punpcklbw 32493, %mm3
+ punpcklbw 0x7eed,%mm3
+
+// CHECK: punpcklbw 3133065982, %mm3
+ punpcklbw 0xbabecafe,%mm3
+
+// CHECK: punpcklbw 305419896, %mm3
+ punpcklbw 0x12345678,%mm3
+
+// CHECK: punpcklbw %mm3, %mm3
+ punpcklbw %mm3,%mm3
+
+// CHECK: punpcklbw 3735928559(%ebx,%ecx,8), %xmm5
+ punpcklbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpcklbw 69, %xmm5
+ punpcklbw 0x45,%xmm5
+
+// CHECK: punpcklbw 32493, %xmm5
+ punpcklbw 0x7eed,%xmm5
+
+// CHECK: punpcklbw 3133065982, %xmm5
+ punpcklbw 0xbabecafe,%xmm5
+
+// CHECK: punpcklbw 305419896, %xmm5
+ punpcklbw 0x12345678,%xmm5
+
+// CHECK: punpcklbw %xmm5, %xmm5
+ punpcklbw %xmm5,%xmm5
+
+// CHECK: punpcklwd 3735928559(%ebx,%ecx,8), %mm3
+ punpcklwd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpcklwd 69, %mm3
+ punpcklwd 0x45,%mm3
+
+// CHECK: punpcklwd 32493, %mm3
+ punpcklwd 0x7eed,%mm3
+
+// CHECK: punpcklwd 3133065982, %mm3
+ punpcklwd 0xbabecafe,%mm3
+
+// CHECK: punpcklwd 305419896, %mm3
+ punpcklwd 0x12345678,%mm3
+
+// CHECK: punpcklwd %mm3, %mm3
+ punpcklwd %mm3,%mm3
+
+// CHECK: punpcklwd 3735928559(%ebx,%ecx,8), %xmm5
+ punpcklwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpcklwd 69, %xmm5
+ punpcklwd 0x45,%xmm5
+
+// CHECK: punpcklwd 32493, %xmm5
+ punpcklwd 0x7eed,%xmm5
+
+// CHECK: punpcklwd 3133065982, %xmm5
+ punpcklwd 0xbabecafe,%xmm5
+
+// CHECK: punpcklwd 305419896, %xmm5
+ punpcklwd 0x12345678,%xmm5
+
+// CHECK: punpcklwd %xmm5, %xmm5
+ punpcklwd %xmm5,%xmm5
+
+// CHECK: punpckldq 3735928559(%ebx,%ecx,8), %mm3
+ punpckldq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckldq 69, %mm3
+ punpckldq 0x45,%mm3
+
+// CHECK: punpckldq 32493, %mm3
+ punpckldq 0x7eed,%mm3
+
+// CHECK: punpckldq 3133065982, %mm3
+ punpckldq 0xbabecafe,%mm3
+
+// CHECK: punpckldq 305419896, %mm3
+ punpckldq 0x12345678,%mm3
+
+// CHECK: punpckldq %mm3, %mm3
+ punpckldq %mm3,%mm3
+
+// CHECK: punpckldq 3735928559(%ebx,%ecx,8), %xmm5
+ punpckldq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckldq 69, %xmm5
+ punpckldq 0x45,%xmm5
+
+// CHECK: punpckldq 32493, %xmm5
+ punpckldq 0x7eed,%xmm5
+
+// CHECK: punpckldq 3133065982, %xmm5
+ punpckldq 0xbabecafe,%xmm5
+
+// CHECK: punpckldq 305419896, %xmm5
+ punpckldq 0x12345678,%xmm5
+
+// CHECK: punpckldq %xmm5, %xmm5
+ punpckldq %xmm5,%xmm5
+
+// CHECK: pxor 3735928559(%ebx,%ecx,8), %mm3
+ pxor 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pxor 69, %mm3
+ pxor 0x45,%mm3
+
+// CHECK: pxor 32493, %mm3
+ pxor 0x7eed,%mm3
+
+// CHECK: pxor 3133065982, %mm3
+ pxor 0xbabecafe,%mm3
+
+// CHECK: pxor 305419896, %mm3
+ pxor 0x12345678,%mm3
+
+// CHECK: pxor %mm3, %mm3
+ pxor %mm3,%mm3
+
+// CHECK: pxor 3735928559(%ebx,%ecx,8), %xmm5
+ pxor 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pxor 69, %xmm5
+ pxor 0x45,%xmm5
+
+// CHECK: pxor 32493, %xmm5
+ pxor 0x7eed,%xmm5
+
+// CHECK: pxor 3133065982, %xmm5
+ pxor 0xbabecafe,%xmm5
+
+// CHECK: pxor 305419896, %xmm5
+ pxor 0x12345678,%xmm5
+
+// CHECK: pxor %xmm5, %xmm5
+ pxor %xmm5,%xmm5
+
+// CHECK: addps 3735928559(%ebx,%ecx,8), %xmm5
+ addps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addps 69, %xmm5
+ addps 0x45,%xmm5
+
+// CHECK: addps 32493, %xmm5
+ addps 0x7eed,%xmm5
+
+// CHECK: addps 3133065982, %xmm5
+ addps 0xbabecafe,%xmm5
+
+// CHECK: addps 305419896, %xmm5
+ addps 0x12345678,%xmm5
+
+// CHECK: addps %xmm5, %xmm5
+ addps %xmm5,%xmm5
+
+// CHECK: addss 3735928559(%ebx,%ecx,8), %xmm5
+ addss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addss 69, %xmm5
+ addss 0x45,%xmm5
+
+// CHECK: addss 32493, %xmm5
+ addss 0x7eed,%xmm5
+
+// CHECK: addss 3133065982, %xmm5
+ addss 0xbabecafe,%xmm5
+
+// CHECK: addss 305419896, %xmm5
+ addss 0x12345678,%xmm5
+
+// CHECK: addss %xmm5, %xmm5
+ addss %xmm5,%xmm5
+
+// CHECK: andnps 3735928559(%ebx,%ecx,8), %xmm5
+ andnps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andnps 69, %xmm5
+ andnps 0x45,%xmm5
+
+// CHECK: andnps 32493, %xmm5
+ andnps 0x7eed,%xmm5
+
+// CHECK: andnps 3133065982, %xmm5
+ andnps 0xbabecafe,%xmm5
+
+// CHECK: andnps 305419896, %xmm5
+ andnps 0x12345678,%xmm5
+
+// CHECK: andnps %xmm5, %xmm5
+ andnps %xmm5,%xmm5
+
+// CHECK: andps 3735928559(%ebx,%ecx,8), %xmm5
+ andps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andps 69, %xmm5
+ andps 0x45,%xmm5
+
+// CHECK: andps 32493, %xmm5
+ andps 0x7eed,%xmm5
+
+// CHECK: andps 3133065982, %xmm5
+ andps 0xbabecafe,%xmm5
+
+// CHECK: andps 305419896, %xmm5
+ andps 0x12345678,%xmm5
+
+// CHECK: andps %xmm5, %xmm5
+ andps %xmm5,%xmm5
+
+// CHECK: comiss 3735928559(%ebx,%ecx,8), %xmm5
+ comiss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: comiss 69, %xmm5
+ comiss 0x45,%xmm5
+
+// CHECK: comiss 32493, %xmm5
+ comiss 0x7eed,%xmm5
+
+// CHECK: comiss 3133065982, %xmm5
+ comiss 0xbabecafe,%xmm5
+
+// CHECK: comiss 305419896, %xmm5
+ comiss 0x12345678,%xmm5
+
+// CHECK: comiss %xmm5, %xmm5
+ comiss %xmm5,%xmm5
+
+// CHECK: cvtpi2ps 3735928559(%ebx,%ecx,8), %xmm5
+ cvtpi2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpi2ps 69, %xmm5
+ cvtpi2ps 0x45,%xmm5
+
+// CHECK: cvtpi2ps 32493, %xmm5
+ cvtpi2ps 0x7eed,%xmm5
+
+// CHECK: cvtpi2ps 3133065982, %xmm5
+ cvtpi2ps 0xbabecafe,%xmm5
+
+// CHECK: cvtpi2ps 305419896, %xmm5
+ cvtpi2ps 0x12345678,%xmm5
+
+// CHECK: cvtpi2ps %mm3, %xmm5
+ cvtpi2ps %mm3,%xmm5
+
+// CHECK: cvtps2pi 3735928559(%ebx,%ecx,8), %mm3
+ cvtps2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvtps2pi 69, %mm3
+ cvtps2pi 0x45,%mm3
+
+// CHECK: cvtps2pi 32493, %mm3
+ cvtps2pi 0x7eed,%mm3
+
+// CHECK: cvtps2pi 3133065982, %mm3
+ cvtps2pi 0xbabecafe,%mm3
+
+// CHECK: cvtps2pi 305419896, %mm3
+ cvtps2pi 0x12345678,%mm3
+
+// CHECK: cvtps2pi %xmm5, %mm3
+ cvtps2pi %xmm5,%mm3
+
+// CHECK: cvtsi2ss %ecx, %xmm5
+ cvtsi2ss %ecx,%xmm5
+
+// CHECK: cvtsi2ss 3735928559(%ebx,%ecx,8), %xmm5
+ cvtsi2ss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtsi2ss 69, %xmm5
+ cvtsi2ss 0x45,%xmm5
+
+// CHECK: cvtsi2ss 32493, %xmm5
+ cvtsi2ss 0x7eed,%xmm5
+
+// CHECK: cvtsi2ss 3133065982, %xmm5
+ cvtsi2ss 0xbabecafe,%xmm5
+
+// CHECK: cvtsi2ss 305419896, %xmm5
+ cvtsi2ss 0x12345678,%xmm5
+
+// CHECK: cvttps2pi 3735928559(%ebx,%ecx,8), %mm3
+ cvttps2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvttps2pi 69, %mm3
+ cvttps2pi 0x45,%mm3
+
+// CHECK: cvttps2pi 32493, %mm3
+ cvttps2pi 0x7eed,%mm3
+
+// CHECK: cvttps2pi 3133065982, %mm3
+ cvttps2pi 0xbabecafe,%mm3
+
+// CHECK: cvttps2pi 305419896, %mm3
+ cvttps2pi 0x12345678,%mm3
+
+// CHECK: cvttps2pi %xmm5, %mm3
+ cvttps2pi %xmm5,%mm3
+
+// CHECK: cvttss2si 3735928559(%ebx,%ecx,8), %ecx
+ cvttss2si 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: cvttss2si 69, %ecx
+ cvttss2si 0x45,%ecx
+
+// CHECK: cvttss2si 32493, %ecx
+ cvttss2si 0x7eed,%ecx
+
+// CHECK: cvttss2si 3133065982, %ecx
+ cvttss2si 0xbabecafe,%ecx
+
+// CHECK: cvttss2si 305419896, %ecx
+ cvttss2si 0x12345678,%ecx
+
+// CHECK: cvttss2si %xmm5, %ecx
+ cvttss2si %xmm5,%ecx
+
+// CHECK: divps 3735928559(%ebx,%ecx,8), %xmm5
+ divps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divps 69, %xmm5
+ divps 0x45,%xmm5
+
+// CHECK: divps 32493, %xmm5
+ divps 0x7eed,%xmm5
+
+// CHECK: divps 3133065982, %xmm5
+ divps 0xbabecafe,%xmm5
+
+// CHECK: divps 305419896, %xmm5
+ divps 0x12345678,%xmm5
+
+// CHECK: divps %xmm5, %xmm5
+ divps %xmm5,%xmm5
+
+// CHECK: divss 3735928559(%ebx,%ecx,8), %xmm5
+ divss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divss 69, %xmm5
+ divss 0x45,%xmm5
+
+// CHECK: divss 32493, %xmm5
+ divss 0x7eed,%xmm5
+
+// CHECK: divss 3133065982, %xmm5
+ divss 0xbabecafe,%xmm5
+
+// CHECK: divss 305419896, %xmm5
+ divss 0x12345678,%xmm5
+
+// CHECK: divss %xmm5, %xmm5
+ divss %xmm5,%xmm5
+
+// CHECK: ldmxcsr 3735928559(%ebx,%ecx,8)
+ ldmxcsr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ldmxcsr 32493
+ ldmxcsr 0x7eed
+
+// CHECK: ldmxcsr 3133065982
+ ldmxcsr 0xbabecafe
+
+// CHECK: ldmxcsr 305419896
+ ldmxcsr 0x12345678
+
+// CHECK: maskmovq %mm3, %mm3
+ maskmovq %mm3,%mm3
+
+// CHECK: maxps 3735928559(%ebx,%ecx,8), %xmm5
+ maxps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxps 69, %xmm5
+ maxps 0x45,%xmm5
+
+// CHECK: maxps 32493, %xmm5
+ maxps 0x7eed,%xmm5
+
+// CHECK: maxps 3133065982, %xmm5
+ maxps 0xbabecafe,%xmm5
+
+// CHECK: maxps 305419896, %xmm5
+ maxps 0x12345678,%xmm5
+
+// CHECK: maxps %xmm5, %xmm5
+ maxps %xmm5,%xmm5
+
+// CHECK: maxss 3735928559(%ebx,%ecx,8), %xmm5
+ maxss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxss 69, %xmm5
+ maxss 0x45,%xmm5
+
+// CHECK: maxss 32493, %xmm5
+ maxss 0x7eed,%xmm5
+
+// CHECK: maxss 3133065982, %xmm5
+ maxss 0xbabecafe,%xmm5
+
+// CHECK: maxss 305419896, %xmm5
+ maxss 0x12345678,%xmm5
+
+// CHECK: maxss %xmm5, %xmm5
+ maxss %xmm5,%xmm5
+
+// CHECK: minps 3735928559(%ebx,%ecx,8), %xmm5
+ minps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minps 69, %xmm5
+ minps 0x45,%xmm5
+
+// CHECK: minps 32493, %xmm5
+ minps 0x7eed,%xmm5
+
+// CHECK: minps 3133065982, %xmm5
+ minps 0xbabecafe,%xmm5
+
+// CHECK: minps 305419896, %xmm5
+ minps 0x12345678,%xmm5
+
+// CHECK: minps %xmm5, %xmm5
+ minps %xmm5,%xmm5
+
+// CHECK: minss 3735928559(%ebx,%ecx,8), %xmm5
+ minss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minss 69, %xmm5
+ minss 0x45,%xmm5
+
+// CHECK: minss 32493, %xmm5
+ minss 0x7eed,%xmm5
+
+// CHECK: minss 3133065982, %xmm5
+ minss 0xbabecafe,%xmm5
+
+// CHECK: minss 305419896, %xmm5
+ minss 0x12345678,%xmm5
+
+// CHECK: minss %xmm5, %xmm5
+ minss %xmm5,%xmm5
+
+// CHECK: movaps 3735928559(%ebx,%ecx,8), %xmm5
+ movaps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movaps 69, %xmm5
+ movaps 0x45,%xmm5
+
+// CHECK: movaps 32493, %xmm5
+ movaps 0x7eed,%xmm5
+
+// CHECK: movaps 3133065982, %xmm5
+ movaps 0xbabecafe,%xmm5
+
+// CHECK: movaps 305419896, %xmm5
+ movaps 0x12345678,%xmm5
+
+// CHECK: movaps %xmm5, %xmm5
+ movaps %xmm5,%xmm5
+
+// CHECK: movaps %xmm5, 3735928559(%ebx,%ecx,8)
+ movaps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movaps %xmm5, 69
+ movaps %xmm5,0x45
+
+// CHECK: movaps %xmm5, 32493
+ movaps %xmm5,0x7eed
+
+// CHECK: movaps %xmm5, 3133065982
+ movaps %xmm5,0xbabecafe
+
+// CHECK: movaps %xmm5, 305419896
+ movaps %xmm5,0x12345678
+
+// CHECK: movaps %xmm5, %xmm5
+ movaps %xmm5,%xmm5
+
+// CHECK: movhlps %xmm5, %xmm5
+ movhlps %xmm5,%xmm5
+
+// CHECK: movhps 3735928559(%ebx,%ecx,8), %xmm5
+ movhps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movhps 69, %xmm5
+ movhps 0x45,%xmm5
+
+// CHECK: movhps 32493, %xmm5
+ movhps 0x7eed,%xmm5
+
+// CHECK: movhps 3133065982, %xmm5
+ movhps 0xbabecafe,%xmm5
+
+// CHECK: movhps 305419896, %xmm5
+ movhps 0x12345678,%xmm5
+
+// CHECK: movhps %xmm5, 3735928559(%ebx,%ecx,8)
+ movhps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movhps %xmm5, 69
+ movhps %xmm5,0x45
+
+// CHECK: movhps %xmm5, 32493
+ movhps %xmm5,0x7eed
+
+// CHECK: movhps %xmm5, 3133065982
+ movhps %xmm5,0xbabecafe
+
+// CHECK: movhps %xmm5, 305419896
+ movhps %xmm5,0x12345678
+
+// CHECK: movlhps %xmm5, %xmm5
+ movlhps %xmm5,%xmm5
+
+// CHECK: movlps 3735928559(%ebx,%ecx,8), %xmm5
+ movlps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movlps 69, %xmm5
+ movlps 0x45,%xmm5
+
+// CHECK: movlps 32493, %xmm5
+ movlps 0x7eed,%xmm5
+
+// CHECK: movlps 3133065982, %xmm5
+ movlps 0xbabecafe,%xmm5
+
+// CHECK: movlps 305419896, %xmm5
+ movlps 0x12345678,%xmm5
+
+// CHECK: movlps %xmm5, 3735928559(%ebx,%ecx,8)
+ movlps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movlps %xmm5, 69
+ movlps %xmm5,0x45
+
+// CHECK: movlps %xmm5, 32493
+ movlps %xmm5,0x7eed
+
+// CHECK: movlps %xmm5, 3133065982
+ movlps %xmm5,0xbabecafe
+
+// CHECK: movlps %xmm5, 305419896
+ movlps %xmm5,0x12345678
+
+// CHECK: movmskps %xmm5, %ecx
+ movmskps %xmm5,%ecx
+
+// CHECK: movntps %xmm5, 3735928559(%ebx,%ecx,8)
+ movntps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntps %xmm5, 69
+ movntps %xmm5,0x45
+
+// CHECK: movntps %xmm5, 32493
+ movntps %xmm5,0x7eed
+
+// CHECK: movntps %xmm5, 3133065982
+ movntps %xmm5,0xbabecafe
+
+// CHECK: movntps %xmm5, 305419896
+ movntps %xmm5,0x12345678
+
+// CHECK: movntq %mm3, 3735928559(%ebx,%ecx,8)
+ movntq %mm3,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntq %mm3, 69
+ movntq %mm3,0x45
+
+// CHECK: movntq %mm3, 32493
+ movntq %mm3,0x7eed
+
+// CHECK: movntq %mm3, 3133065982
+ movntq %mm3,0xbabecafe
+
+// CHECK: movntq %mm3, 305419896
+ movntq %mm3,0x12345678
+
+// CHECK: movntdq %xmm5, 3735928559(%ebx,%ecx,8)
+ movntdq %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntdq %xmm5, 69
+ movntdq %xmm5,0x45
+
+// CHECK: movntdq %xmm5, 32493
+ movntdq %xmm5,0x7eed
+
+// CHECK: movntdq %xmm5, 3133065982
+ movntdq %xmm5,0xbabecafe
+
+// CHECK: movntdq %xmm5, 305419896
+ movntdq %xmm5,0x12345678
+
+// CHECK: movss 3735928559(%ebx,%ecx,8), %xmm5
+ movss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movss 69, %xmm5
+ movss 0x45,%xmm5
+
+// CHECK: movss 32493, %xmm5
+ movss 0x7eed,%xmm5
+
+// CHECK: movss 3133065982, %xmm5
+ movss 0xbabecafe,%xmm5
+
+// CHECK: movss 305419896, %xmm5
+ movss 0x12345678,%xmm5
+
+// CHECK: movss %xmm5, %xmm5
+ movss %xmm5,%xmm5
+
+// CHECK: movss %xmm5, 3735928559(%ebx,%ecx,8)
+ movss %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movss %xmm5, 69
+ movss %xmm5,0x45
+
+// CHECK: movss %xmm5, 32493
+ movss %xmm5,0x7eed
+
+// CHECK: movss %xmm5, 3133065982
+ movss %xmm5,0xbabecafe
+
+// CHECK: movss %xmm5, 305419896
+ movss %xmm5,0x12345678
+
+// CHECK: movss %xmm5, %xmm5
+ movss %xmm5,%xmm5
+
+// CHECK: movups 3735928559(%ebx,%ecx,8), %xmm5
+ movups 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movups 69, %xmm5
+ movups 0x45,%xmm5
+
+// CHECK: movups 32493, %xmm5
+ movups 0x7eed,%xmm5
+
+// CHECK: movups 3133065982, %xmm5
+ movups 0xbabecafe,%xmm5
+
+// CHECK: movups 305419896, %xmm5
+ movups 0x12345678,%xmm5
+
+// CHECK: movups %xmm5, %xmm5
+ movups %xmm5,%xmm5
+
+// CHECK: movups %xmm5, 3735928559(%ebx,%ecx,8)
+ movups %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movups %xmm5, 69
+ movups %xmm5,0x45
+
+// CHECK: movups %xmm5, 32493
+ movups %xmm5,0x7eed
+
+// CHECK: movups %xmm5, 3133065982
+ movups %xmm5,0xbabecafe
+
+// CHECK: movups %xmm5, 305419896
+ movups %xmm5,0x12345678
+
+// CHECK: movups %xmm5, %xmm5
+ movups %xmm5,%xmm5
+
+// CHECK: mulps 3735928559(%ebx,%ecx,8), %xmm5
+ mulps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulps 69, %xmm5
+ mulps 0x45,%xmm5
+
+// CHECK: mulps 32493, %xmm5
+ mulps 0x7eed,%xmm5
+
+// CHECK: mulps 3133065982, %xmm5
+ mulps 0xbabecafe,%xmm5
+
+// CHECK: mulps 305419896, %xmm5
+ mulps 0x12345678,%xmm5
+
+// CHECK: mulps %xmm5, %xmm5
+ mulps %xmm5,%xmm5
+
+// CHECK: mulss 3735928559(%ebx,%ecx,8), %xmm5
+ mulss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulss 69, %xmm5
+ mulss 0x45,%xmm5
+
+// CHECK: mulss 32493, %xmm5
+ mulss 0x7eed,%xmm5
+
+// CHECK: mulss 3133065982, %xmm5
+ mulss 0xbabecafe,%xmm5
+
+// CHECK: mulss 305419896, %xmm5
+ mulss 0x12345678,%xmm5
+
+// CHECK: mulss %xmm5, %xmm5
+ mulss %xmm5,%xmm5
+
+// CHECK: orps 3735928559(%ebx,%ecx,8), %xmm5
+ orps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: orps 69, %xmm5
+ orps 0x45,%xmm5
+
+// CHECK: orps 32493, %xmm5
+ orps 0x7eed,%xmm5
+
+// CHECK: orps 3133065982, %xmm5
+ orps 0xbabecafe,%xmm5
+
+// CHECK: orps 305419896, %xmm5
+ orps 0x12345678,%xmm5
+
+// CHECK: orps %xmm5, %xmm5
+ orps %xmm5,%xmm5
+
+// CHECK: pavgb 3735928559(%ebx,%ecx,8), %mm3
+ pavgb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pavgb 69, %mm3
+ pavgb 0x45,%mm3
+
+// CHECK: pavgb 32493, %mm3
+ pavgb 0x7eed,%mm3
+
+// CHECK: pavgb 3133065982, %mm3
+ pavgb 0xbabecafe,%mm3
+
+// CHECK: pavgb 305419896, %mm3
+ pavgb 0x12345678,%mm3
+
+// CHECK: pavgb %mm3, %mm3
+ pavgb %mm3,%mm3
+
+// CHECK: pavgb 3735928559(%ebx,%ecx,8), %xmm5
+ pavgb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pavgb 69, %xmm5
+ pavgb 0x45,%xmm5
+
+// CHECK: pavgb 32493, %xmm5
+ pavgb 0x7eed,%xmm5
+
+// CHECK: pavgb 3133065982, %xmm5
+ pavgb 0xbabecafe,%xmm5
+
+// CHECK: pavgb 305419896, %xmm5
+ pavgb 0x12345678,%xmm5
+
+// CHECK: pavgb %xmm5, %xmm5
+ pavgb %xmm5,%xmm5
+
+// CHECK: pavgw 3735928559(%ebx,%ecx,8), %mm3
+ pavgw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pavgw 69, %mm3
+ pavgw 0x45,%mm3
+
+// CHECK: pavgw 32493, %mm3
+ pavgw 0x7eed,%mm3
+
+// CHECK: pavgw 3133065982, %mm3
+ pavgw 0xbabecafe,%mm3
+
+// CHECK: pavgw 305419896, %mm3
+ pavgw 0x12345678,%mm3
+
+// CHECK: pavgw %mm3, %mm3
+ pavgw %mm3,%mm3
+
+// CHECK: pavgw 3735928559(%ebx,%ecx,8), %xmm5
+ pavgw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pavgw 69, %xmm5
+ pavgw 0x45,%xmm5
+
+// CHECK: pavgw 32493, %xmm5
+ pavgw 0x7eed,%xmm5
+
+// CHECK: pavgw 3133065982, %xmm5
+ pavgw 0xbabecafe,%xmm5
+
+// CHECK: pavgw 305419896, %xmm5
+ pavgw 0x12345678,%xmm5
+
+// CHECK: pavgw %xmm5, %xmm5
+ pavgw %xmm5,%xmm5
+
+// CHECK: pmaxsw 3735928559(%ebx,%ecx,8), %mm3
+ pmaxsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaxsw 69, %mm3
+ pmaxsw 0x45,%mm3
+
+// CHECK: pmaxsw 32493, %mm3
+ pmaxsw 0x7eed,%mm3
+
+// CHECK: pmaxsw 3133065982, %mm3
+ pmaxsw 0xbabecafe,%mm3
+
+// CHECK: pmaxsw 305419896, %mm3
+ pmaxsw 0x12345678,%mm3
+
+// CHECK: pmaxsw %mm3, %mm3
+ pmaxsw %mm3,%mm3
+
+// CHECK: pmaxsw 3735928559(%ebx,%ecx,8), %xmm5
+ pmaxsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxsw 69, %xmm5
+ pmaxsw 0x45,%xmm5
+
+// CHECK: pmaxsw 32493, %xmm5
+ pmaxsw 0x7eed,%xmm5
+
+// CHECK: pmaxsw 3133065982, %xmm5
+ pmaxsw 0xbabecafe,%xmm5
+
+// CHECK: pmaxsw 305419896, %xmm5
+ pmaxsw 0x12345678,%xmm5
+
+// CHECK: pmaxsw %xmm5, %xmm5
+ pmaxsw %xmm5,%xmm5
+
+// CHECK: pmaxub 3735928559(%ebx,%ecx,8), %mm3
+ pmaxub 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaxub 69, %mm3
+ pmaxub 0x45,%mm3
+
+// CHECK: pmaxub 32493, %mm3
+ pmaxub 0x7eed,%mm3
+
+// CHECK: pmaxub 3133065982, %mm3
+ pmaxub 0xbabecafe,%mm3
+
+// CHECK: pmaxub 305419896, %mm3
+ pmaxub 0x12345678,%mm3
+
+// CHECK: pmaxub %mm3, %mm3
+ pmaxub %mm3,%mm3
+
+// CHECK: pmaxub 3735928559(%ebx,%ecx,8), %xmm5
+ pmaxub 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxub 69, %xmm5
+ pmaxub 0x45,%xmm5
+
+// CHECK: pmaxub 32493, %xmm5
+ pmaxub 0x7eed,%xmm5
+
+// CHECK: pmaxub 3133065982, %xmm5
+ pmaxub 0xbabecafe,%xmm5
+
+// CHECK: pmaxub 305419896, %xmm5
+ pmaxub 0x12345678,%xmm5
+
+// CHECK: pmaxub %xmm5, %xmm5
+ pmaxub %xmm5,%xmm5
+
+// CHECK: pminsw 3735928559(%ebx,%ecx,8), %mm3
+ pminsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pminsw 69, %mm3
+ pminsw 0x45,%mm3
+
+// CHECK: pminsw 32493, %mm3
+ pminsw 0x7eed,%mm3
+
+// CHECK: pminsw 3133065982, %mm3
+ pminsw 0xbabecafe,%mm3
+
+// CHECK: pminsw 305419896, %mm3
+ pminsw 0x12345678,%mm3
+
+// CHECK: pminsw %mm3, %mm3
+ pminsw %mm3,%mm3
+
+// CHECK: pminsw 3735928559(%ebx,%ecx,8), %xmm5
+ pminsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminsw 69, %xmm5
+ pminsw 0x45,%xmm5
+
+// CHECK: pminsw 32493, %xmm5
+ pminsw 0x7eed,%xmm5
+
+// CHECK: pminsw 3133065982, %xmm5
+ pminsw 0xbabecafe,%xmm5
+
+// CHECK: pminsw 305419896, %xmm5
+ pminsw 0x12345678,%xmm5
+
+// CHECK: pminsw %xmm5, %xmm5
+ pminsw %xmm5,%xmm5
+
+// CHECK: pminub 3735928559(%ebx,%ecx,8), %mm3
+ pminub 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pminub 69, %mm3
+ pminub 0x45,%mm3
+
+// CHECK: pminub 32493, %mm3
+ pminub 0x7eed,%mm3
+
+// CHECK: pminub 3133065982, %mm3
+ pminub 0xbabecafe,%mm3
+
+// CHECK: pminub 305419896, %mm3
+ pminub 0x12345678,%mm3
+
+// CHECK: pminub %mm3, %mm3
+ pminub %mm3,%mm3
+
+// CHECK: pminub 3735928559(%ebx,%ecx,8), %xmm5
+ pminub 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminub 69, %xmm5
+ pminub 0x45,%xmm5
+
+// CHECK: pminub 32493, %xmm5
+ pminub 0x7eed,%xmm5
+
+// CHECK: pminub 3133065982, %xmm5
+ pminub 0xbabecafe,%xmm5
+
+// CHECK: pminub 305419896, %xmm5
+ pminub 0x12345678,%xmm5
+
+// CHECK: pminub %xmm5, %xmm5
+ pminub %xmm5,%xmm5
+
+// CHECK: pmovmskb %mm3, %ecx
+ pmovmskb %mm3,%ecx
+
+// CHECK: pmovmskb %xmm5, %ecx
+ pmovmskb %xmm5,%ecx
+
+// CHECK: pmulhuw 3735928559(%ebx,%ecx,8), %mm3
+ pmulhuw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmulhuw 69, %mm3
+ pmulhuw 0x45,%mm3
+
+// CHECK: pmulhuw 32493, %mm3
+ pmulhuw 0x7eed,%mm3
+
+// CHECK: pmulhuw 3133065982, %mm3
+ pmulhuw 0xbabecafe,%mm3
+
+// CHECK: pmulhuw 305419896, %mm3
+ pmulhuw 0x12345678,%mm3
+
+// CHECK: pmulhuw %mm3, %mm3
+ pmulhuw %mm3,%mm3
+
+// CHECK: pmulhuw 3735928559(%ebx,%ecx,8), %xmm5
+ pmulhuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulhuw 69, %xmm5
+ pmulhuw 0x45,%xmm5
+
+// CHECK: pmulhuw 32493, %xmm5
+ pmulhuw 0x7eed,%xmm5
+
+// CHECK: pmulhuw 3133065982, %xmm5
+ pmulhuw 0xbabecafe,%xmm5
+
+// CHECK: pmulhuw 305419896, %xmm5
+ pmulhuw 0x12345678,%xmm5
+
+// CHECK: pmulhuw %xmm5, %xmm5
+ pmulhuw %xmm5,%xmm5
+
+// CHECK: prefetchnta 3735928559(%ebx,%ecx,8)
+ prefetchnta 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetchnta 32493
+ prefetchnta 0x7eed
+
+// CHECK: prefetchnta 3133065982
+ prefetchnta 0xbabecafe
+
+// CHECK: prefetchnta 305419896
+ prefetchnta 0x12345678
+
+// CHECK: prefetcht0 3735928559(%ebx,%ecx,8)
+ prefetcht0 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht0 32493
+ prefetcht0 0x7eed
+
+// CHECK: prefetcht0 3133065982
+ prefetcht0 0xbabecafe
+
+// CHECK: prefetcht0 305419896
+ prefetcht0 0x12345678
+
+// CHECK: prefetcht1 3735928559(%ebx,%ecx,8)
+ prefetcht1 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht1 32493
+ prefetcht1 0x7eed
+
+// CHECK: prefetcht1 3133065982
+ prefetcht1 0xbabecafe
+
+// CHECK: prefetcht1 305419896
+ prefetcht1 0x12345678
+
+// CHECK: prefetcht2 3735928559(%ebx,%ecx,8)
+ prefetcht2 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht2 32493
+ prefetcht2 0x7eed
+
+// CHECK: prefetcht2 3133065982
+ prefetcht2 0xbabecafe
+
+// CHECK: prefetcht2 305419896
+ prefetcht2 0x12345678
+
+// CHECK: psadbw 3735928559(%ebx,%ecx,8), %mm3
+ psadbw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psadbw 69, %mm3
+ psadbw 0x45,%mm3
+
+// CHECK: psadbw 32493, %mm3
+ psadbw 0x7eed,%mm3
+
+// CHECK: psadbw 3133065982, %mm3
+ psadbw 0xbabecafe,%mm3
+
+// CHECK: psadbw 305419896, %mm3
+ psadbw 0x12345678,%mm3
+
+// CHECK: psadbw %mm3, %mm3
+ psadbw %mm3,%mm3
+
+// CHECK: psadbw 3735928559(%ebx,%ecx,8), %xmm5
+ psadbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psadbw 69, %xmm5
+ psadbw 0x45,%xmm5
+
+// CHECK: psadbw 32493, %xmm5
+ psadbw 0x7eed,%xmm5
+
+// CHECK: psadbw 3133065982, %xmm5
+ psadbw 0xbabecafe,%xmm5
+
+// CHECK: psadbw 305419896, %xmm5
+ psadbw 0x12345678,%xmm5
+
+// CHECK: psadbw %xmm5, %xmm5
+ psadbw %xmm5,%xmm5
+
+// CHECK: rcpps 3735928559(%ebx,%ecx,8), %xmm5
+ rcpps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rcpps 69, %xmm5
+ rcpps 0x45,%xmm5
+
+// CHECK: rcpps 32493, %xmm5
+ rcpps 0x7eed,%xmm5
+
+// CHECK: rcpps 3133065982, %xmm5
+ rcpps 0xbabecafe,%xmm5
+
+// CHECK: rcpps 305419896, %xmm5
+ rcpps 0x12345678,%xmm5
+
+// CHECK: rcpps %xmm5, %xmm5
+ rcpps %xmm5,%xmm5
+
+// CHECK: rcpss 3735928559(%ebx,%ecx,8), %xmm5
+ rcpss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rcpss 69, %xmm5
+ rcpss 0x45,%xmm5
+
+// CHECK: rcpss 32493, %xmm5
+ rcpss 0x7eed,%xmm5
+
+// CHECK: rcpss 3133065982, %xmm5
+ rcpss 0xbabecafe,%xmm5
+
+// CHECK: rcpss 305419896, %xmm5
+ rcpss 0x12345678,%xmm5
+
+// CHECK: rcpss %xmm5, %xmm5
+ rcpss %xmm5,%xmm5
+
+// CHECK: rsqrtps 3735928559(%ebx,%ecx,8), %xmm5
+ rsqrtps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rsqrtps 69, %xmm5
+ rsqrtps 0x45,%xmm5
+
+// CHECK: rsqrtps 32493, %xmm5
+ rsqrtps 0x7eed,%xmm5
+
+// CHECK: rsqrtps 3133065982, %xmm5
+ rsqrtps 0xbabecafe,%xmm5
+
+// CHECK: rsqrtps 305419896, %xmm5
+ rsqrtps 0x12345678,%xmm5
+
+// CHECK: rsqrtps %xmm5, %xmm5
+ rsqrtps %xmm5,%xmm5
+
+// CHECK: rsqrtss 3735928559(%ebx,%ecx,8), %xmm5
+ rsqrtss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rsqrtss 69, %xmm5
+ rsqrtss 0x45,%xmm5
+
+// CHECK: rsqrtss 32493, %xmm5
+ rsqrtss 0x7eed,%xmm5
+
+// CHECK: rsqrtss 3133065982, %xmm5
+ rsqrtss 0xbabecafe,%xmm5
+
+// CHECK: rsqrtss 305419896, %xmm5
+ rsqrtss 0x12345678,%xmm5
+
+// CHECK: rsqrtss %xmm5, %xmm5
+ rsqrtss %xmm5,%xmm5
+
+// CHECK: sfence
+ sfence
+
+// CHECK: sqrtps 3735928559(%ebx,%ecx,8), %xmm5
+ sqrtps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtps 69, %xmm5
+ sqrtps 0x45,%xmm5
+
+// CHECK: sqrtps 32493, %xmm5
+ sqrtps 0x7eed,%xmm5
+
+// CHECK: sqrtps 3133065982, %xmm5
+ sqrtps 0xbabecafe,%xmm5
+
+// CHECK: sqrtps 305419896, %xmm5
+ sqrtps 0x12345678,%xmm5
+
+// CHECK: sqrtps %xmm5, %xmm5
+ sqrtps %xmm5,%xmm5
+
+// CHECK: sqrtss 3735928559(%ebx,%ecx,8), %xmm5
+ sqrtss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtss 69, %xmm5
+ sqrtss 0x45,%xmm5
+
+// CHECK: sqrtss 32493, %xmm5
+ sqrtss 0x7eed,%xmm5
+
+// CHECK: sqrtss 3133065982, %xmm5
+ sqrtss 0xbabecafe,%xmm5
+
+// CHECK: sqrtss 305419896, %xmm5
+ sqrtss 0x12345678,%xmm5
+
+// CHECK: sqrtss %xmm5, %xmm5
+ sqrtss %xmm5,%xmm5
+
+// CHECK: stmxcsr 3735928559(%ebx,%ecx,8)
+ stmxcsr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: stmxcsr 32493
+ stmxcsr 0x7eed
+
+// CHECK: stmxcsr 3133065982
+ stmxcsr 0xbabecafe
+
+// CHECK: stmxcsr 305419896
+ stmxcsr 0x12345678
+
+// CHECK: subps 3735928559(%ebx,%ecx,8), %xmm5
+ subps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subps 69, %xmm5
+ subps 0x45,%xmm5
+
+// CHECK: subps 32493, %xmm5
+ subps 0x7eed,%xmm5
+
+// CHECK: subps 3133065982, %xmm5
+ subps 0xbabecafe,%xmm5
+
+// CHECK: subps 305419896, %xmm5
+ subps 0x12345678,%xmm5
+
+// CHECK: subps %xmm5, %xmm5
+ subps %xmm5,%xmm5
+
+// CHECK: subss 3735928559(%ebx,%ecx,8), %xmm5
+ subss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subss 69, %xmm5
+ subss 0x45,%xmm5
+
+// CHECK: subss 32493, %xmm5
+ subss 0x7eed,%xmm5
+
+// CHECK: subss 3133065982, %xmm5
+ subss 0xbabecafe,%xmm5
+
+// CHECK: subss 305419896, %xmm5
+ subss 0x12345678,%xmm5
+
+// CHECK: subss %xmm5, %xmm5
+ subss %xmm5,%xmm5
+
+// CHECK: ucomiss 3735928559(%ebx,%ecx,8), %xmm5
+ ucomiss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ucomiss 69, %xmm5
+ ucomiss 0x45,%xmm5
+
+// CHECK: ucomiss 32493, %xmm5
+ ucomiss 0x7eed,%xmm5
+
+// CHECK: ucomiss 3133065982, %xmm5
+ ucomiss 0xbabecafe,%xmm5
+
+// CHECK: ucomiss 305419896, %xmm5
+ ucomiss 0x12345678,%xmm5
+
+// CHECK: ucomiss %xmm5, %xmm5
+ ucomiss %xmm5,%xmm5
+
+// CHECK: unpckhps 3735928559(%ebx,%ecx,8), %xmm5
+ unpckhps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpckhps 69, %xmm5
+ unpckhps 0x45,%xmm5
+
+// CHECK: unpckhps 32493, %xmm5
+ unpckhps 0x7eed,%xmm5
+
+// CHECK: unpckhps 3133065982, %xmm5
+ unpckhps 0xbabecafe,%xmm5
+
+// CHECK: unpckhps 305419896, %xmm5
+ unpckhps 0x12345678,%xmm5
+
+// CHECK: unpckhps %xmm5, %xmm5
+ unpckhps %xmm5,%xmm5
+
+// CHECK: unpcklps 3735928559(%ebx,%ecx,8), %xmm5
+ unpcklps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpcklps 69, %xmm5
+ unpcklps 0x45,%xmm5
+
+// CHECK: unpcklps 32493, %xmm5
+ unpcklps 0x7eed,%xmm5
+
+// CHECK: unpcklps 3133065982, %xmm5
+ unpcklps 0xbabecafe,%xmm5
+
+// CHECK: unpcklps 305419896, %xmm5
+ unpcklps 0x12345678,%xmm5
+
+// CHECK: unpcklps %xmm5, %xmm5
+ unpcklps %xmm5,%xmm5
+
+// CHECK: xorps 3735928559(%ebx,%ecx,8), %xmm5
+ xorps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: xorps 69, %xmm5
+ xorps 0x45,%xmm5
+
+// CHECK: xorps 32493, %xmm5
+ xorps 0x7eed,%xmm5
+
+// CHECK: xorps 3133065982, %xmm5
+ xorps 0xbabecafe,%xmm5
+
+// CHECK: xorps 305419896, %xmm5
+ xorps 0x12345678,%xmm5
+
+// CHECK: xorps %xmm5, %xmm5
+ xorps %xmm5,%xmm5
+
+// CHECK: addpd 3735928559(%ebx,%ecx,8), %xmm5
+ addpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addpd 69, %xmm5
+ addpd 0x45,%xmm5
+
+// CHECK: addpd 32493, %xmm5
+ addpd 0x7eed,%xmm5
+
+// CHECK: addpd 3133065982, %xmm5
+ addpd 0xbabecafe,%xmm5
+
+// CHECK: addpd 305419896, %xmm5
+ addpd 0x12345678,%xmm5
+
+// CHECK: addpd %xmm5, %xmm5
+ addpd %xmm5,%xmm5
+
+// CHECK: addsd 3735928559(%ebx,%ecx,8), %xmm5
+ addsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addsd 69, %xmm5
+ addsd 0x45,%xmm5
+
+// CHECK: addsd 32493, %xmm5
+ addsd 0x7eed,%xmm5
+
+// CHECK: addsd 3133065982, %xmm5
+ addsd 0xbabecafe,%xmm5
+
+// CHECK: addsd 305419896, %xmm5
+ addsd 0x12345678,%xmm5
+
+// CHECK: addsd %xmm5, %xmm5
+ addsd %xmm5,%xmm5
+
+// CHECK: andnpd 3735928559(%ebx,%ecx,8), %xmm5
+ andnpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andnpd 69, %xmm5
+ andnpd 0x45,%xmm5
+
+// CHECK: andnpd 32493, %xmm5
+ andnpd 0x7eed,%xmm5
+
+// CHECK: andnpd 3133065982, %xmm5
+ andnpd 0xbabecafe,%xmm5
+
+// CHECK: andnpd 305419896, %xmm5
+ andnpd 0x12345678,%xmm5
+
+// CHECK: andnpd %xmm5, %xmm5
+ andnpd %xmm5,%xmm5
+
+// CHECK: andpd 3735928559(%ebx,%ecx,8), %xmm5
+ andpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andpd 69, %xmm5
+ andpd 0x45,%xmm5
+
+// CHECK: andpd 32493, %xmm5
+ andpd 0x7eed,%xmm5
+
+// CHECK: andpd 3133065982, %xmm5
+ andpd 0xbabecafe,%xmm5
+
+// CHECK: andpd 305419896, %xmm5
+ andpd 0x12345678,%xmm5
+
+// CHECK: andpd %xmm5, %xmm5
+ andpd %xmm5,%xmm5
+
+// CHECK: comisd 3735928559(%ebx,%ecx,8), %xmm5
+ comisd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: comisd 69, %xmm5
+ comisd 0x45,%xmm5
+
+// CHECK: comisd 32493, %xmm5
+ comisd 0x7eed,%xmm5
+
+// CHECK: comisd 3133065982, %xmm5
+ comisd 0xbabecafe,%xmm5
+
+// CHECK: comisd 305419896, %xmm5
+ comisd 0x12345678,%xmm5
+
+// CHECK: comisd %xmm5, %xmm5
+ comisd %xmm5,%xmm5
+
+// CHECK: cvtpi2pd 3735928559(%ebx,%ecx,8), %xmm5
+ cvtpi2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpi2pd 69, %xmm5
+ cvtpi2pd 0x45,%xmm5
+
+// CHECK: cvtpi2pd 32493, %xmm5
+ cvtpi2pd 0x7eed,%xmm5
+
+// CHECK: cvtpi2pd 3133065982, %xmm5
+ cvtpi2pd 0xbabecafe,%xmm5
+
+// CHECK: cvtpi2pd 305419896, %xmm5
+ cvtpi2pd 0x12345678,%xmm5
+
+// CHECK: cvtpi2pd %mm3, %xmm5
+ cvtpi2pd %mm3,%xmm5
+
+// CHECK: cvtsi2sd %ecx, %xmm5
+ cvtsi2sd %ecx,%xmm5
+
+// CHECK: cvtsi2sd 3735928559(%ebx,%ecx,8), %xmm5
+ cvtsi2sd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtsi2sd 69, %xmm5
+ cvtsi2sd 0x45,%xmm5
+
+// CHECK: cvtsi2sd 32493, %xmm5
+ cvtsi2sd 0x7eed,%xmm5
+
+// CHECK: cvtsi2sd 3133065982, %xmm5
+ cvtsi2sd 0xbabecafe,%xmm5
+
+// CHECK: cvtsi2sd 305419896, %xmm5
+ cvtsi2sd 0x12345678,%xmm5
+
+// CHECK: divpd 3735928559(%ebx,%ecx,8), %xmm5
+ divpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divpd 69, %xmm5
+ divpd 0x45,%xmm5
+
+// CHECK: divpd 32493, %xmm5
+ divpd 0x7eed,%xmm5
+
+// CHECK: divpd 3133065982, %xmm5
+ divpd 0xbabecafe,%xmm5
+
+// CHECK: divpd 305419896, %xmm5
+ divpd 0x12345678,%xmm5
+
+// CHECK: divpd %xmm5, %xmm5
+ divpd %xmm5,%xmm5
+
+// CHECK: divsd 3735928559(%ebx,%ecx,8), %xmm5
+ divsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divsd 69, %xmm5
+ divsd 0x45,%xmm5
+
+// CHECK: divsd 32493, %xmm5
+ divsd 0x7eed,%xmm5
+
+// CHECK: divsd 3133065982, %xmm5
+ divsd 0xbabecafe,%xmm5
+
+// CHECK: divsd 305419896, %xmm5
+ divsd 0x12345678,%xmm5
+
+// CHECK: divsd %xmm5, %xmm5
+ divsd %xmm5,%xmm5
+
+// CHECK: maxpd 3735928559(%ebx,%ecx,8), %xmm5
+ maxpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxpd 69, %xmm5
+ maxpd 0x45,%xmm5
+
+// CHECK: maxpd 32493, %xmm5
+ maxpd 0x7eed,%xmm5
+
+// CHECK: maxpd 3133065982, %xmm5
+ maxpd 0xbabecafe,%xmm5
+
+// CHECK: maxpd 305419896, %xmm5
+ maxpd 0x12345678,%xmm5
+
+// CHECK: maxpd %xmm5, %xmm5
+ maxpd %xmm5,%xmm5
+
+// CHECK: maxsd 3735928559(%ebx,%ecx,8), %xmm5
+ maxsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxsd 69, %xmm5
+ maxsd 0x45,%xmm5
+
+// CHECK: maxsd 32493, %xmm5
+ maxsd 0x7eed,%xmm5
+
+// CHECK: maxsd 3133065982, %xmm5
+ maxsd 0xbabecafe,%xmm5
+
+// CHECK: maxsd 305419896, %xmm5
+ maxsd 0x12345678,%xmm5
+
+// CHECK: maxsd %xmm5, %xmm5
+ maxsd %xmm5,%xmm5
+
+// CHECK: minpd 3735928559(%ebx,%ecx,8), %xmm5
+ minpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minpd 69, %xmm5
+ minpd 0x45,%xmm5
+
+// CHECK: minpd 32493, %xmm5
+ minpd 0x7eed,%xmm5
+
+// CHECK: minpd 3133065982, %xmm5
+ minpd 0xbabecafe,%xmm5
+
+// CHECK: minpd 305419896, %xmm5
+ minpd 0x12345678,%xmm5
+
+// CHECK: minpd %xmm5, %xmm5
+ minpd %xmm5,%xmm5
+
+// CHECK: minsd 3735928559(%ebx,%ecx,8), %xmm5
+ minsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minsd 69, %xmm5
+ minsd 0x45,%xmm5
+
+// CHECK: minsd 32493, %xmm5
+ minsd 0x7eed,%xmm5
+
+// CHECK: minsd 3133065982, %xmm5
+ minsd 0xbabecafe,%xmm5
+
+// CHECK: minsd 305419896, %xmm5
+ minsd 0x12345678,%xmm5
+
+// CHECK: minsd %xmm5, %xmm5
+ minsd %xmm5,%xmm5
+
+// CHECK: movapd 3735928559(%ebx,%ecx,8), %xmm5
+ movapd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movapd 69, %xmm5
+ movapd 0x45,%xmm5
+
+// CHECK: movapd 32493, %xmm5
+ movapd 0x7eed,%xmm5
+
+// CHECK: movapd 3133065982, %xmm5
+ movapd 0xbabecafe,%xmm5
+
+// CHECK: movapd 305419896, %xmm5
+ movapd 0x12345678,%xmm5
+
+// CHECK: movapd %xmm5, %xmm5
+ movapd %xmm5,%xmm5
+
+// CHECK: movapd %xmm5, 3735928559(%ebx,%ecx,8)
+ movapd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movapd %xmm5, 69
+ movapd %xmm5,0x45
+
+// CHECK: movapd %xmm5, 32493
+ movapd %xmm5,0x7eed
+
+// CHECK: movapd %xmm5, 3133065982
+ movapd %xmm5,0xbabecafe
+
+// CHECK: movapd %xmm5, 305419896
+ movapd %xmm5,0x12345678
+
+// CHECK: movapd %xmm5, %xmm5
+ movapd %xmm5,%xmm5
+
+// CHECK: movhpd 3735928559(%ebx,%ecx,8), %xmm5
+ movhpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movhpd 69, %xmm5
+ movhpd 0x45,%xmm5
+
+// CHECK: movhpd 32493, %xmm5
+ movhpd 0x7eed,%xmm5
+
+// CHECK: movhpd 3133065982, %xmm5
+ movhpd 0xbabecafe,%xmm5
+
+// CHECK: movhpd 305419896, %xmm5
+ movhpd 0x12345678,%xmm5
+
+// CHECK: movhpd %xmm5, 3735928559(%ebx,%ecx,8)
+ movhpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movhpd %xmm5, 69
+ movhpd %xmm5,0x45
+
+// CHECK: movhpd %xmm5, 32493
+ movhpd %xmm5,0x7eed
+
+// CHECK: movhpd %xmm5, 3133065982
+ movhpd %xmm5,0xbabecafe
+
+// CHECK: movhpd %xmm5, 305419896
+ movhpd %xmm5,0x12345678
+
+// CHECK: movlpd 3735928559(%ebx,%ecx,8), %xmm5
+ movlpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movlpd 69, %xmm5
+ movlpd 0x45,%xmm5
+
+// CHECK: movlpd 32493, %xmm5
+ movlpd 0x7eed,%xmm5
+
+// CHECK: movlpd 3133065982, %xmm5
+ movlpd 0xbabecafe,%xmm5
+
+// CHECK: movlpd 305419896, %xmm5
+ movlpd 0x12345678,%xmm5
+
+// CHECK: movlpd %xmm5, 3735928559(%ebx,%ecx,8)
+ movlpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movlpd %xmm5, 69
+ movlpd %xmm5,0x45
+
+// CHECK: movlpd %xmm5, 32493
+ movlpd %xmm5,0x7eed
+
+// CHECK: movlpd %xmm5, 3133065982
+ movlpd %xmm5,0xbabecafe
+
+// CHECK: movlpd %xmm5, 305419896
+ movlpd %xmm5,0x12345678
+
+// CHECK: movmskpd %xmm5, %ecx
+ movmskpd %xmm5,%ecx
+
+// CHECK: movntpd %xmm5, 3735928559(%ebx,%ecx,8)
+ movntpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntpd %xmm5, 69
+ movntpd %xmm5,0x45
+
+// CHECK: movntpd %xmm5, 32493
+ movntpd %xmm5,0x7eed
+
+// CHECK: movntpd %xmm5, 3133065982
+ movntpd %xmm5,0xbabecafe
+
+// CHECK: movntpd %xmm5, 305419896
+ movntpd %xmm5,0x12345678
+
+// CHECK: movsd 3735928559(%ebx,%ecx,8), %xmm5
+ movsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movsd 69, %xmm5
+ movsd 0x45,%xmm5
+
+// CHECK: movsd 32493, %xmm5
+ movsd 0x7eed,%xmm5
+
+// CHECK: movsd 3133065982, %xmm5
+ movsd 0xbabecafe,%xmm5
+
+// CHECK: movsd 305419896, %xmm5
+ movsd 0x12345678,%xmm5
+
+// CHECK: movsd %xmm5, %xmm5
+ movsd %xmm5,%xmm5
+
+// CHECK: movsd %xmm5, 3735928559(%ebx,%ecx,8)
+ movsd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movsd %xmm5, 69
+ movsd %xmm5,0x45
+
+// CHECK: movsd %xmm5, 32493
+ movsd %xmm5,0x7eed
+
+// CHECK: movsd %xmm5, 3133065982
+ movsd %xmm5,0xbabecafe
+
+// CHECK: movsd %xmm5, 305419896
+ movsd %xmm5,0x12345678
+
+// CHECK: movsd %xmm5, %xmm5
+ movsd %xmm5,%xmm5
+
+// CHECK: movupd 3735928559(%ebx,%ecx,8), %xmm5
+ movupd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movupd 69, %xmm5
+ movupd 0x45,%xmm5
+
+// CHECK: movupd 32493, %xmm5
+ movupd 0x7eed,%xmm5
+
+// CHECK: movupd 3133065982, %xmm5
+ movupd 0xbabecafe,%xmm5
+
+// CHECK: movupd 305419896, %xmm5
+ movupd 0x12345678,%xmm5
+
+// CHECK: movupd %xmm5, %xmm5
+ movupd %xmm5,%xmm5
+
+// CHECK: movupd %xmm5, 3735928559(%ebx,%ecx,8)
+ movupd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movupd %xmm5, 69
+ movupd %xmm5,0x45
+
+// CHECK: movupd %xmm5, 32493
+ movupd %xmm5,0x7eed
+
+// CHECK: movupd %xmm5, 3133065982
+ movupd %xmm5,0xbabecafe
+
+// CHECK: movupd %xmm5, 305419896
+ movupd %xmm5,0x12345678
+
+// CHECK: movupd %xmm5, %xmm5
+ movupd %xmm5,%xmm5
+
+// CHECK: mulpd 3735928559(%ebx,%ecx,8), %xmm5
+ mulpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulpd 69, %xmm5
+ mulpd 0x45,%xmm5
+
+// CHECK: mulpd 32493, %xmm5
+ mulpd 0x7eed,%xmm5
+
+// CHECK: mulpd 3133065982, %xmm5
+ mulpd 0xbabecafe,%xmm5
+
+// CHECK: mulpd 305419896, %xmm5
+ mulpd 0x12345678,%xmm5
+
+// CHECK: mulpd %xmm5, %xmm5
+ mulpd %xmm5,%xmm5
+
+// CHECK: mulsd 3735928559(%ebx,%ecx,8), %xmm5
+ mulsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulsd 69, %xmm5
+ mulsd 0x45,%xmm5
+
+// CHECK: mulsd 32493, %xmm5
+ mulsd 0x7eed,%xmm5
+
+// CHECK: mulsd 3133065982, %xmm5
+ mulsd 0xbabecafe,%xmm5
+
+// CHECK: mulsd 305419896, %xmm5
+ mulsd 0x12345678,%xmm5
+
+// CHECK: mulsd %xmm5, %xmm5
+ mulsd %xmm5,%xmm5
+
+// CHECK: orpd 3735928559(%ebx,%ecx,8), %xmm5
+ orpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: orpd 69, %xmm5
+ orpd 0x45,%xmm5
+
+// CHECK: orpd 32493, %xmm5
+ orpd 0x7eed,%xmm5
+
+// CHECK: orpd 3133065982, %xmm5
+ orpd 0xbabecafe,%xmm5
+
+// CHECK: orpd 305419896, %xmm5
+ orpd 0x12345678,%xmm5
+
+// CHECK: orpd %xmm5, %xmm5
+ orpd %xmm5,%xmm5
+
+// CHECK: sqrtpd 3735928559(%ebx,%ecx,8), %xmm5
+ sqrtpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtpd 69, %xmm5
+ sqrtpd 0x45,%xmm5
+
+// CHECK: sqrtpd 32493, %xmm5
+ sqrtpd 0x7eed,%xmm5
+
+// CHECK: sqrtpd 3133065982, %xmm5
+ sqrtpd 0xbabecafe,%xmm5
+
+// CHECK: sqrtpd 305419896, %xmm5
+ sqrtpd 0x12345678,%xmm5
+
+// CHECK: sqrtpd %xmm5, %xmm5
+ sqrtpd %xmm5,%xmm5
+
+// CHECK: sqrtsd 3735928559(%ebx,%ecx,8), %xmm5
+ sqrtsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtsd 69, %xmm5
+ sqrtsd 0x45,%xmm5
+
+// CHECK: sqrtsd 32493, %xmm5
+ sqrtsd 0x7eed,%xmm5
+
+// CHECK: sqrtsd 3133065982, %xmm5
+ sqrtsd 0xbabecafe,%xmm5
+
+// CHECK: sqrtsd 305419896, %xmm5
+ sqrtsd 0x12345678,%xmm5
+
+// CHECK: sqrtsd %xmm5, %xmm5
+ sqrtsd %xmm5,%xmm5
+
+// CHECK: subpd 3735928559(%ebx,%ecx,8), %xmm5
+ subpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subpd 69, %xmm5
+ subpd 0x45,%xmm5
+
+// CHECK: subpd 32493, %xmm5
+ subpd 0x7eed,%xmm5
+
+// CHECK: subpd 3133065982, %xmm5
+ subpd 0xbabecafe,%xmm5
+
+// CHECK: subpd 305419896, %xmm5
+ subpd 0x12345678,%xmm5
+
+// CHECK: subpd %xmm5, %xmm5
+ subpd %xmm5,%xmm5
+
+// CHECK: subsd 3735928559(%ebx,%ecx,8), %xmm5
+ subsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subsd 69, %xmm5
+ subsd 0x45,%xmm5
+
+// CHECK: subsd 32493, %xmm5
+ subsd 0x7eed,%xmm5
+
+// CHECK: subsd 3133065982, %xmm5
+ subsd 0xbabecafe,%xmm5
+
+// CHECK: subsd 305419896, %xmm5
+ subsd 0x12345678,%xmm5
+
+// CHECK: subsd %xmm5, %xmm5
+ subsd %xmm5,%xmm5
+
+// CHECK: ucomisd 3735928559(%ebx,%ecx,8), %xmm5
+ ucomisd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ucomisd 69, %xmm5
+ ucomisd 0x45,%xmm5
+
+// CHECK: ucomisd 32493, %xmm5
+ ucomisd 0x7eed,%xmm5
+
+// CHECK: ucomisd 3133065982, %xmm5
+ ucomisd 0xbabecafe,%xmm5
+
+// CHECK: ucomisd 305419896, %xmm5
+ ucomisd 0x12345678,%xmm5
+
+// CHECK: ucomisd %xmm5, %xmm5
+ ucomisd %xmm5,%xmm5
+
+// CHECK: unpckhpd 3735928559(%ebx,%ecx,8), %xmm5
+ unpckhpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpckhpd 69, %xmm5
+ unpckhpd 0x45,%xmm5
+
+// CHECK: unpckhpd 32493, %xmm5
+ unpckhpd 0x7eed,%xmm5
+
+// CHECK: unpckhpd 3133065982, %xmm5
+ unpckhpd 0xbabecafe,%xmm5
+
+// CHECK: unpckhpd 305419896, %xmm5
+ unpckhpd 0x12345678,%xmm5
+
+// CHECK: unpckhpd %xmm5, %xmm5
+ unpckhpd %xmm5,%xmm5
+
+// CHECK: unpcklpd 3735928559(%ebx,%ecx,8), %xmm5
+ unpcklpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpcklpd 69, %xmm5
+ unpcklpd 0x45,%xmm5
+
+// CHECK: unpcklpd 32493, %xmm5
+ unpcklpd 0x7eed,%xmm5
+
+// CHECK: unpcklpd 3133065982, %xmm5
+ unpcklpd 0xbabecafe,%xmm5
+
+// CHECK: unpcklpd 305419896, %xmm5
+ unpcklpd 0x12345678,%xmm5
+
+// CHECK: unpcklpd %xmm5, %xmm5
+ unpcklpd %xmm5,%xmm5
+
+// CHECK: xorpd 3735928559(%ebx,%ecx,8), %xmm5
+ xorpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: xorpd 69, %xmm5
+ xorpd 0x45,%xmm5
+
+// CHECK: xorpd 32493, %xmm5
+ xorpd 0x7eed,%xmm5
+
+// CHECK: xorpd 3133065982, %xmm5
+ xorpd 0xbabecafe,%xmm5
+
+// CHECK: xorpd 305419896, %xmm5
+ xorpd 0x12345678,%xmm5
+
+// CHECK: xorpd %xmm5, %xmm5
+ xorpd %xmm5,%xmm5
+
+// CHECK: cvtdq2pd 3735928559(%ebx,%ecx,8), %xmm5
+ cvtdq2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtdq2pd 69, %xmm5
+ cvtdq2pd 0x45,%xmm5
+
+// CHECK: cvtdq2pd 32493, %xmm5
+ cvtdq2pd 0x7eed,%xmm5
+
+// CHECK: cvtdq2pd 3133065982, %xmm5
+ cvtdq2pd 0xbabecafe,%xmm5
+
+// CHECK: cvtdq2pd 305419896, %xmm5
+ cvtdq2pd 0x12345678,%xmm5
+
+// CHECK: cvtdq2pd %xmm5, %xmm5
+ cvtdq2pd %xmm5,%xmm5
+
+// CHECK: cvtpd2dq 3735928559(%ebx,%ecx,8), %xmm5
+ cvtpd2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpd2dq 69, %xmm5
+ cvtpd2dq 0x45,%xmm5
+
+// CHECK: cvtpd2dq 32493, %xmm5
+ cvtpd2dq 0x7eed,%xmm5
+
+// CHECK: cvtpd2dq 3133065982, %xmm5
+ cvtpd2dq 0xbabecafe,%xmm5
+
+// CHECK: cvtpd2dq 305419896, %xmm5
+ cvtpd2dq 0x12345678,%xmm5
+
+// CHECK: cvtpd2dq %xmm5, %xmm5
+ cvtpd2dq %xmm5,%xmm5
+
+// CHECK: cvtdq2ps 3735928559(%ebx,%ecx,8), %xmm5
+ cvtdq2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtdq2ps 69, %xmm5
+ cvtdq2ps 0x45,%xmm5
+
+// CHECK: cvtdq2ps 32493, %xmm5
+ cvtdq2ps 0x7eed,%xmm5
+
+// CHECK: cvtdq2ps 3133065982, %xmm5
+ cvtdq2ps 0xbabecafe,%xmm5
+
+// CHECK: cvtdq2ps 305419896, %xmm5
+ cvtdq2ps 0x12345678,%xmm5
+
+// CHECK: cvtdq2ps %xmm5, %xmm5
+ cvtdq2ps %xmm5,%xmm5
+
+// CHECK: cvtpd2pi 3735928559(%ebx,%ecx,8), %mm3
+ cvtpd2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvtpd2pi 69, %mm3
+ cvtpd2pi 0x45,%mm3
+
+// CHECK: cvtpd2pi 32493, %mm3
+ cvtpd2pi 0x7eed,%mm3
+
+// CHECK: cvtpd2pi 3133065982, %mm3
+ cvtpd2pi 0xbabecafe,%mm3
+
+// CHECK: cvtpd2pi 305419896, %mm3
+ cvtpd2pi 0x12345678,%mm3
+
+// CHECK: cvtpd2pi %xmm5, %mm3
+ cvtpd2pi %xmm5,%mm3
+
+// CHECK: cvtpd2ps 3735928559(%ebx,%ecx,8), %xmm5
+ cvtpd2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpd2ps 69, %xmm5
+ cvtpd2ps 0x45,%xmm5
+
+// CHECK: cvtpd2ps 32493, %xmm5
+ cvtpd2ps 0x7eed,%xmm5
+
+// CHECK: cvtpd2ps 3133065982, %xmm5
+ cvtpd2ps 0xbabecafe,%xmm5
+
+// CHECK: cvtpd2ps 305419896, %xmm5
+ cvtpd2ps 0x12345678,%xmm5
+
+// CHECK: cvtpd2ps %xmm5, %xmm5
+ cvtpd2ps %xmm5,%xmm5
+
+// CHECK: cvtps2pd 3735928559(%ebx,%ecx,8), %xmm5
+ cvtps2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtps2pd 69, %xmm5
+ cvtps2pd 0x45,%xmm5
+
+// CHECK: cvtps2pd 32493, %xmm5
+ cvtps2pd 0x7eed,%xmm5
+
+// CHECK: cvtps2pd 3133065982, %xmm5
+ cvtps2pd 0xbabecafe,%xmm5
+
+// CHECK: cvtps2pd 305419896, %xmm5
+ cvtps2pd 0x12345678,%xmm5
+
+// CHECK: cvtps2pd %xmm5, %xmm5
+ cvtps2pd %xmm5,%xmm5
+
+// CHECK: cvtps2dq 3735928559(%ebx,%ecx,8), %xmm5
+ cvtps2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtps2dq 69, %xmm5
+ cvtps2dq 0x45,%xmm5
+
+// CHECK: cvtps2dq 32493, %xmm5
+ cvtps2dq 0x7eed,%xmm5
+
+// CHECK: cvtps2dq 3133065982, %xmm5
+ cvtps2dq 0xbabecafe,%xmm5
+
+// CHECK: cvtps2dq 305419896, %xmm5
+ cvtps2dq 0x12345678,%xmm5
+
+// CHECK: cvtps2dq %xmm5, %xmm5
+ cvtps2dq %xmm5,%xmm5
+
+// CHECK: cvtsd2ss 3735928559(%ebx,%ecx,8), %xmm5
+ cvtsd2ss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtsd2ss 69, %xmm5
+ cvtsd2ss 0x45,%xmm5
+
+// CHECK: cvtsd2ss 32493, %xmm5
+ cvtsd2ss 0x7eed,%xmm5
+
+// CHECK: cvtsd2ss 3133065982, %xmm5
+ cvtsd2ss 0xbabecafe,%xmm5
+
+// CHECK: cvtsd2ss 305419896, %xmm5
+ cvtsd2ss 0x12345678,%xmm5
+
+// CHECK: cvtsd2ss %xmm5, %xmm5
+ cvtsd2ss %xmm5,%xmm5
+
+// CHECK: cvtss2sd 3735928559(%ebx,%ecx,8), %xmm5
+ cvtss2sd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtss2sd 69, %xmm5
+ cvtss2sd 0x45,%xmm5
+
+// CHECK: cvtss2sd 32493, %xmm5
+ cvtss2sd 0x7eed,%xmm5
+
+// CHECK: cvtss2sd 3133065982, %xmm5
+ cvtss2sd 0xbabecafe,%xmm5
+
+// CHECK: cvtss2sd 305419896, %xmm5
+ cvtss2sd 0x12345678,%xmm5
+
+// CHECK: cvtss2sd %xmm5, %xmm5
+ cvtss2sd %xmm5,%xmm5
+
+// CHECK: cvttpd2pi 3735928559(%ebx,%ecx,8), %mm3
+ cvttpd2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvttpd2pi 69, %mm3
+ cvttpd2pi 0x45,%mm3
+
+// CHECK: cvttpd2pi 32493, %mm3
+ cvttpd2pi 0x7eed,%mm3
+
+// CHECK: cvttpd2pi 3133065982, %mm3
+ cvttpd2pi 0xbabecafe,%mm3
+
+// CHECK: cvttpd2pi 305419896, %mm3
+ cvttpd2pi 0x12345678,%mm3
+
+// CHECK: cvttpd2pi %xmm5, %mm3
+ cvttpd2pi %xmm5,%mm3
+
+// CHECK: cvttsd2si 3735928559(%ebx,%ecx,8), %ecx
+ cvttsd2si 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: cvttsd2si 69, %ecx
+ cvttsd2si 0x45,%ecx
+
+// CHECK: cvttsd2si 32493, %ecx
+ cvttsd2si 0x7eed,%ecx
+
+// CHECK: cvttsd2si 3133065982, %ecx
+ cvttsd2si 0xbabecafe,%ecx
+
+// CHECK: cvttsd2si 305419896, %ecx
+ cvttsd2si 0x12345678,%ecx
+
+// CHECK: cvttsd2si %xmm5, %ecx
+ cvttsd2si %xmm5,%ecx
+
+// CHECK: cvttps2dq 3735928559(%ebx,%ecx,8), %xmm5
+ cvttps2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvttps2dq 69, %xmm5
+ cvttps2dq 0x45,%xmm5
+
+// CHECK: cvttps2dq 32493, %xmm5
+ cvttps2dq 0x7eed,%xmm5
+
+// CHECK: cvttps2dq 3133065982, %xmm5
+ cvttps2dq 0xbabecafe,%xmm5
+
+// CHECK: cvttps2dq 305419896, %xmm5
+ cvttps2dq 0x12345678,%xmm5
+
+// CHECK: cvttps2dq %xmm5, %xmm5
+ cvttps2dq %xmm5,%xmm5
+
+// CHECK: maskmovdqu %xmm5, %xmm5
+ maskmovdqu %xmm5,%xmm5
+
+// CHECK: movdqa 3735928559(%ebx,%ecx,8), %xmm5
+ movdqa 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movdqa 69, %xmm5
+ movdqa 0x45,%xmm5
+
+// CHECK: movdqa 32493, %xmm5
+ movdqa 0x7eed,%xmm5
+
+// CHECK: movdqa 3133065982, %xmm5
+ movdqa 0xbabecafe,%xmm5
+
+// CHECK: movdqa 305419896, %xmm5
+ movdqa 0x12345678,%xmm5
+
+// CHECK: movdqa %xmm5, %xmm5
+ movdqa %xmm5,%xmm5
+
+// CHECK: movdqa %xmm5, 3735928559(%ebx,%ecx,8)
+ movdqa %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movdqa %xmm5, 69
+ movdqa %xmm5,0x45
+
+// CHECK: movdqa %xmm5, 32493
+ movdqa %xmm5,0x7eed
+
+// CHECK: movdqa %xmm5, 3133065982
+ movdqa %xmm5,0xbabecafe
+
+// CHECK: movdqa %xmm5, 305419896
+ movdqa %xmm5,0x12345678
+
+// CHECK: movdqa %xmm5, %xmm5
+ movdqa %xmm5,%xmm5
+
+// CHECK: movdqu 3735928559(%ebx,%ecx,8), %xmm5
+ movdqu 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movdqu 69, %xmm5
+ movdqu 0x45,%xmm5
+
+// CHECK: movdqu 32493, %xmm5
+ movdqu 0x7eed,%xmm5
+
+// CHECK: movdqu 3133065982, %xmm5
+ movdqu 0xbabecafe,%xmm5
+
+// CHECK: movdqu 305419896, %xmm5
+ movdqu 0x12345678,%xmm5
+
+// CHECK: movdqu %xmm5, 3735928559(%ebx,%ecx,8)
+ movdqu %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movdqu %xmm5, 69
+ movdqu %xmm5,0x45
+
+// CHECK: movdqu %xmm5, 32493
+ movdqu %xmm5,0x7eed
+
+// CHECK: movdqu %xmm5, 3133065982
+ movdqu %xmm5,0xbabecafe
+
+// CHECK: movdqu %xmm5, 305419896
+ movdqu %xmm5,0x12345678
+
+// CHECK: movdq2q %xmm5, %mm3
+ movdq2q %xmm5,%mm3
+
+// CHECK: movq2dq %mm3, %xmm5
+ movq2dq %mm3,%xmm5
+
+// CHECK: pmuludq 3735928559(%ebx,%ecx,8), %mm3
+ pmuludq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmuludq 69, %mm3
+ pmuludq 0x45,%mm3
+
+// CHECK: pmuludq 32493, %mm3
+ pmuludq 0x7eed,%mm3
+
+// CHECK: pmuludq 3133065982, %mm3
+ pmuludq 0xbabecafe,%mm3
+
+// CHECK: pmuludq 305419896, %mm3
+ pmuludq 0x12345678,%mm3
+
+// CHECK: pmuludq %mm3, %mm3
+ pmuludq %mm3,%mm3
+
+// CHECK: pmuludq 3735928559(%ebx,%ecx,8), %xmm5
+ pmuludq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmuludq 69, %xmm5
+ pmuludq 0x45,%xmm5
+
+// CHECK: pmuludq 32493, %xmm5
+ pmuludq 0x7eed,%xmm5
+
+// CHECK: pmuludq 3133065982, %xmm5
+ pmuludq 0xbabecafe,%xmm5
+
+// CHECK: pmuludq 305419896, %xmm5
+ pmuludq 0x12345678,%xmm5
+
+// CHECK: pmuludq %xmm5, %xmm5
+ pmuludq %xmm5,%xmm5
+
+// CHECK: pslldq $127, %xmm5
+ pslldq $0x7f,%xmm5
+
+// CHECK: psrldq $127, %xmm5
+ psrldq $0x7f,%xmm5
+
+// CHECK: punpckhqdq 3735928559(%ebx,%ecx,8), %xmm5
+ punpckhqdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhqdq 69, %xmm5
+ punpckhqdq 0x45,%xmm5
+
+// CHECK: punpckhqdq 32493, %xmm5
+ punpckhqdq 0x7eed,%xmm5
+
+// CHECK: punpckhqdq 3133065982, %xmm5
+ punpckhqdq 0xbabecafe,%xmm5
+
+// CHECK: punpckhqdq 305419896, %xmm5
+ punpckhqdq 0x12345678,%xmm5
+
+// CHECK: punpckhqdq %xmm5, %xmm5
+ punpckhqdq %xmm5,%xmm5
+
+// CHECK: punpcklqdq 3735928559(%ebx,%ecx,8), %xmm5
+ punpcklqdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpcklqdq 69, %xmm5
+ punpcklqdq 0x45,%xmm5
+
+// CHECK: punpcklqdq 32493, %xmm5
+ punpcklqdq 0x7eed,%xmm5
+
+// CHECK: punpcklqdq 3133065982, %xmm5
+ punpcklqdq 0xbabecafe,%xmm5
+
+// CHECK: punpcklqdq 305419896, %xmm5
+ punpcklqdq 0x12345678,%xmm5
+
+// CHECK: punpcklqdq %xmm5, %xmm5
+ punpcklqdq %xmm5,%xmm5
+
+// CHECK: addsubpd 3735928559(%ebx,%ecx,8), %xmm5
+ addsubpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addsubpd 69, %xmm5
+ addsubpd 0x45,%xmm5
+
+// CHECK: addsubpd 32493, %xmm5
+ addsubpd 0x7eed,%xmm5
+
+// CHECK: addsubpd 3133065982, %xmm5
+ addsubpd 0xbabecafe,%xmm5
+
+// CHECK: addsubpd 305419896, %xmm5
+ addsubpd 0x12345678,%xmm5
+
+// CHECK: addsubpd %xmm5, %xmm5
+ addsubpd %xmm5,%xmm5
+
+// CHECK: addsubps 3735928559(%ebx,%ecx,8), %xmm5
+ addsubps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addsubps 69, %xmm5
+ addsubps 0x45,%xmm5
+
+// CHECK: addsubps 32493, %xmm5
+ addsubps 0x7eed,%xmm5
+
+// CHECK: addsubps 3133065982, %xmm5
+ addsubps 0xbabecafe,%xmm5
+
+// CHECK: addsubps 305419896, %xmm5
+ addsubps 0x12345678,%xmm5
+
+// CHECK: addsubps %xmm5, %xmm5
+ addsubps %xmm5,%xmm5
+
+// CHECK: fisttpl 3735928559(%ebx,%ecx,8)
+ fisttpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisttpl 3133065982
+ fisttpl 0xbabecafe
+
+// CHECK: fisttpl 305419896
+ fisttpl 0x12345678
+
+// CHECK: haddpd 3735928559(%ebx,%ecx,8), %xmm5
+ haddpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: haddpd 69, %xmm5
+ haddpd 0x45,%xmm5
+
+// CHECK: haddpd 32493, %xmm5
+ haddpd 0x7eed,%xmm5
+
+// CHECK: haddpd 3133065982, %xmm5
+ haddpd 0xbabecafe,%xmm5
+
+// CHECK: haddpd 305419896, %xmm5
+ haddpd 0x12345678,%xmm5
+
+// CHECK: haddpd %xmm5, %xmm5
+ haddpd %xmm5,%xmm5
+
+// CHECK: haddps 3735928559(%ebx,%ecx,8), %xmm5
+ haddps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: haddps 69, %xmm5
+ haddps 0x45,%xmm5
+
+// CHECK: haddps 32493, %xmm5
+ haddps 0x7eed,%xmm5
+
+// CHECK: haddps 3133065982, %xmm5
+ haddps 0xbabecafe,%xmm5
+
+// CHECK: haddps 305419896, %xmm5
+ haddps 0x12345678,%xmm5
+
+// CHECK: haddps %xmm5, %xmm5
+ haddps %xmm5,%xmm5
+
+// CHECK: hsubpd 3735928559(%ebx,%ecx,8), %xmm5
+ hsubpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: hsubpd 69, %xmm5
+ hsubpd 0x45,%xmm5
+
+// CHECK: hsubpd 32493, %xmm5
+ hsubpd 0x7eed,%xmm5
+
+// CHECK: hsubpd 3133065982, %xmm5
+ hsubpd 0xbabecafe,%xmm5
+
+// CHECK: hsubpd 305419896, %xmm5
+ hsubpd 0x12345678,%xmm5
+
+// CHECK: hsubpd %xmm5, %xmm5
+ hsubpd %xmm5,%xmm5
+
+// CHECK: hsubps 3735928559(%ebx,%ecx,8), %xmm5
+ hsubps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: hsubps 69, %xmm5
+ hsubps 0x45,%xmm5
+
+// CHECK: hsubps 32493, %xmm5
+ hsubps 0x7eed,%xmm5
+
+// CHECK: hsubps 3133065982, %xmm5
+ hsubps 0xbabecafe,%xmm5
+
+// CHECK: hsubps 305419896, %xmm5
+ hsubps 0x12345678,%xmm5
+
+// CHECK: hsubps %xmm5, %xmm5
+ hsubps %xmm5,%xmm5
+
+// CHECK: lddqu 3735928559(%ebx,%ecx,8), %xmm5
+ lddqu 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: lddqu 69, %xmm5
+ lddqu 0x45,%xmm5
+
+// CHECK: lddqu 32493, %xmm5
+ lddqu 0x7eed,%xmm5
+
+// CHECK: lddqu 3133065982, %xmm5
+ lddqu 0xbabecafe,%xmm5
+
+// CHECK: lddqu 305419896, %xmm5
+ lddqu 0x12345678,%xmm5
+
+// CHECK: monitor
+ monitor
+
+// CHECK: movddup 3735928559(%ebx,%ecx,8), %xmm5
+ movddup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movddup 69, %xmm5
+ movddup 0x45,%xmm5
+
+// CHECK: movddup 32493, %xmm5
+ movddup 0x7eed,%xmm5
+
+// CHECK: movddup 3133065982, %xmm5
+ movddup 0xbabecafe,%xmm5
+
+// CHECK: movddup 305419896, %xmm5
+ movddup 0x12345678,%xmm5
+
+// CHECK: movddup %xmm5, %xmm5
+ movddup %xmm5,%xmm5
+
+// CHECK: movshdup 3735928559(%ebx,%ecx,8), %xmm5
+ movshdup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movshdup 69, %xmm5
+ movshdup 0x45,%xmm5
+
+// CHECK: movshdup 32493, %xmm5
+ movshdup 0x7eed,%xmm5
+
+// CHECK: movshdup 3133065982, %xmm5
+ movshdup 0xbabecafe,%xmm5
+
+// CHECK: movshdup 305419896, %xmm5
+ movshdup 0x12345678,%xmm5
+
+// CHECK: movshdup %xmm5, %xmm5
+ movshdup %xmm5,%xmm5
+
+// CHECK: movsldup 3735928559(%ebx,%ecx,8), %xmm5
+ movsldup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movsldup 69, %xmm5
+ movsldup 0x45,%xmm5
+
+// CHECK: movsldup 32493, %xmm5
+ movsldup 0x7eed,%xmm5
+
+// CHECK: movsldup 3133065982, %xmm5
+ movsldup 0xbabecafe,%xmm5
+
+// CHECK: movsldup 305419896, %xmm5
+ movsldup 0x12345678,%xmm5
+
+// CHECK: movsldup %xmm5, %xmm5
+ movsldup %xmm5,%xmm5
+
+// CHECK: mwait
+ mwait
+
+// CHECK: vmcall
+ vmcall
+
+// CHECK: vmclear 3735928559(%ebx,%ecx,8)
+ vmclear 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: vmclear 32493
+ vmclear 0x7eed
+
+// CHECK: vmclear 3133065982
+ vmclear 0xbabecafe
+
+// CHECK: vmclear 305419896
+ vmclear 0x12345678
+
+// CHECK: vmlaunch
+ vmlaunch
+
+// CHECK: vmresume
+ vmresume
+
+// CHECK: vmptrld 3735928559(%ebx,%ecx,8)
+ vmptrld 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: vmptrld 32493
+ vmptrld 0x7eed
+
+// CHECK: vmptrld 3133065982
+ vmptrld 0xbabecafe
+
+// CHECK: vmptrld 305419896
+ vmptrld 0x12345678
+
+// CHECK: vmptrst 3735928559(%ebx,%ecx,8)
+ vmptrst 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: vmptrst 32493
+ vmptrst 0x7eed
+
+// CHECK: vmptrst 3133065982
+ vmptrst 0xbabecafe
+
+// CHECK: vmptrst 305419896
+ vmptrst 0x12345678
+
+// CHECK: vmxoff
+ vmxoff
+
+// CHECK: vmxon 3735928559(%ebx,%ecx,8)
+ vmxon 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: vmxon 32493
+ vmxon 0x7eed
+
+// CHECK: vmxon 3133065982
+ vmxon 0xbabecafe
+
+// CHECK: vmxon 305419896
+ vmxon 0x12345678
+
+// CHECK: phaddw 3735928559(%ebx,%ecx,8), %mm3
+ phaddw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phaddw 69, %mm3
+ phaddw 0x45,%mm3
+
+// CHECK: phaddw 32493, %mm3
+ phaddw 0x7eed,%mm3
+
+// CHECK: phaddw 3133065982, %mm3
+ phaddw 0xbabecafe,%mm3
+
+// CHECK: phaddw 305419896, %mm3
+ phaddw 0x12345678,%mm3
+
+// CHECK: phaddw %mm3, %mm3
+ phaddw %mm3,%mm3
+
+// CHECK: phaddw 3735928559(%ebx,%ecx,8), %xmm5
+ phaddw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phaddw 69, %xmm5
+ phaddw 0x45,%xmm5
+
+// CHECK: phaddw 32493, %xmm5
+ phaddw 0x7eed,%xmm5
+
+// CHECK: phaddw 3133065982, %xmm5
+ phaddw 0xbabecafe,%xmm5
+
+// CHECK: phaddw 305419896, %xmm5
+ phaddw 0x12345678,%xmm5
+
+// CHECK: phaddw %xmm5, %xmm5
+ phaddw %xmm5,%xmm5
+
+// CHECK: phaddd 3735928559(%ebx,%ecx,8), %mm3
+ phaddd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phaddd 69, %mm3
+ phaddd 0x45,%mm3
+
+// CHECK: phaddd 32493, %mm3
+ phaddd 0x7eed,%mm3
+
+// CHECK: phaddd 3133065982, %mm3
+ phaddd 0xbabecafe,%mm3
+
+// CHECK: phaddd 305419896, %mm3
+ phaddd 0x12345678,%mm3
+
+// CHECK: phaddd %mm3, %mm3
+ phaddd %mm3,%mm3
+
+// CHECK: phaddd 3735928559(%ebx,%ecx,8), %xmm5
+ phaddd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phaddd 69, %xmm5
+ phaddd 0x45,%xmm5
+
+// CHECK: phaddd 32493, %xmm5
+ phaddd 0x7eed,%xmm5
+
+// CHECK: phaddd 3133065982, %xmm5
+ phaddd 0xbabecafe,%xmm5
+
+// CHECK: phaddd 305419896, %xmm5
+ phaddd 0x12345678,%xmm5
+
+// CHECK: phaddd %xmm5, %xmm5
+ phaddd %xmm5,%xmm5
+
+// CHECK: phaddsw 3735928559(%ebx,%ecx,8), %mm3
+ phaddsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phaddsw 69, %mm3
+ phaddsw 0x45,%mm3
+
+// CHECK: phaddsw 32493, %mm3
+ phaddsw 0x7eed,%mm3
+
+// CHECK: phaddsw 3133065982, %mm3
+ phaddsw 0xbabecafe,%mm3
+
+// CHECK: phaddsw 305419896, %mm3
+ phaddsw 0x12345678,%mm3
+
+// CHECK: phaddsw %mm3, %mm3
+ phaddsw %mm3,%mm3
+
+// CHECK: phaddsw 3735928559(%ebx,%ecx,8), %xmm5
+ phaddsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phaddsw 69, %xmm5
+ phaddsw 0x45,%xmm5
+
+// CHECK: phaddsw 32493, %xmm5
+ phaddsw 0x7eed,%xmm5
+
+// CHECK: phaddsw 3133065982, %xmm5
+ phaddsw 0xbabecafe,%xmm5
+
+// CHECK: phaddsw 305419896, %xmm5
+ phaddsw 0x12345678,%xmm5
+
+// CHECK: phaddsw %xmm5, %xmm5
+ phaddsw %xmm5,%xmm5
+
+// CHECK: phsubw 3735928559(%ebx,%ecx,8), %mm3
+ phsubw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phsubw 69, %mm3
+ phsubw 0x45,%mm3
+
+// CHECK: phsubw 32493, %mm3
+ phsubw 0x7eed,%mm3
+
+// CHECK: phsubw 3133065982, %mm3
+ phsubw 0xbabecafe,%mm3
+
+// CHECK: phsubw 305419896, %mm3
+ phsubw 0x12345678,%mm3
+
+// CHECK: phsubw %mm3, %mm3
+ phsubw %mm3,%mm3
+
+// CHECK: phsubw 3735928559(%ebx,%ecx,8), %xmm5
+ phsubw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phsubw 69, %xmm5
+ phsubw 0x45,%xmm5
+
+// CHECK: phsubw 32493, %xmm5
+ phsubw 0x7eed,%xmm5
+
+// CHECK: phsubw 3133065982, %xmm5
+ phsubw 0xbabecafe,%xmm5
+
+// CHECK: phsubw 305419896, %xmm5
+ phsubw 0x12345678,%xmm5
+
+// CHECK: phsubw %xmm5, %xmm5
+ phsubw %xmm5,%xmm5
+
+// CHECK: phsubd 3735928559(%ebx,%ecx,8), %mm3
+ phsubd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phsubd 69, %mm3
+ phsubd 0x45,%mm3
+
+// CHECK: phsubd 32493, %mm3
+ phsubd 0x7eed,%mm3
+
+// CHECK: phsubd 3133065982, %mm3
+ phsubd 0xbabecafe,%mm3
+
+// CHECK: phsubd 305419896, %mm3
+ phsubd 0x12345678,%mm3
+
+// CHECK: phsubd %mm3, %mm3
+ phsubd %mm3,%mm3
+
+// CHECK: phsubd 3735928559(%ebx,%ecx,8), %xmm5
+ phsubd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phsubd 69, %xmm5
+ phsubd 0x45,%xmm5
+
+// CHECK: phsubd 32493, %xmm5
+ phsubd 0x7eed,%xmm5
+
+// CHECK: phsubd 3133065982, %xmm5
+ phsubd 0xbabecafe,%xmm5
+
+// CHECK: phsubd 305419896, %xmm5
+ phsubd 0x12345678,%xmm5
+
+// CHECK: phsubd %xmm5, %xmm5
+ phsubd %xmm5,%xmm5
+
+// CHECK: phsubsw 3735928559(%ebx,%ecx,8), %mm3
+ phsubsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phsubsw 69, %mm3
+ phsubsw 0x45,%mm3
+
+// CHECK: phsubsw 32493, %mm3
+ phsubsw 0x7eed,%mm3
+
+// CHECK: phsubsw 3133065982, %mm3
+ phsubsw 0xbabecafe,%mm3
+
+// CHECK: phsubsw 305419896, %mm3
+ phsubsw 0x12345678,%mm3
+
+// CHECK: phsubsw %mm3, %mm3
+ phsubsw %mm3,%mm3
+
+// CHECK: phsubsw 3735928559(%ebx,%ecx,8), %xmm5
+ phsubsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phsubsw 69, %xmm5
+ phsubsw 0x45,%xmm5
+
+// CHECK: phsubsw 32493, %xmm5
+ phsubsw 0x7eed,%xmm5
+
+// CHECK: phsubsw 3133065982, %xmm5
+ phsubsw 0xbabecafe,%xmm5
+
+// CHECK: phsubsw 305419896, %xmm5
+ phsubsw 0x12345678,%xmm5
+
+// CHECK: phsubsw %xmm5, %xmm5
+ phsubsw %xmm5,%xmm5
+
+// CHECK: pmaddubsw 3735928559(%ebx,%ecx,8), %mm3
+ pmaddubsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaddubsw 69, %mm3
+ pmaddubsw 0x45,%mm3
+
+// CHECK: pmaddubsw 32493, %mm3
+ pmaddubsw 0x7eed,%mm3
+
+// CHECK: pmaddubsw 3133065982, %mm3
+ pmaddubsw 0xbabecafe,%mm3
+
+// CHECK: pmaddubsw 305419896, %mm3
+ pmaddubsw 0x12345678,%mm3
+
+// CHECK: pmaddubsw %mm3, %mm3
+ pmaddubsw %mm3,%mm3
+
+// CHECK: pmaddubsw 3735928559(%ebx,%ecx,8), %xmm5
+ pmaddubsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaddubsw 69, %xmm5
+ pmaddubsw 0x45,%xmm5
+
+// CHECK: pmaddubsw 32493, %xmm5
+ pmaddubsw 0x7eed,%xmm5
+
+// CHECK: pmaddubsw 3133065982, %xmm5
+ pmaddubsw 0xbabecafe,%xmm5
+
+// CHECK: pmaddubsw 305419896, %xmm5
+ pmaddubsw 0x12345678,%xmm5
+
+// CHECK: pmaddubsw %xmm5, %xmm5
+ pmaddubsw %xmm5,%xmm5
+
+// CHECK: pmulhrsw 3735928559(%ebx,%ecx,8), %mm3
+ pmulhrsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmulhrsw 69, %mm3
+ pmulhrsw 0x45,%mm3
+
+// CHECK: pmulhrsw 32493, %mm3
+ pmulhrsw 0x7eed,%mm3
+
+// CHECK: pmulhrsw 3133065982, %mm3
+ pmulhrsw 0xbabecafe,%mm3
+
+// CHECK: pmulhrsw 305419896, %mm3
+ pmulhrsw 0x12345678,%mm3
+
+// CHECK: pmulhrsw %mm3, %mm3
+ pmulhrsw %mm3,%mm3
+
+// CHECK: pmulhrsw 3735928559(%ebx,%ecx,8), %xmm5
+ pmulhrsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulhrsw 69, %xmm5
+ pmulhrsw 0x45,%xmm5
+
+// CHECK: pmulhrsw 32493, %xmm5
+ pmulhrsw 0x7eed,%xmm5
+
+// CHECK: pmulhrsw 3133065982, %xmm5
+ pmulhrsw 0xbabecafe,%xmm5
+
+// CHECK: pmulhrsw 305419896, %xmm5
+ pmulhrsw 0x12345678,%xmm5
+
+// CHECK: pmulhrsw %xmm5, %xmm5
+ pmulhrsw %xmm5,%xmm5
+
+// CHECK: pshufb 3735928559(%ebx,%ecx,8), %mm3
+ pshufb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pshufb 69, %mm3
+ pshufb 0x45,%mm3
+
+// CHECK: pshufb 32493, %mm3
+ pshufb 0x7eed,%mm3
+
+// CHECK: pshufb 3133065982, %mm3
+ pshufb 0xbabecafe,%mm3
+
+// CHECK: pshufb 305419896, %mm3
+ pshufb 0x12345678,%mm3
+
+// CHECK: pshufb %mm3, %mm3
+ pshufb %mm3,%mm3
+
+// CHECK: pshufb 3735928559(%ebx,%ecx,8), %xmm5
+ pshufb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pshufb 69, %xmm5
+ pshufb 0x45,%xmm5
+
+// CHECK: pshufb 32493, %xmm5
+ pshufb 0x7eed,%xmm5
+
+// CHECK: pshufb 3133065982, %xmm5
+ pshufb 0xbabecafe,%xmm5
+
+// CHECK: pshufb 305419896, %xmm5
+ pshufb 0x12345678,%xmm5
+
+// CHECK: pshufb %xmm5, %xmm5
+ pshufb %xmm5,%xmm5
+
+// CHECK: psignb 3735928559(%ebx,%ecx,8), %mm3
+ psignb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psignb 69, %mm3
+ psignb 0x45,%mm3
+
+// CHECK: psignb 32493, %mm3
+ psignb 0x7eed,%mm3
+
+// CHECK: psignb 3133065982, %mm3
+ psignb 0xbabecafe,%mm3
+
+// CHECK: psignb 305419896, %mm3
+ psignb 0x12345678,%mm3
+
+// CHECK: psignb %mm3, %mm3
+ psignb %mm3,%mm3
+
+// CHECK: psignb 3735928559(%ebx,%ecx,8), %xmm5
+ psignb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psignb 69, %xmm5
+ psignb 0x45,%xmm5
+
+// CHECK: psignb 32493, %xmm5
+ psignb 0x7eed,%xmm5
+
+// CHECK: psignb 3133065982, %xmm5
+ psignb 0xbabecafe,%xmm5
+
+// CHECK: psignb 305419896, %xmm5
+ psignb 0x12345678,%xmm5
+
+// CHECK: psignb %xmm5, %xmm5
+ psignb %xmm5,%xmm5
+
+// CHECK: psignw 3735928559(%ebx,%ecx,8), %mm3
+ psignw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psignw 69, %mm3
+ psignw 0x45,%mm3
+
+// CHECK: psignw 32493, %mm3
+ psignw 0x7eed,%mm3
+
+// CHECK: psignw 3133065982, %mm3
+ psignw 0xbabecafe,%mm3
+
+// CHECK: psignw 305419896, %mm3
+ psignw 0x12345678,%mm3
+
+// CHECK: psignw %mm3, %mm3
+ psignw %mm3,%mm3
+
+// CHECK: psignw 3735928559(%ebx,%ecx,8), %xmm5
+ psignw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psignw 69, %xmm5
+ psignw 0x45,%xmm5
+
+// CHECK: psignw 32493, %xmm5
+ psignw 0x7eed,%xmm5
+
+// CHECK: psignw 3133065982, %xmm5
+ psignw 0xbabecafe,%xmm5
+
+// CHECK: psignw 305419896, %xmm5
+ psignw 0x12345678,%xmm5
+
+// CHECK: psignw %xmm5, %xmm5
+ psignw %xmm5,%xmm5
+
+// CHECK: psignd 3735928559(%ebx,%ecx,8), %mm3
+ psignd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psignd 69, %mm3
+ psignd 0x45,%mm3
+
+// CHECK: psignd 32493, %mm3
+ psignd 0x7eed,%mm3
+
+// CHECK: psignd 3133065982, %mm3
+ psignd 0xbabecafe,%mm3
+
+// CHECK: psignd 305419896, %mm3
+ psignd 0x12345678,%mm3
+
+// CHECK: psignd %mm3, %mm3
+ psignd %mm3,%mm3
+
+// CHECK: psignd 3735928559(%ebx,%ecx,8), %xmm5
+ psignd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psignd 69, %xmm5
+ psignd 0x45,%xmm5
+
+// CHECK: psignd 32493, %xmm5
+ psignd 0x7eed,%xmm5
+
+// CHECK: psignd 3133065982, %xmm5
+ psignd 0xbabecafe,%xmm5
+
+// CHECK: psignd 305419896, %xmm5
+ psignd 0x12345678,%xmm5
+
+// CHECK: psignd %xmm5, %xmm5
+ psignd %xmm5,%xmm5
+
+// CHECK: pabsb 3735928559(%ebx,%ecx,8), %mm3
+ pabsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsb 69, %mm3
+ pabsb 0x45,%mm3
+
+// CHECK: pabsb 32493, %mm3
+ pabsb 0x7eed,%mm3
+
+// CHECK: pabsb 3133065982, %mm3
+ pabsb 0xbabecafe,%mm3
+
+// CHECK: pabsb 305419896, %mm3
+ pabsb 0x12345678,%mm3
+
+// CHECK: pabsb %mm3, %mm3
+ pabsb %mm3,%mm3
+
+// CHECK: pabsb 3735928559(%ebx,%ecx,8), %xmm5
+ pabsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsb 69, %xmm5
+ pabsb 0x45,%xmm5
+
+// CHECK: pabsb 32493, %xmm5
+ pabsb 0x7eed,%xmm5
+
+// CHECK: pabsb 3133065982, %xmm5
+ pabsb 0xbabecafe,%xmm5
+
+// CHECK: pabsb 305419896, %xmm5
+ pabsb 0x12345678,%xmm5
+
+// CHECK: pabsb %xmm5, %xmm5
+ pabsb %xmm5,%xmm5
+
+// CHECK: pabsw 3735928559(%ebx,%ecx,8), %mm3
+ pabsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsw 69, %mm3
+ pabsw 0x45,%mm3
+
+// CHECK: pabsw 32493, %mm3
+ pabsw 0x7eed,%mm3
+
+// CHECK: pabsw 3133065982, %mm3
+ pabsw 0xbabecafe,%mm3
+
+// CHECK: pabsw 305419896, %mm3
+ pabsw 0x12345678,%mm3
+
+// CHECK: pabsw %mm3, %mm3
+ pabsw %mm3,%mm3
+
+// CHECK: pabsw 3735928559(%ebx,%ecx,8), %xmm5
+ pabsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsw 69, %xmm5
+ pabsw 0x45,%xmm5
+
+// CHECK: pabsw 32493, %xmm5
+ pabsw 0x7eed,%xmm5
+
+// CHECK: pabsw 3133065982, %xmm5
+ pabsw 0xbabecafe,%xmm5
+
+// CHECK: pabsw 305419896, %xmm5
+ pabsw 0x12345678,%xmm5
+
+// CHECK: pabsw %xmm5, %xmm5
+ pabsw %xmm5,%xmm5
+
+// CHECK: pabsd 3735928559(%ebx,%ecx,8), %mm3
+ pabsd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsd 69, %mm3
+ pabsd 0x45,%mm3
+
+// CHECK: pabsd 32493, %mm3
+ pabsd 0x7eed,%mm3
+
+// CHECK: pabsd 3133065982, %mm3
+ pabsd 0xbabecafe,%mm3
+
+// CHECK: pabsd 305419896, %mm3
+ pabsd 0x12345678,%mm3
+
+// CHECK: pabsd %mm3, %mm3
+ pabsd %mm3,%mm3
+
+// CHECK: pabsd 3735928559(%ebx,%ecx,8), %xmm5
+ pabsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsd 69, %xmm5
+ pabsd 0x45,%xmm5
+
+// CHECK: pabsd 32493, %xmm5
+ pabsd 0x7eed,%xmm5
+
+// CHECK: pabsd 3133065982, %xmm5
+ pabsd 0xbabecafe,%xmm5
+
+// CHECK: pabsd 305419896, %xmm5
+ pabsd 0x12345678,%xmm5
+
+// CHECK: pabsd %xmm5, %xmm5
+ pabsd %xmm5,%xmm5
+
+// CHECK: femms
+ femms
+
+// CHECK: movntdqa 3735928559(%ebx,%ecx,8), %xmm5
+ movntdqa 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movntdqa 69, %xmm5
+ movntdqa 0x45,%xmm5
+
+// CHECK: movntdqa 32493, %xmm5
+ movntdqa 0x7eed,%xmm5
+
+// CHECK: movntdqa 3133065982, %xmm5
+ movntdqa 0xbabecafe,%xmm5
+
+// CHECK: movntdqa 305419896, %xmm5
+ movntdqa 0x12345678,%xmm5
+
+// CHECK: packusdw 3735928559(%ebx,%ecx,8), %xmm5
+ packusdw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packusdw 69, %xmm5
+ packusdw 0x45,%xmm5
+
+// CHECK: packusdw 32493, %xmm5
+ packusdw 0x7eed,%xmm5
+
+// CHECK: packusdw 3133065982, %xmm5
+ packusdw 0xbabecafe,%xmm5
+
+// CHECK: packusdw 305419896, %xmm5
+ packusdw 0x12345678,%xmm5
+
+// CHECK: packusdw %xmm5, %xmm5
+ packusdw %xmm5,%xmm5
+
+// CHECK: pcmpeqq 3735928559(%ebx,%ecx,8), %xmm5
+ pcmpeqq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqq 69, %xmm5
+ pcmpeqq 0x45,%xmm5
+
+// CHECK: pcmpeqq 32493, %xmm5
+ pcmpeqq 0x7eed,%xmm5
+
+// CHECK: pcmpeqq 3133065982, %xmm5
+ pcmpeqq 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqq 305419896, %xmm5
+ pcmpeqq 0x12345678,%xmm5
+
+// CHECK: pcmpeqq %xmm5, %xmm5
+ pcmpeqq %xmm5,%xmm5
+
+// CHECK: phminposuw 3735928559(%ebx,%ecx,8), %xmm5
+ phminposuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phminposuw 69, %xmm5
+ phminposuw 0x45,%xmm5
+
+// CHECK: phminposuw 32493, %xmm5
+ phminposuw 0x7eed,%xmm5
+
+// CHECK: phminposuw 3133065982, %xmm5
+ phminposuw 0xbabecafe,%xmm5
+
+// CHECK: phminposuw 305419896, %xmm5
+ phminposuw 0x12345678,%xmm5
+
+// CHECK: phminposuw %xmm5, %xmm5
+ phminposuw %xmm5,%xmm5
+
+// CHECK: pmaxsb 3735928559(%ebx,%ecx,8), %xmm5
+ pmaxsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxsb 69, %xmm5
+ pmaxsb 0x45,%xmm5
+
+// CHECK: pmaxsb 32493, %xmm5
+ pmaxsb 0x7eed,%xmm5
+
+// CHECK: pmaxsb 3133065982, %xmm5
+ pmaxsb 0xbabecafe,%xmm5
+
+// CHECK: pmaxsb 305419896, %xmm5
+ pmaxsb 0x12345678,%xmm5
+
+// CHECK: pmaxsb %xmm5, %xmm5
+ pmaxsb %xmm5,%xmm5
+
+// CHECK: pmaxsd 3735928559(%ebx,%ecx,8), %xmm5
+ pmaxsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxsd 69, %xmm5
+ pmaxsd 0x45,%xmm5
+
+// CHECK: pmaxsd 32493, %xmm5
+ pmaxsd 0x7eed,%xmm5
+
+// CHECK: pmaxsd 3133065982, %xmm5
+ pmaxsd 0xbabecafe,%xmm5
+
+// CHECK: pmaxsd 305419896, %xmm5
+ pmaxsd 0x12345678,%xmm5
+
+// CHECK: pmaxsd %xmm5, %xmm5
+ pmaxsd %xmm5,%xmm5
+
+// CHECK: pmaxud 3735928559(%ebx,%ecx,8), %xmm5
+ pmaxud 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxud 69, %xmm5
+ pmaxud 0x45,%xmm5
+
+// CHECK: pmaxud 32493, %xmm5
+ pmaxud 0x7eed,%xmm5
+
+// CHECK: pmaxud 3133065982, %xmm5
+ pmaxud 0xbabecafe,%xmm5
+
+// CHECK: pmaxud 305419896, %xmm5
+ pmaxud 0x12345678,%xmm5
+
+// CHECK: pmaxud %xmm5, %xmm5
+ pmaxud %xmm5,%xmm5
+
+// CHECK: pmaxuw 3735928559(%ebx,%ecx,8), %xmm5
+ pmaxuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxuw 69, %xmm5
+ pmaxuw 0x45,%xmm5
+
+// CHECK: pmaxuw 32493, %xmm5
+ pmaxuw 0x7eed,%xmm5
+
+// CHECK: pmaxuw 3133065982, %xmm5
+ pmaxuw 0xbabecafe,%xmm5
+
+// CHECK: pmaxuw 305419896, %xmm5
+ pmaxuw 0x12345678,%xmm5
+
+// CHECK: pmaxuw %xmm5, %xmm5
+ pmaxuw %xmm5,%xmm5
+
+// CHECK: pminsb 3735928559(%ebx,%ecx,8), %xmm5
+ pminsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminsb 69, %xmm5
+ pminsb 0x45,%xmm5
+
+// CHECK: pminsb 32493, %xmm5
+ pminsb 0x7eed,%xmm5
+
+// CHECK: pminsb 3133065982, %xmm5
+ pminsb 0xbabecafe,%xmm5
+
+// CHECK: pminsb 305419896, %xmm5
+ pminsb 0x12345678,%xmm5
+
+// CHECK: pminsb %xmm5, %xmm5
+ pminsb %xmm5,%xmm5
+
+// CHECK: pminsd 3735928559(%ebx,%ecx,8), %xmm5
+ pminsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminsd 69, %xmm5
+ pminsd 0x45,%xmm5
+
+// CHECK: pminsd 32493, %xmm5
+ pminsd 0x7eed,%xmm5
+
+// CHECK: pminsd 3133065982, %xmm5
+ pminsd 0xbabecafe,%xmm5
+
+// CHECK: pminsd 305419896, %xmm5
+ pminsd 0x12345678,%xmm5
+
+// CHECK: pminsd %xmm5, %xmm5
+ pminsd %xmm5,%xmm5
+
+// CHECK: pminud 3735928559(%ebx,%ecx,8), %xmm5
+ pminud 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminud 69, %xmm5
+ pminud 0x45,%xmm5
+
+// CHECK: pminud 32493, %xmm5
+ pminud 0x7eed,%xmm5
+
+// CHECK: pminud 3133065982, %xmm5
+ pminud 0xbabecafe,%xmm5
+
+// CHECK: pminud 305419896, %xmm5
+ pminud 0x12345678,%xmm5
+
+// CHECK: pminud %xmm5, %xmm5
+ pminud %xmm5,%xmm5
+
+// CHECK: pminuw 3735928559(%ebx,%ecx,8), %xmm5
+ pminuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminuw 69, %xmm5
+ pminuw 0x45,%xmm5
+
+// CHECK: pminuw 32493, %xmm5
+ pminuw 0x7eed,%xmm5
+
+// CHECK: pminuw 3133065982, %xmm5
+ pminuw 0xbabecafe,%xmm5
+
+// CHECK: pminuw 305419896, %xmm5
+ pminuw 0x12345678,%xmm5
+
+// CHECK: pminuw %xmm5, %xmm5
+ pminuw %xmm5,%xmm5
+
+// CHECK: pmovsxbw 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbw 69, %xmm5
+ pmovsxbw 0x45,%xmm5
+
+// CHECK: pmovsxbw 32493, %xmm5
+ pmovsxbw 0x7eed,%xmm5
+
+// CHECK: pmovsxbw 3133065982, %xmm5
+ pmovsxbw 0xbabecafe,%xmm5
+
+// CHECK: pmovsxbw 305419896, %xmm5
+ pmovsxbw 0x12345678,%xmm5
+
+// CHECK: pmovsxbw %xmm5, %xmm5
+ pmovsxbw %xmm5,%xmm5
+
+// CHECK: pmovsxbd 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxbd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbd 69, %xmm5
+ pmovsxbd 0x45,%xmm5
+
+// CHECK: pmovsxbd 32493, %xmm5
+ pmovsxbd 0x7eed,%xmm5
+
+// CHECK: pmovsxbd 3133065982, %xmm5
+ pmovsxbd 0xbabecafe,%xmm5
+
+// CHECK: pmovsxbd 305419896, %xmm5
+ pmovsxbd 0x12345678,%xmm5
+
+// CHECK: pmovsxbd %xmm5, %xmm5
+ pmovsxbd %xmm5,%xmm5
+
+// CHECK: pmovsxbq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxbq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbq 69, %xmm5
+ pmovsxbq 0x45,%xmm5
+
+// CHECK: pmovsxbq 32493, %xmm5
+ pmovsxbq 0x7eed,%xmm5
+
+// CHECK: pmovsxbq 3133065982, %xmm5
+ pmovsxbq 0xbabecafe,%xmm5
+
+// CHECK: pmovsxbq 305419896, %xmm5
+ pmovsxbq 0x12345678,%xmm5
+
+// CHECK: pmovsxbq %xmm5, %xmm5
+ pmovsxbq %xmm5,%xmm5
+
+// CHECK: pmovsxwd 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxwd 69, %xmm5
+ pmovsxwd 0x45,%xmm5
+
+// CHECK: pmovsxwd 32493, %xmm5
+ pmovsxwd 0x7eed,%xmm5
+
+// CHECK: pmovsxwd 3133065982, %xmm5
+ pmovsxwd 0xbabecafe,%xmm5
+
+// CHECK: pmovsxwd 305419896, %xmm5
+ pmovsxwd 0x12345678,%xmm5
+
+// CHECK: pmovsxwd %xmm5, %xmm5
+ pmovsxwd %xmm5,%xmm5
+
+// CHECK: pmovsxwq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxwq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxwq 69, %xmm5
+ pmovsxwq 0x45,%xmm5
+
+// CHECK: pmovsxwq 32493, %xmm5
+ pmovsxwq 0x7eed,%xmm5
+
+// CHECK: pmovsxwq 3133065982, %xmm5
+ pmovsxwq 0xbabecafe,%xmm5
+
+// CHECK: pmovsxwq 305419896, %xmm5
+ pmovsxwq 0x12345678,%xmm5
+
+// CHECK: pmovsxwq %xmm5, %xmm5
+ pmovsxwq %xmm5,%xmm5
+
+// CHECK: pmovsxdq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovsxdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxdq 69, %xmm5
+ pmovsxdq 0x45,%xmm5
+
+// CHECK: pmovsxdq 32493, %xmm5
+ pmovsxdq 0x7eed,%xmm5
+
+// CHECK: pmovsxdq 3133065982, %xmm5
+ pmovsxdq 0xbabecafe,%xmm5
+
+// CHECK: pmovsxdq 305419896, %xmm5
+ pmovsxdq 0x12345678,%xmm5
+
+// CHECK: pmovsxdq %xmm5, %xmm5
+ pmovsxdq %xmm5,%xmm5
+
+// CHECK: pmovzxbw 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbw 69, %xmm5
+ pmovzxbw 0x45,%xmm5
+
+// CHECK: pmovzxbw 32493, %xmm5
+ pmovzxbw 0x7eed,%xmm5
+
+// CHECK: pmovzxbw 3133065982, %xmm5
+ pmovzxbw 0xbabecafe,%xmm5
+
+// CHECK: pmovzxbw 305419896, %xmm5
+ pmovzxbw 0x12345678,%xmm5
+
+// CHECK: pmovzxbw %xmm5, %xmm5
+ pmovzxbw %xmm5,%xmm5
+
+// CHECK: pmovzxbd 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxbd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbd 69, %xmm5
+ pmovzxbd 0x45,%xmm5
+
+// CHECK: pmovzxbd 32493, %xmm5
+ pmovzxbd 0x7eed,%xmm5
+
+// CHECK: pmovzxbd 3133065982, %xmm5
+ pmovzxbd 0xbabecafe,%xmm5
+
+// CHECK: pmovzxbd 305419896, %xmm5
+ pmovzxbd 0x12345678,%xmm5
+
+// CHECK: pmovzxbd %xmm5, %xmm5
+ pmovzxbd %xmm5,%xmm5
+
+// CHECK: pmovzxbq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxbq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbq 69, %xmm5
+ pmovzxbq 0x45,%xmm5
+
+// CHECK: pmovzxbq 32493, %xmm5
+ pmovzxbq 0x7eed,%xmm5
+
+// CHECK: pmovzxbq 3133065982, %xmm5
+ pmovzxbq 0xbabecafe,%xmm5
+
+// CHECK: pmovzxbq 305419896, %xmm5
+ pmovzxbq 0x12345678,%xmm5
+
+// CHECK: pmovzxbq %xmm5, %xmm5
+ pmovzxbq %xmm5,%xmm5
+
+// CHECK: pmovzxwd 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxwd 69, %xmm5
+ pmovzxwd 0x45,%xmm5
+
+// CHECK: pmovzxwd 32493, %xmm5
+ pmovzxwd 0x7eed,%xmm5
+
+// CHECK: pmovzxwd 3133065982, %xmm5
+ pmovzxwd 0xbabecafe,%xmm5
+
+// CHECK: pmovzxwd 305419896, %xmm5
+ pmovzxwd 0x12345678,%xmm5
+
+// CHECK: pmovzxwd %xmm5, %xmm5
+ pmovzxwd %xmm5,%xmm5
+
+// CHECK: pmovzxwq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxwq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxwq 69, %xmm5
+ pmovzxwq 0x45,%xmm5
+
+// CHECK: pmovzxwq 32493, %xmm5
+ pmovzxwq 0x7eed,%xmm5
+
+// CHECK: pmovzxwq 3133065982, %xmm5
+ pmovzxwq 0xbabecafe,%xmm5
+
+// CHECK: pmovzxwq 305419896, %xmm5
+ pmovzxwq 0x12345678,%xmm5
+
+// CHECK: pmovzxwq %xmm5, %xmm5
+ pmovzxwq %xmm5,%xmm5
+
+// CHECK: pmovzxdq 3735928559(%ebx,%ecx,8), %xmm5
+ pmovzxdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxdq 69, %xmm5
+ pmovzxdq 0x45,%xmm5
+
+// CHECK: pmovzxdq 32493, %xmm5
+ pmovzxdq 0x7eed,%xmm5
+
+// CHECK: pmovzxdq 3133065982, %xmm5
+ pmovzxdq 0xbabecafe,%xmm5
+
+// CHECK: pmovzxdq 305419896, %xmm5
+ pmovzxdq 0x12345678,%xmm5
+
+// CHECK: pmovzxdq %xmm5, %xmm5
+ pmovzxdq %xmm5,%xmm5
+
+// CHECK: pmuldq 3735928559(%ebx,%ecx,8), %xmm5
+ pmuldq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmuldq 69, %xmm5
+ pmuldq 0x45,%xmm5
+
+// CHECK: pmuldq 32493, %xmm5
+ pmuldq 0x7eed,%xmm5
+
+// CHECK: pmuldq 3133065982, %xmm5
+ pmuldq 0xbabecafe,%xmm5
+
+// CHECK: pmuldq 305419896, %xmm5
+ pmuldq 0x12345678,%xmm5
+
+// CHECK: pmuldq %xmm5, %xmm5
+ pmuldq %xmm5,%xmm5
+
+// CHECK: pmulld 3735928559(%ebx,%ecx,8), %xmm5
+ pmulld 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulld 69, %xmm5
+ pmulld 0x45,%xmm5
+
+// CHECK: pmulld 32493, %xmm5
+ pmulld 0x7eed,%xmm5
+
+// CHECK: pmulld 3133065982, %xmm5
+ pmulld 0xbabecafe,%xmm5
+
+// CHECK: pmulld 305419896, %xmm5
+ pmulld 0x12345678,%xmm5
+
+// CHECK: pmulld %xmm5, %xmm5
+ pmulld %xmm5,%xmm5
+
+// CHECK: ptest 3735928559(%ebx,%ecx,8), %xmm5
+ ptest 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ptest 69, %xmm5
+ ptest 0x45,%xmm5
+
+// CHECK: ptest 32493, %xmm5
+ ptest 0x7eed,%xmm5
+
+// CHECK: ptest 3133065982, %xmm5
+ ptest 0xbabecafe,%xmm5
+
+// CHECK: ptest 305419896, %xmm5
+ ptest 0x12345678,%xmm5
+
+// CHECK: ptest %xmm5, %xmm5
+ ptest %xmm5,%xmm5
+
+// CHECK: crc32 3735928559(%ebx,%ecx,8), %ecx
+ crc32 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: crc32 69, %ecx
+ crc32 0x45,%ecx
+
+// CHECK: crc32 32493, %ecx
+ crc32 0x7eed,%ecx
+
+// CHECK: crc32 3133065982, %ecx
+ crc32 0xbabecafe,%ecx
+
+// CHECK: crc32 305419896, %ecx
+ crc32 0x12345678,%ecx
+
+// CHECK: crc32 %ecx, %ecx
+ crc32 %ecx,%ecx
+
+// CHECK: crc32 %ecx, %ecx
+ crc32 %ecx,%ecx
+
+// CHECK: crc32 3735928559(%ebx,%ecx,8), %ecx
+ crc32 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: crc32 69, %ecx
+ crc32 0x45,%ecx
+
+// CHECK: crc32 32493, %ecx
+ crc32 0x7eed,%ecx
+
+// CHECK: crc32 3133065982, %ecx
+ crc32 0xbabecafe,%ecx
+
+// CHECK: crc32 305419896, %ecx
+ crc32 0x12345678,%ecx
+
+// CHECK: pcmpgtq 3735928559(%ebx,%ecx,8), %xmm5
+ pcmpgtq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtq 69, %xmm5
+ pcmpgtq 0x45,%xmm5
+
+// CHECK: pcmpgtq 32493, %xmm5
+ pcmpgtq 0x7eed,%xmm5
+
+// CHECK: pcmpgtq 3133065982, %xmm5
+ pcmpgtq 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtq 305419896, %xmm5
+ pcmpgtq 0x12345678,%xmm5
+
+// CHECK: pcmpgtq %xmm5, %xmm5
+ pcmpgtq %xmm5,%xmm5
diff --git a/test/MC/AsmParser/X86/x86_32-encoding.s b/test/MC/AsmParser/X86/x86_32-encoding.s
new file mode 100644
index 0000000..e325bdd
--- /dev/null
+++ b/test/MC/AsmParser/X86/x86_32-encoding.s
@@ -0,0 +1,9861 @@
+// RUN: llvm-mc -triple i386-unknown-unknown --show-encoding %s | FileCheck %s
+
+// CHECK: movb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc6,0x84,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ movb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movb $127, 69
+// CHECK: encoding: [0xc6,0x05,0x45,0x00,0x00,0x00,0x7f]
+ movb $0x7f,0x45
+
+// CHECK: movb $127, 32493
+// CHECK: encoding: [0xc6,0x05,0xed,0x7e,0x00,0x00,0x7f]
+ movb $0x7f,0x7eed
+
+// CHECK: movb $127, 3133065982
+// CHECK: encoding: [0xc6,0x05,0xfe,0xca,0xbe,0xba,0x7f]
+ movb $0x7f,0xbabecafe
+
+// CHECK: movb $127, 305419896
+// CHECK: encoding: [0xc6,0x05,0x78,0x56,0x34,0x12,0x7f]
+ movb $0x7f,0x12345678
+
+// CHECK: movw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0xc7,0x84,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ movw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movw $31438, 69
+// CHECK: encoding: [0x66,0xc7,0x05,0x45,0x00,0x00,0x00,0xce,0x7a]
+ movw $0x7ace,0x45
+
+// CHECK: movw $31438, 32493
+// CHECK: encoding: [0x66,0xc7,0x05,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ movw $0x7ace,0x7eed
+
+// CHECK: movw $31438, 3133065982
+// CHECK: encoding: [0x66,0xc7,0x05,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ movw $0x7ace,0xbabecafe
+
+// CHECK: movw $31438, 305419896
+// CHECK: encoding: [0x66,0xc7,0x05,0x78,0x56,0x34,0x12,0xce,0x7a]
+ movw $0x7ace,0x12345678
+
+// CHECK: movl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc7,0x84,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ movl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movl $2063514302, 69
+// CHECK: encoding: [0xc7,0x05,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ movl $0x7afebabe,0x45
+
+// CHECK: movl $2063514302, 32493
+// CHECK: encoding: [0xc7,0x05,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ movl $0x7afebabe,0x7eed
+
+// CHECK: movl $2063514302, 3133065982
+// CHECK: encoding: [0xc7,0x05,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ movl $0x7afebabe,0xbabecafe
+
+// CHECK: movl $2063514302, 305419896
+// CHECK: encoding: [0xc7,0x05,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ movl $0x7afebabe,0x12345678
+
+// CHECK: movl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc7,0x84,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ movl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movl $324478056, 69
+// CHECK: encoding: [0xc7,0x05,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ movl $0x13572468,0x45
+
+// CHECK: movl $324478056, 32493
+// CHECK: encoding: [0xc7,0x05,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ movl $0x13572468,0x7eed
+
+// CHECK: movl $324478056, 3133065982
+// CHECK: encoding: [0xc7,0x05,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ movl $0x13572468,0xbabecafe
+
+// CHECK: movl $324478056, 305419896
+// CHECK: encoding: [0xc7,0x05,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ movl $0x13572468,0x12345678
+
+// CHECK: movsbl 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0x0f,0xbe,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ movsbl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movsbl 69, %ecx
+// CHECK: encoding: [0x0f,0xbe,0x0d,0x45,0x00,0x00,0x00]
+ movsbl 0x45,%ecx
+
+// CHECK: movsbl 32493, %ecx
+// CHECK: encoding: [0x0f,0xbe,0x0d,0xed,0x7e,0x00,0x00]
+ movsbl 0x7eed,%ecx
+
+// CHECK: movsbl 3133065982, %ecx
+// CHECK: encoding: [0x0f,0xbe,0x0d,0xfe,0xca,0xbe,0xba]
+ movsbl 0xbabecafe,%ecx
+
+// CHECK: movsbl 305419896, %ecx
+// CHECK: encoding: [0x0f,0xbe,0x0d,0x78,0x56,0x34,0x12]
+ movsbl 0x12345678,%ecx
+
+// CHECK: movsbw 3735928559(%ebx,%ecx,8), %bx
+// CHECK: encoding: [0x66,0x0f,0xbe,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movsbw 0xdeadbeef(%ebx,%ecx,8),%bx
+
+// CHECK: movsbw 69, %bx
+// CHECK: encoding: [0x66,0x0f,0xbe,0x1d,0x45,0x00,0x00,0x00]
+ movsbw 0x45,%bx
+
+// CHECK: movsbw 32493, %bx
+// CHECK: encoding: [0x66,0x0f,0xbe,0x1d,0xed,0x7e,0x00,0x00]
+ movsbw 0x7eed,%bx
+
+// CHECK: movsbw 3133065982, %bx
+// CHECK: encoding: [0x66,0x0f,0xbe,0x1d,0xfe,0xca,0xbe,0xba]
+ movsbw 0xbabecafe,%bx
+
+// CHECK: movsbw 305419896, %bx
+// CHECK: encoding: [0x66,0x0f,0xbe,0x1d,0x78,0x56,0x34,0x12]
+ movsbw 0x12345678,%bx
+
+// CHECK: movswl 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0x0f,0xbf,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ movswl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movswl 69, %ecx
+// CHECK: encoding: [0x0f,0xbf,0x0d,0x45,0x00,0x00,0x00]
+ movswl 0x45,%ecx
+
+// CHECK: movswl 32493, %ecx
+// CHECK: encoding: [0x0f,0xbf,0x0d,0xed,0x7e,0x00,0x00]
+ movswl 0x7eed,%ecx
+
+// CHECK: movswl 3133065982, %ecx
+// CHECK: encoding: [0x0f,0xbf,0x0d,0xfe,0xca,0xbe,0xba]
+ movswl 0xbabecafe,%ecx
+
+// CHECK: movswl 305419896, %ecx
+// CHECK: encoding: [0x0f,0xbf,0x0d,0x78,0x56,0x34,0x12]
+ movswl 0x12345678,%ecx
+
+// CHECK: movzbl 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0x0f,0xb6,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ movzbl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movzbl 69, %ecx
+// CHECK: encoding: [0x0f,0xb6,0x0d,0x45,0x00,0x00,0x00]
+ movzbl 0x45,%ecx
+
+// CHECK: movzbl 32493, %ecx
+// CHECK: encoding: [0x0f,0xb6,0x0d,0xed,0x7e,0x00,0x00]
+ movzbl 0x7eed,%ecx
+
+// CHECK: movzbl 3133065982, %ecx
+// CHECK: encoding: [0x0f,0xb6,0x0d,0xfe,0xca,0xbe,0xba]
+ movzbl 0xbabecafe,%ecx
+
+// CHECK: movzbl 305419896, %ecx
+// CHECK: encoding: [0x0f,0xb6,0x0d,0x78,0x56,0x34,0x12]
+ movzbl 0x12345678,%ecx
+
+// CHECK: movzbw 3735928559(%ebx,%ecx,8), %bx
+// CHECK: encoding: [0x66,0x0f,0xb6,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movzbw 0xdeadbeef(%ebx,%ecx,8),%bx
+
+// CHECK: movzbw 69, %bx
+// CHECK: encoding: [0x66,0x0f,0xb6,0x1d,0x45,0x00,0x00,0x00]
+ movzbw 0x45,%bx
+
+// CHECK: movzbw 32493, %bx
+// CHECK: encoding: [0x66,0x0f,0xb6,0x1d,0xed,0x7e,0x00,0x00]
+ movzbw 0x7eed,%bx
+
+// CHECK: movzbw 3133065982, %bx
+// CHECK: encoding: [0x66,0x0f,0xb6,0x1d,0xfe,0xca,0xbe,0xba]
+ movzbw 0xbabecafe,%bx
+
+// CHECK: movzbw 305419896, %bx
+// CHECK: encoding: [0x66,0x0f,0xb6,0x1d,0x78,0x56,0x34,0x12]
+ movzbw 0x12345678,%bx
+
+// CHECK: movzwl 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0x0f,0xb7,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ movzwl 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: movzwl 69, %ecx
+// CHECK: encoding: [0x0f,0xb7,0x0d,0x45,0x00,0x00,0x00]
+ movzwl 0x45,%ecx
+
+// CHECK: movzwl 32493, %ecx
+// CHECK: encoding: [0x0f,0xb7,0x0d,0xed,0x7e,0x00,0x00]
+ movzwl 0x7eed,%ecx
+
+// CHECK: movzwl 3133065982, %ecx
+// CHECK: encoding: [0x0f,0xb7,0x0d,0xfe,0xca,0xbe,0xba]
+ movzwl 0xbabecafe,%ecx
+
+// CHECK: movzwl 305419896, %ecx
+// CHECK: encoding: [0x0f,0xb7,0x0d,0x78,0x56,0x34,0x12]
+ movzwl 0x12345678,%ecx
+
+// CHECK: pushl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ pushl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: pushw 32493
+// CHECK: encoding: [0x66,0xff,0x35,0xed,0x7e,0x00,0x00]
+ pushw 0x7eed
+
+// CHECK: pushl 3133065982
+// CHECK: encoding: [0xff,0x35,0xfe,0xca,0xbe,0xba]
+ pushl 0xbabecafe
+
+// CHECK: pushl 305419896
+// CHECK: encoding: [0xff,0x35,0x78,0x56,0x34,0x12]
+ pushl 0x12345678
+
+// CHECK: popl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x8f,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ popl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: popw 32493
+// CHECK: encoding: [0x66,0x8f,0x05,0xed,0x7e,0x00,0x00]
+ popw 0x7eed
+
+// CHECK: popl 3133065982
+// CHECK: encoding: [0x8f,0x05,0xfe,0xca,0xbe,0xba]
+ popl 0xbabecafe
+
+// CHECK: popl 305419896
+// CHECK: encoding: [0x8f,0x05,0x78,0x56,0x34,0x12]
+ popl 0x12345678
+
+// CHECK: clc
+// CHECK: encoding: [0xf8]
+ clc
+
+// CHECK: cld
+// CHECK: encoding: [0xfc]
+ cld
+
+// CHECK: cli
+// CHECK: encoding: [0xfa]
+ cli
+
+// CHECK: clts
+// CHECK: encoding: [0x0f,0x06]
+ clts
+
+// CHECK: cmc
+// CHECK: encoding: [0xf5]
+ cmc
+
+// CHECK: lahf
+// CHECK: encoding: [0x9f]
+ lahf
+
+// CHECK: sahf
+// CHECK: encoding: [0x9e]
+ sahf
+
+// CHECK: stc
+// CHECK: encoding: [0xf9]
+ stc
+
+// CHECK: std
+// CHECK: encoding: [0xfd]
+ std
+
+// CHECK: sti
+// CHECK: encoding: [0xfb]
+ sti
+
+// CHECK: addb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x84,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ addb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addb $254, 69
+// CHECK: encoding: [0x80,0x05,0x45,0x00,0x00,0x00,0xfe]
+ addb $0xfe,0x45
+
+// CHECK: addb $254, 32493
+// CHECK: encoding: [0x80,0x05,0xed,0x7e,0x00,0x00,0xfe]
+ addb $0xfe,0x7eed
+
+// CHECK: addb $254, 3133065982
+// CHECK: encoding: [0x80,0x05,0xfe,0xca,0xbe,0xba,0xfe]
+ addb $0xfe,0xbabecafe
+
+// CHECK: addb $254, 305419896
+// CHECK: encoding: [0x80,0x05,0x78,0x56,0x34,0x12,0xfe]
+ addb $0xfe,0x12345678
+
+// CHECK: addb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x84,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ addb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addb $127, 69
+// CHECK: encoding: [0x80,0x05,0x45,0x00,0x00,0x00,0x7f]
+ addb $0x7f,0x45
+
+// CHECK: addb $127, 32493
+// CHECK: encoding: [0x80,0x05,0xed,0x7e,0x00,0x00,0x7f]
+ addb $0x7f,0x7eed
+
+// CHECK: addb $127, 3133065982
+// CHECK: encoding: [0x80,0x05,0xfe,0xca,0xbe,0xba,0x7f]
+ addb $0x7f,0xbabecafe
+
+// CHECK: addb $127, 305419896
+// CHECK: encoding: [0x80,0x05,0x78,0x56,0x34,0x12,0x7f]
+ addb $0x7f,0x12345678
+
+// CHECK: addw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0x84,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ addw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x05,0x45,0x00,0x00,0x00,0xce,0x7a]
+ addw $0x7ace,0x45
+
+// CHECK: addw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x05,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ addw $0x7ace,0x7eed
+
+// CHECK: addw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x05,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ addw $0x7ace,0xbabecafe
+
+// CHECK: addw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x05,0x78,0x56,0x34,0x12,0xce,0x7a]
+ addw $0x7ace,0x12345678
+
+// CHECK: addl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x84,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ addl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addl $2063514302, 69
+// CHECK: encoding: [0x81,0x05,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ addl $0x7afebabe,0x45
+
+// CHECK: addl $2063514302, 32493
+// CHECK: encoding: [0x81,0x05,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ addl $0x7afebabe,0x7eed
+
+// CHECK: addl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x05,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ addl $0x7afebabe,0xbabecafe
+
+// CHECK: addl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x05,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ addl $0x7afebabe,0x12345678
+
+// CHECK: addl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x84,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ addl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: addl $324478056, 69
+// CHECK: encoding: [0x81,0x05,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ addl $0x13572468,0x45
+
+// CHECK: addl $324478056, 32493
+// CHECK: encoding: [0x81,0x05,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ addl $0x13572468,0x7eed
+
+// CHECK: addl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x05,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ addl $0x13572468,0xbabecafe
+
+// CHECK: addl $324478056, 305419896
+// CHECK: encoding: [0x81,0x05,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ addl $0x13572468,0x12345678
+
+// CHECK: incl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ incl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: incw 32493
+// CHECK: encoding: [0x66,0xff,0x05,0xed,0x7e,0x00,0x00]
+ incw 0x7eed
+
+// CHECK: incl 3133065982
+// CHECK: encoding: [0xff,0x05,0xfe,0xca,0xbe,0xba]
+ incl 0xbabecafe
+
+// CHECK: incl 305419896
+// CHECK: encoding: [0xff,0x05,0x78,0x56,0x34,0x12]
+ incl 0x12345678
+
+// CHECK: subb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xac,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ subb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subb $254, 69
+// CHECK: encoding: [0x80,0x2d,0x45,0x00,0x00,0x00,0xfe]
+ subb $0xfe,0x45
+
+// CHECK: subb $254, 32493
+// CHECK: encoding: [0x80,0x2d,0xed,0x7e,0x00,0x00,0xfe]
+ subb $0xfe,0x7eed
+
+// CHECK: subb $254, 3133065982
+// CHECK: encoding: [0x80,0x2d,0xfe,0xca,0xbe,0xba,0xfe]
+ subb $0xfe,0xbabecafe
+
+// CHECK: subb $254, 305419896
+// CHECK: encoding: [0x80,0x2d,0x78,0x56,0x34,0x12,0xfe]
+ subb $0xfe,0x12345678
+
+// CHECK: subb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xac,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ subb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subb $127, 69
+// CHECK: encoding: [0x80,0x2d,0x45,0x00,0x00,0x00,0x7f]
+ subb $0x7f,0x45
+
+// CHECK: subb $127, 32493
+// CHECK: encoding: [0x80,0x2d,0xed,0x7e,0x00,0x00,0x7f]
+ subb $0x7f,0x7eed
+
+// CHECK: subb $127, 3133065982
+// CHECK: encoding: [0x80,0x2d,0xfe,0xca,0xbe,0xba,0x7f]
+ subb $0x7f,0xbabecafe
+
+// CHECK: subb $127, 305419896
+// CHECK: encoding: [0x80,0x2d,0x78,0x56,0x34,0x12,0x7f]
+ subb $0x7f,0x12345678
+
+// CHECK: subw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0xac,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ subw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x2d,0x45,0x00,0x00,0x00,0xce,0x7a]
+ subw $0x7ace,0x45
+
+// CHECK: subw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x2d,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ subw $0x7ace,0x7eed
+
+// CHECK: subw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x2d,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ subw $0x7ace,0xbabecafe
+
+// CHECK: subw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x2d,0x78,0x56,0x34,0x12,0xce,0x7a]
+ subw $0x7ace,0x12345678
+
+// CHECK: subl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xac,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ subl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subl $2063514302, 69
+// CHECK: encoding: [0x81,0x2d,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ subl $0x7afebabe,0x45
+
+// CHECK: subl $2063514302, 32493
+// CHECK: encoding: [0x81,0x2d,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ subl $0x7afebabe,0x7eed
+
+// CHECK: subl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x2d,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ subl $0x7afebabe,0xbabecafe
+
+// CHECK: subl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x2d,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ subl $0x7afebabe,0x12345678
+
+// CHECK: subl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xac,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ subl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: subl $324478056, 69
+// CHECK: encoding: [0x81,0x2d,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ subl $0x13572468,0x45
+
+// CHECK: subl $324478056, 32493
+// CHECK: encoding: [0x81,0x2d,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ subl $0x13572468,0x7eed
+
+// CHECK: subl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x2d,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ subl $0x13572468,0xbabecafe
+
+// CHECK: subl $324478056, 305419896
+// CHECK: encoding: [0x81,0x2d,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ subl $0x13572468,0x12345678
+
+// CHECK: decl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ decl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: decw 32493
+// CHECK: encoding: [0x66,0xff,0x0d,0xed,0x7e,0x00,0x00]
+ decw 0x7eed
+
+// CHECK: decl 3133065982
+// CHECK: encoding: [0xff,0x0d,0xfe,0xca,0xbe,0xba]
+ decl 0xbabecafe
+
+// CHECK: decl 305419896
+// CHECK: encoding: [0xff,0x0d,0x78,0x56,0x34,0x12]
+ decl 0x12345678
+
+// CHECK: sbbb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x9c,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ sbbb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbb $254, 69
+// CHECK: encoding: [0x80,0x1d,0x45,0x00,0x00,0x00,0xfe]
+ sbbb $0xfe,0x45
+
+// CHECK: sbbb $254, 32493
+// CHECK: encoding: [0x80,0x1d,0xed,0x7e,0x00,0x00,0xfe]
+ sbbb $0xfe,0x7eed
+
+// CHECK: sbbb $254, 3133065982
+// CHECK: encoding: [0x80,0x1d,0xfe,0xca,0xbe,0xba,0xfe]
+ sbbb $0xfe,0xbabecafe
+
+// CHECK: sbbb $254, 305419896
+// CHECK: encoding: [0x80,0x1d,0x78,0x56,0x34,0x12,0xfe]
+ sbbb $0xfe,0x12345678
+
+// CHECK: sbbb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x9c,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ sbbb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbb $127, 69
+// CHECK: encoding: [0x80,0x1d,0x45,0x00,0x00,0x00,0x7f]
+ sbbb $0x7f,0x45
+
+// CHECK: sbbb $127, 32493
+// CHECK: encoding: [0x80,0x1d,0xed,0x7e,0x00,0x00,0x7f]
+ sbbb $0x7f,0x7eed
+
+// CHECK: sbbb $127, 3133065982
+// CHECK: encoding: [0x80,0x1d,0xfe,0xca,0xbe,0xba,0x7f]
+ sbbb $0x7f,0xbabecafe
+
+// CHECK: sbbb $127, 305419896
+// CHECK: encoding: [0x80,0x1d,0x78,0x56,0x34,0x12,0x7f]
+ sbbb $0x7f,0x12345678
+
+// CHECK: sbbw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0x9c,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ sbbw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x1d,0x45,0x00,0x00,0x00,0xce,0x7a]
+ sbbw $0x7ace,0x45
+
+// CHECK: sbbw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x1d,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ sbbw $0x7ace,0x7eed
+
+// CHECK: sbbw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x1d,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ sbbw $0x7ace,0xbabecafe
+
+// CHECK: sbbw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x1d,0x78,0x56,0x34,0x12,0xce,0x7a]
+ sbbw $0x7ace,0x12345678
+
+// CHECK: sbbl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x9c,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ sbbl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbl $2063514302, 69
+// CHECK: encoding: [0x81,0x1d,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ sbbl $0x7afebabe,0x45
+
+// CHECK: sbbl $2063514302, 32493
+// CHECK: encoding: [0x81,0x1d,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ sbbl $0x7afebabe,0x7eed
+
+// CHECK: sbbl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x1d,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ sbbl $0x7afebabe,0xbabecafe
+
+// CHECK: sbbl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x1d,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ sbbl $0x7afebabe,0x12345678
+
+// CHECK: sbbl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x9c,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ sbbl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sbbl $324478056, 69
+// CHECK: encoding: [0x81,0x1d,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ sbbl $0x13572468,0x45
+
+// CHECK: sbbl $324478056, 32493
+// CHECK: encoding: [0x81,0x1d,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ sbbl $0x13572468,0x7eed
+
+// CHECK: sbbl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x1d,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ sbbl $0x13572468,0xbabecafe
+
+// CHECK: sbbl $324478056, 305419896
+// CHECK: encoding: [0x81,0x1d,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ sbbl $0x13572468,0x12345678
+
+// CHECK: cmpb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xbc,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ cmpb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpb $254, 69
+// CHECK: encoding: [0x80,0x3d,0x45,0x00,0x00,0x00,0xfe]
+ cmpb $0xfe,0x45
+
+// CHECK: cmpb $254, 32493
+// CHECK: encoding: [0x80,0x3d,0xed,0x7e,0x00,0x00,0xfe]
+ cmpb $0xfe,0x7eed
+
+// CHECK: cmpb $254, 3133065982
+// CHECK: encoding: [0x80,0x3d,0xfe,0xca,0xbe,0xba,0xfe]
+ cmpb $0xfe,0xbabecafe
+
+// CHECK: cmpb $254, 305419896
+// CHECK: encoding: [0x80,0x3d,0x78,0x56,0x34,0x12,0xfe]
+ cmpb $0xfe,0x12345678
+
+// CHECK: cmpb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xbc,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ cmpb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpb $127, 69
+// CHECK: encoding: [0x80,0x3d,0x45,0x00,0x00,0x00,0x7f]
+ cmpb $0x7f,0x45
+
+// CHECK: cmpb $127, 32493
+// CHECK: encoding: [0x80,0x3d,0xed,0x7e,0x00,0x00,0x7f]
+ cmpb $0x7f,0x7eed
+
+// CHECK: cmpb $127, 3133065982
+// CHECK: encoding: [0x80,0x3d,0xfe,0xca,0xbe,0xba,0x7f]
+ cmpb $0x7f,0xbabecafe
+
+// CHECK: cmpb $127, 305419896
+// CHECK: encoding: [0x80,0x3d,0x78,0x56,0x34,0x12,0x7f]
+ cmpb $0x7f,0x12345678
+
+// CHECK: cmpw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0xbc,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ cmpw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x3d,0x45,0x00,0x00,0x00,0xce,0x7a]
+ cmpw $0x7ace,0x45
+
+// CHECK: cmpw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x3d,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ cmpw $0x7ace,0x7eed
+
+// CHECK: cmpw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x3d,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ cmpw $0x7ace,0xbabecafe
+
+// CHECK: cmpw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x3d,0x78,0x56,0x34,0x12,0xce,0x7a]
+ cmpw $0x7ace,0x12345678
+
+// CHECK: cmpl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xbc,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ cmpl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpl $2063514302, 69
+// CHECK: encoding: [0x81,0x3d,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ cmpl $0x7afebabe,0x45
+
+// CHECK: cmpl $2063514302, 32493
+// CHECK: encoding: [0x81,0x3d,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ cmpl $0x7afebabe,0x7eed
+
+// CHECK: cmpl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x3d,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ cmpl $0x7afebabe,0xbabecafe
+
+// CHECK: cmpl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x3d,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ cmpl $0x7afebabe,0x12345678
+
+// CHECK: cmpl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xbc,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ cmpl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpl $324478056, 69
+// CHECK: encoding: [0x81,0x3d,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ cmpl $0x13572468,0x45
+
+// CHECK: cmpl $324478056, 32493
+// CHECK: encoding: [0x81,0x3d,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ cmpl $0x13572468,0x7eed
+
+// CHECK: cmpl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x3d,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ cmpl $0x13572468,0xbabecafe
+
+// CHECK: cmpl $324478056, 305419896
+// CHECK: encoding: [0x81,0x3d,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ cmpl $0x13572468,0x12345678
+
+// CHECK: testb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf6,0x84,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ testb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testb $127, 69
+// CHECK: encoding: [0xf6,0x05,0x45,0x00,0x00,0x00,0x7f]
+ testb $0x7f,0x45
+
+// CHECK: testb $127, 32493
+// CHECK: encoding: [0xf6,0x05,0xed,0x7e,0x00,0x00,0x7f]
+ testb $0x7f,0x7eed
+
+// CHECK: testb $127, 3133065982
+// CHECK: encoding: [0xf6,0x05,0xfe,0xca,0xbe,0xba,0x7f]
+ testb $0x7f,0xbabecafe
+
+// CHECK: testb $127, 305419896
+// CHECK: encoding: [0xf6,0x05,0x78,0x56,0x34,0x12,0x7f]
+ testb $0x7f,0x12345678
+
+// CHECK: testw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0xf7,0x84,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ testw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testw $31438, 69
+// CHECK: encoding: [0x66,0xf7,0x05,0x45,0x00,0x00,0x00,0xce,0x7a]
+ testw $0x7ace,0x45
+
+// CHECK: testw $31438, 32493
+// CHECK: encoding: [0x66,0xf7,0x05,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ testw $0x7ace,0x7eed
+
+// CHECK: testw $31438, 3133065982
+// CHECK: encoding: [0x66,0xf7,0x05,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ testw $0x7ace,0xbabecafe
+
+// CHECK: testw $31438, 305419896
+// CHECK: encoding: [0x66,0xf7,0x05,0x78,0x56,0x34,0x12,0xce,0x7a]
+ testw $0x7ace,0x12345678
+
+// CHECK: testl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0x84,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ testl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testl $2063514302, 69
+// CHECK: encoding: [0xf7,0x05,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ testl $0x7afebabe,0x45
+
+// CHECK: testl $2063514302, 32493
+// CHECK: encoding: [0xf7,0x05,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ testl $0x7afebabe,0x7eed
+
+// CHECK: testl $2063514302, 3133065982
+// CHECK: encoding: [0xf7,0x05,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ testl $0x7afebabe,0xbabecafe
+
+// CHECK: testl $2063514302, 305419896
+// CHECK: encoding: [0xf7,0x05,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ testl $0x7afebabe,0x12345678
+
+// CHECK: testl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0x84,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ testl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: testl $324478056, 69
+// CHECK: encoding: [0xf7,0x05,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ testl $0x13572468,0x45
+
+// CHECK: testl $324478056, 32493
+// CHECK: encoding: [0xf7,0x05,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ testl $0x13572468,0x7eed
+
+// CHECK: testl $324478056, 3133065982
+// CHECK: encoding: [0xf7,0x05,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ testl $0x13572468,0xbabecafe
+
+// CHECK: testl $324478056, 305419896
+// CHECK: encoding: [0xf7,0x05,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ testl $0x13572468,0x12345678
+
+// CHECK: andb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xa4,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ andb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andb $254, 69
+// CHECK: encoding: [0x80,0x25,0x45,0x00,0x00,0x00,0xfe]
+ andb $0xfe,0x45
+
+// CHECK: andb $254, 32493
+// CHECK: encoding: [0x80,0x25,0xed,0x7e,0x00,0x00,0xfe]
+ andb $0xfe,0x7eed
+
+// CHECK: andb $254, 3133065982
+// CHECK: encoding: [0x80,0x25,0xfe,0xca,0xbe,0xba,0xfe]
+ andb $0xfe,0xbabecafe
+
+// CHECK: andb $254, 305419896
+// CHECK: encoding: [0x80,0x25,0x78,0x56,0x34,0x12,0xfe]
+ andb $0xfe,0x12345678
+
+// CHECK: andb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ andb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andb $127, 69
+// CHECK: encoding: [0x80,0x25,0x45,0x00,0x00,0x00,0x7f]
+ andb $0x7f,0x45
+
+// CHECK: andb $127, 32493
+// CHECK: encoding: [0x80,0x25,0xed,0x7e,0x00,0x00,0x7f]
+ andb $0x7f,0x7eed
+
+// CHECK: andb $127, 3133065982
+// CHECK: encoding: [0x80,0x25,0xfe,0xca,0xbe,0xba,0x7f]
+ andb $0x7f,0xbabecafe
+
+// CHECK: andb $127, 305419896
+// CHECK: encoding: [0x80,0x25,0x78,0x56,0x34,0x12,0x7f]
+ andb $0x7f,0x12345678
+
+// CHECK: andw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0xa4,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ andw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x25,0x45,0x00,0x00,0x00,0xce,0x7a]
+ andw $0x7ace,0x45
+
+// CHECK: andw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x25,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ andw $0x7ace,0x7eed
+
+// CHECK: andw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x25,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ andw $0x7ace,0xbabecafe
+
+// CHECK: andw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x25,0x78,0x56,0x34,0x12,0xce,0x7a]
+ andw $0x7ace,0x12345678
+
+// CHECK: andl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xa4,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ andl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andl $2063514302, 69
+// CHECK: encoding: [0x81,0x25,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ andl $0x7afebabe,0x45
+
+// CHECK: andl $2063514302, 32493
+// CHECK: encoding: [0x81,0x25,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ andl $0x7afebabe,0x7eed
+
+// CHECK: andl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x25,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ andl $0x7afebabe,0xbabecafe
+
+// CHECK: andl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x25,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ andl $0x7afebabe,0x12345678
+
+// CHECK: andl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ andl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: andl $324478056, 69
+// CHECK: encoding: [0x81,0x25,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ andl $0x13572468,0x45
+
+// CHECK: andl $324478056, 32493
+// CHECK: encoding: [0x81,0x25,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ andl $0x13572468,0x7eed
+
+// CHECK: andl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x25,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ andl $0x13572468,0xbabecafe
+
+// CHECK: andl $324478056, 305419896
+// CHECK: encoding: [0x81,0x25,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ andl $0x13572468,0x12345678
+
+// CHECK: orb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x8c,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ orb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orb $254, 69
+// CHECK: encoding: [0x80,0x0d,0x45,0x00,0x00,0x00,0xfe]
+ orb $0xfe,0x45
+
+// CHECK: orb $254, 32493
+// CHECK: encoding: [0x80,0x0d,0xed,0x7e,0x00,0x00,0xfe]
+ orb $0xfe,0x7eed
+
+// CHECK: orb $254, 3133065982
+// CHECK: encoding: [0x80,0x0d,0xfe,0xca,0xbe,0xba,0xfe]
+ orb $0xfe,0xbabecafe
+
+// CHECK: orb $254, 305419896
+// CHECK: encoding: [0x80,0x0d,0x78,0x56,0x34,0x12,0xfe]
+ orb $0xfe,0x12345678
+
+// CHECK: orb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x8c,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ orb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orb $127, 69
+// CHECK: encoding: [0x80,0x0d,0x45,0x00,0x00,0x00,0x7f]
+ orb $0x7f,0x45
+
+// CHECK: orb $127, 32493
+// CHECK: encoding: [0x80,0x0d,0xed,0x7e,0x00,0x00,0x7f]
+ orb $0x7f,0x7eed
+
+// CHECK: orb $127, 3133065982
+// CHECK: encoding: [0x80,0x0d,0xfe,0xca,0xbe,0xba,0x7f]
+ orb $0x7f,0xbabecafe
+
+// CHECK: orb $127, 305419896
+// CHECK: encoding: [0x80,0x0d,0x78,0x56,0x34,0x12,0x7f]
+ orb $0x7f,0x12345678
+
+// CHECK: orw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0x8c,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ orw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x0d,0x45,0x00,0x00,0x00,0xce,0x7a]
+ orw $0x7ace,0x45
+
+// CHECK: orw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x0d,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ orw $0x7ace,0x7eed
+
+// CHECK: orw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x0d,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ orw $0x7ace,0xbabecafe
+
+// CHECK: orw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x0d,0x78,0x56,0x34,0x12,0xce,0x7a]
+ orw $0x7ace,0x12345678
+
+// CHECK: orl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x8c,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ orl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orl $2063514302, 69
+// CHECK: encoding: [0x81,0x0d,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ orl $0x7afebabe,0x45
+
+// CHECK: orl $2063514302, 32493
+// CHECK: encoding: [0x81,0x0d,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ orl $0x7afebabe,0x7eed
+
+// CHECK: orl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x0d,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ orl $0x7afebabe,0xbabecafe
+
+// CHECK: orl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x0d,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ orl $0x7afebabe,0x12345678
+
+// CHECK: orl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x8c,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ orl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: orl $324478056, 69
+// CHECK: encoding: [0x81,0x0d,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ orl $0x13572468,0x45
+
+// CHECK: orl $324478056, 32493
+// CHECK: encoding: [0x81,0x0d,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ orl $0x13572468,0x7eed
+
+// CHECK: orl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x0d,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ orl $0x13572468,0xbabecafe
+
+// CHECK: orl $324478056, 305419896
+// CHECK: encoding: [0x81,0x0d,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ orl $0x13572468,0x12345678
+
+// CHECK: xorb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xb4,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ xorb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorb $254, 69
+// CHECK: encoding: [0x80,0x35,0x45,0x00,0x00,0x00,0xfe]
+ xorb $0xfe,0x45
+
+// CHECK: xorb $254, 32493
+// CHECK: encoding: [0x80,0x35,0xed,0x7e,0x00,0x00,0xfe]
+ xorb $0xfe,0x7eed
+
+// CHECK: xorb $254, 3133065982
+// CHECK: encoding: [0x80,0x35,0xfe,0xca,0xbe,0xba,0xfe]
+ xorb $0xfe,0xbabecafe
+
+// CHECK: xorb $254, 305419896
+// CHECK: encoding: [0x80,0x35,0x78,0x56,0x34,0x12,0xfe]
+ xorb $0xfe,0x12345678
+
+// CHECK: xorb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0xb4,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ xorb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorb $127, 69
+// CHECK: encoding: [0x80,0x35,0x45,0x00,0x00,0x00,0x7f]
+ xorb $0x7f,0x45
+
+// CHECK: xorb $127, 32493
+// CHECK: encoding: [0x80,0x35,0xed,0x7e,0x00,0x00,0x7f]
+ xorb $0x7f,0x7eed
+
+// CHECK: xorb $127, 3133065982
+// CHECK: encoding: [0x80,0x35,0xfe,0xca,0xbe,0xba,0x7f]
+ xorb $0x7f,0xbabecafe
+
+// CHECK: xorb $127, 305419896
+// CHECK: encoding: [0x80,0x35,0x78,0x56,0x34,0x12,0x7f]
+ xorb $0x7f,0x12345678
+
+// CHECK: xorw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0xb4,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ xorw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x35,0x45,0x00,0x00,0x00,0xce,0x7a]
+ xorw $0x7ace,0x45
+
+// CHECK: xorw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x35,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ xorw $0x7ace,0x7eed
+
+// CHECK: xorw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x35,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ xorw $0x7ace,0xbabecafe
+
+// CHECK: xorw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x35,0x78,0x56,0x34,0x12,0xce,0x7a]
+ xorw $0x7ace,0x12345678
+
+// CHECK: xorl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xb4,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ xorl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorl $2063514302, 69
+// CHECK: encoding: [0x81,0x35,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ xorl $0x7afebabe,0x45
+
+// CHECK: xorl $2063514302, 32493
+// CHECK: encoding: [0x81,0x35,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ xorl $0x7afebabe,0x7eed
+
+// CHECK: xorl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x35,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ xorl $0x7afebabe,0xbabecafe
+
+// CHECK: xorl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x35,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ xorl $0x7afebabe,0x12345678
+
+// CHECK: xorl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0xb4,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ xorl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: xorl $324478056, 69
+// CHECK: encoding: [0x81,0x35,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ xorl $0x13572468,0x45
+
+// CHECK: xorl $324478056, 32493
+// CHECK: encoding: [0x81,0x35,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ xorl $0x13572468,0x7eed
+
+// CHECK: xorl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x35,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ xorl $0x13572468,0xbabecafe
+
+// CHECK: xorl $324478056, 305419896
+// CHECK: encoding: [0x81,0x35,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ xorl $0x13572468,0x12345678
+
+// CHECK: adcb $254, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x94,0xcb,0xef,0xbe,0xad,0xde,0xfe]
+ adcb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcb $254, 69
+// CHECK: encoding: [0x80,0x15,0x45,0x00,0x00,0x00,0xfe]
+ adcb $0xfe,0x45
+
+// CHECK: adcb $254, 32493
+// CHECK: encoding: [0x80,0x15,0xed,0x7e,0x00,0x00,0xfe]
+ adcb $0xfe,0x7eed
+
+// CHECK: adcb $254, 3133065982
+// CHECK: encoding: [0x80,0x15,0xfe,0xca,0xbe,0xba,0xfe]
+ adcb $0xfe,0xbabecafe
+
+// CHECK: adcb $254, 305419896
+// CHECK: encoding: [0x80,0x15,0x78,0x56,0x34,0x12,0xfe]
+ adcb $0xfe,0x12345678
+
+// CHECK: adcb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x80,0x94,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ adcb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcb $127, 69
+// CHECK: encoding: [0x80,0x15,0x45,0x00,0x00,0x00,0x7f]
+ adcb $0x7f,0x45
+
+// CHECK: adcb $127, 32493
+// CHECK: encoding: [0x80,0x15,0xed,0x7e,0x00,0x00,0x7f]
+ adcb $0x7f,0x7eed
+
+// CHECK: adcb $127, 3133065982
+// CHECK: encoding: [0x80,0x15,0xfe,0xca,0xbe,0xba,0x7f]
+ adcb $0x7f,0xbabecafe
+
+// CHECK: adcb $127, 305419896
+// CHECK: encoding: [0x80,0x15,0x78,0x56,0x34,0x12,0x7f]
+ adcb $0x7f,0x12345678
+
+// CHECK: adcw $31438, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x81,0x94,0xcb,0xef,0xbe,0xad,0xde,0xce,0x7a]
+ adcw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcw $31438, 69
+// CHECK: encoding: [0x66,0x81,0x15,0x45,0x00,0x00,0x00,0xce,0x7a]
+ adcw $0x7ace,0x45
+
+// CHECK: adcw $31438, 32493
+// CHECK: encoding: [0x66,0x81,0x15,0xed,0x7e,0x00,0x00,0xce,0x7a]
+ adcw $0x7ace,0x7eed
+
+// CHECK: adcw $31438, 3133065982
+// CHECK: encoding: [0x66,0x81,0x15,0xfe,0xca,0xbe,0xba,0xce,0x7a]
+ adcw $0x7ace,0xbabecafe
+
+// CHECK: adcw $31438, 305419896
+// CHECK: encoding: [0x66,0x81,0x15,0x78,0x56,0x34,0x12,0xce,0x7a]
+ adcw $0x7ace,0x12345678
+
+// CHECK: adcl $2063514302, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x94,0xcb,0xef,0xbe,0xad,0xde,0xbe,0xba,0xfe,0x7a]
+ adcl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcl $2063514302, 69
+// CHECK: encoding: [0x81,0x15,0x45,0x00,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ adcl $0x7afebabe,0x45
+
+// CHECK: adcl $2063514302, 32493
+// CHECK: encoding: [0x81,0x15,0xed,0x7e,0x00,0x00,0xbe,0xba,0xfe,0x7a]
+ adcl $0x7afebabe,0x7eed
+
+// CHECK: adcl $2063514302, 3133065982
+// CHECK: encoding: [0x81,0x15,0xfe,0xca,0xbe,0xba,0xbe,0xba,0xfe,0x7a]
+ adcl $0x7afebabe,0xbabecafe
+
+// CHECK: adcl $2063514302, 305419896
+// CHECK: encoding: [0x81,0x15,0x78,0x56,0x34,0x12,0xbe,0xba,0xfe,0x7a]
+ adcl $0x7afebabe,0x12345678
+
+// CHECK: adcl $324478056, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x81,0x94,0xcb,0xef,0xbe,0xad,0xde,0x68,0x24,0x57,0x13]
+ adcl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: adcl $324478056, 69
+// CHECK: encoding: [0x81,0x15,0x45,0x00,0x00,0x00,0x68,0x24,0x57,0x13]
+ adcl $0x13572468,0x45
+
+// CHECK: adcl $324478056, 32493
+// CHECK: encoding: [0x81,0x15,0xed,0x7e,0x00,0x00,0x68,0x24,0x57,0x13]
+ adcl $0x13572468,0x7eed
+
+// CHECK: adcl $324478056, 3133065982
+// CHECK: encoding: [0x81,0x15,0xfe,0xca,0xbe,0xba,0x68,0x24,0x57,0x13]
+ adcl $0x13572468,0xbabecafe
+
+// CHECK: adcl $324478056, 305419896
+// CHECK: encoding: [0x81,0x15,0x78,0x56,0x34,0x12,0x68,0x24,0x57,0x13]
+ adcl $0x13572468,0x12345678
+
+// CHECK: negl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ negl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: negw 32493
+// CHECK: encoding: [0x66,0xf7,0x1d,0xed,0x7e,0x00,0x00]
+ negw 0x7eed
+
+// CHECK: negl 3133065982
+// CHECK: encoding: [0xf7,0x1d,0xfe,0xca,0xbe,0xba]
+ negl 0xbabecafe
+
+// CHECK: negl 305419896
+// CHECK: encoding: [0xf7,0x1d,0x78,0x56,0x34,0x12]
+ negl 0x12345678
+
+// CHECK: notl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ notl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: notw 32493
+// CHECK: encoding: [0x66,0xf7,0x15,0xed,0x7e,0x00,0x00]
+ notw 0x7eed
+
+// CHECK: notl 3133065982
+// CHECK: encoding: [0xf7,0x15,0xfe,0xca,0xbe,0xba]
+ notl 0xbabecafe
+
+// CHECK: notl 305419896
+// CHECK: encoding: [0xf7,0x15,0x78,0x56,0x34,0x12]
+ notl 0x12345678
+
+// CHECK: cbtw
+// CHECK: encoding: [0x66,0x98]
+ cbtw
+
+// CHECK: cwtl
+// CHECK: encoding: [0x98]
+ cwtl
+
+// CHECK: cwtd
+// CHECK: encoding: [0x66,0x99]
+ cwtd
+
+// CHECK: cltd
+// CHECK: encoding: [0x99]
+ cltd
+
+// CHECK: mull 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ mull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: mulw 32493
+// CHECK: encoding: [0x66,0xf7,0x25,0xed,0x7e,0x00,0x00]
+ mulw 0x7eed
+
+// CHECK: mull 3133065982
+// CHECK: encoding: [0xf7,0x25,0xfe,0xca,0xbe,0xba]
+ mull 0xbabecafe
+
+// CHECK: mull 305419896
+// CHECK: encoding: [0xf7,0x25,0x78,0x56,0x34,0x12]
+ mull 0x12345678
+
+// CHECK: imull 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ imull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: imulw 32493
+// CHECK: encoding: [0x66,0xf7,0x2d,0xed,0x7e,0x00,0x00]
+ imulw 0x7eed
+
+// CHECK: imull 3133065982
+// CHECK: encoding: [0xf7,0x2d,0xfe,0xca,0xbe,0xba]
+ imull 0xbabecafe
+
+// CHECK: imull 305419896
+// CHECK: encoding: [0xf7,0x2d,0x78,0x56,0x34,0x12]
+ imull 0x12345678
+
+// CHECK: divl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ divl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: divw 32493
+// CHECK: encoding: [0x66,0xf7,0x35,0xed,0x7e,0x00,0x00]
+ divw 0x7eed
+
+// CHECK: divl 3133065982
+// CHECK: encoding: [0xf7,0x35,0xfe,0xca,0xbe,0xba]
+ divl 0xbabecafe
+
+// CHECK: divl 305419896
+// CHECK: encoding: [0xf7,0x35,0x78,0x56,0x34,0x12]
+ divl 0x12345678
+
+// CHECK: idivl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf7,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ idivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: idivw 32493
+// CHECK: encoding: [0x66,0xf7,0x3d,0xed,0x7e,0x00,0x00]
+ idivw 0x7eed
+
+// CHECK: idivl 3133065982
+// CHECK: encoding: [0xf7,0x3d,0xfe,0xca,0xbe,0xba]
+ idivl 0xbabecafe
+
+// CHECK: idivl 305419896
+// CHECK: encoding: [0xf7,0x3d,0x78,0x56,0x34,0x12]
+ idivl 0x12345678
+
+// CHECK: roll $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0x84,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ roll $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: roll $0, 69
+// CHECK: encoding: [0xc1,0x05,0x45,0x00,0x00,0x00,0x00]
+ roll $0,0x45
+
+// CHECK: roll $0, 32493
+// CHECK: encoding: [0xc1,0x05,0xed,0x7e,0x00,0x00,0x00]
+ roll $0,0x7eed
+
+// CHECK: roll $0, 3133065982
+// CHECK: encoding: [0xc1,0x05,0xfe,0xca,0xbe,0xba,0x00]
+ roll $0,0xbabecafe
+
+// CHECK: roll $0, 305419896
+// CHECK: encoding: [0xc1,0x05,0x78,0x56,0x34,0x12,0x00]
+ roll $0,0x12345678
+
+// CHECK: rolb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0x84,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ rolb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rolb $127, 69
+// CHECK: encoding: [0xc0,0x05,0x45,0x00,0x00,0x00,0x7f]
+ rolb $0x7f,0x45
+
+// CHECK: rolb $127, 32493
+// CHECK: encoding: [0xc0,0x05,0xed,0x7e,0x00,0x00,0x7f]
+ rolb $0x7f,0x7eed
+
+// CHECK: rolb $127, 3133065982
+// CHECK: encoding: [0xc0,0x05,0xfe,0xca,0xbe,0xba,0x7f]
+ rolb $0x7f,0xbabecafe
+
+// CHECK: rolb $127, 305419896
+// CHECK: encoding: [0xc0,0x05,0x78,0x56,0x34,0x12,0x7f]
+ rolb $0x7f,0x12345678
+
+// CHECK: roll 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ roll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rolw 32493
+// CHECK: encoding: [0x66,0xd1,0x05,0xed,0x7e,0x00,0x00]
+ rolw 0x7eed
+
+// CHECK: roll 3133065982
+// CHECK: encoding: [0xd1,0x05,0xfe,0xca,0xbe,0xba]
+ roll 0xbabecafe
+
+// CHECK: roll 305419896
+// CHECK: encoding: [0xd1,0x05,0x78,0x56,0x34,0x12]
+ roll 0x12345678
+
+// CHECK: rorl $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0x8c,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ rorl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorl $0, 69
+// CHECK: encoding: [0xc1,0x0d,0x45,0x00,0x00,0x00,0x00]
+ rorl $0,0x45
+
+// CHECK: rorl $0, 32493
+// CHECK: encoding: [0xc1,0x0d,0xed,0x7e,0x00,0x00,0x00]
+ rorl $0,0x7eed
+
+// CHECK: rorl $0, 3133065982
+// CHECK: encoding: [0xc1,0x0d,0xfe,0xca,0xbe,0xba,0x00]
+ rorl $0,0xbabecafe
+
+// CHECK: rorl $0, 305419896
+// CHECK: encoding: [0xc1,0x0d,0x78,0x56,0x34,0x12,0x00]
+ rorl $0,0x12345678
+
+// CHECK: rorb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0x8c,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ rorb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorb $127, 69
+// CHECK: encoding: [0xc0,0x0d,0x45,0x00,0x00,0x00,0x7f]
+ rorb $0x7f,0x45
+
+// CHECK: rorb $127, 32493
+// CHECK: encoding: [0xc0,0x0d,0xed,0x7e,0x00,0x00,0x7f]
+ rorb $0x7f,0x7eed
+
+// CHECK: rorb $127, 3133065982
+// CHECK: encoding: [0xc0,0x0d,0xfe,0xca,0xbe,0xba,0x7f]
+ rorb $0x7f,0xbabecafe
+
+// CHECK: rorb $127, 305419896
+// CHECK: encoding: [0xc0,0x0d,0x78,0x56,0x34,0x12,0x7f]
+ rorb $0x7f,0x12345678
+
+// CHECK: rorl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ rorl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: rorw 32493
+// CHECK: encoding: [0x66,0xd1,0x0d,0xed,0x7e,0x00,0x00]
+ rorw 0x7eed
+
+// CHECK: rorl 3133065982
+// CHECK: encoding: [0xd1,0x0d,0xfe,0xca,0xbe,0xba]
+ rorl 0xbabecafe
+
+// CHECK: rorl 305419896
+// CHECK: encoding: [0xd1,0x0d,0x78,0x56,0x34,0x12]
+ rorl 0x12345678
+
+// CHECK: shll $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ sall $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shll $0, 69
+// CHECK: encoding: [0xc1,0x25,0x45,0x00,0x00,0x00,0x00]
+ sall $0,0x45
+
+// CHECK: shll $0, 32493
+// CHECK: encoding: [0xc1,0x25,0xed,0x7e,0x00,0x00,0x00]
+ sall $0,0x7eed
+
+// CHECK: shll $0, 3133065982
+// CHECK: encoding: [0xc1,0x25,0xfe,0xca,0xbe,0xba,0x00]
+ sall $0,0xbabecafe
+
+// CHECK: shll $0, 305419896
+// CHECK: encoding: [0xc1,0x25,0x78,0x56,0x34,0x12,0x00]
+ sall $0,0x12345678
+
+// CHECK: shlb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ salb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlb $127, 69
+// CHECK: encoding: [0xc0,0x25,0x45,0x00,0x00,0x00,0x7f]
+ salb $0x7f,0x45
+
+// CHECK: shlb $127, 32493
+// CHECK: encoding: [0xc0,0x25,0xed,0x7e,0x00,0x00,0x7f]
+ salb $0x7f,0x7eed
+
+// CHECK: shlb $127, 3133065982
+// CHECK: encoding: [0xc0,0x25,0xfe,0xca,0xbe,0xba,0x7f]
+ salb $0x7f,0xbabecafe
+
+// CHECK: shlb $127, 305419896
+// CHECK: encoding: [0xc0,0x25,0x78,0x56,0x34,0x12,0x7f]
+ salb $0x7f,0x12345678
+
+// CHECK: shll 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ sall 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlw 32493
+// CHECK: encoding: [0x66,0xd1,0x25,0xed,0x7e,0x00,0x00]
+ salw 0x7eed
+
+// CHECK: shll 3133065982
+// CHECK: encoding: [0xd1,0x25,0xfe,0xca,0xbe,0xba]
+ sall 0xbabecafe
+
+// CHECK: shll 305419896
+// CHECK: encoding: [0xd1,0x25,0x78,0x56,0x34,0x12]
+ sall 0x12345678
+
+// CHECK: shll $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ shll $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shll $0, 69
+// CHECK: encoding: [0xc1,0x25,0x45,0x00,0x00,0x00,0x00]
+ shll $0,0x45
+
+// CHECK: shll $0, 32493
+// CHECK: encoding: [0xc1,0x25,0xed,0x7e,0x00,0x00,0x00]
+ shll $0,0x7eed
+
+// CHECK: shll $0, 3133065982
+// CHECK: encoding: [0xc1,0x25,0xfe,0xca,0xbe,0xba,0x00]
+ shll $0,0xbabecafe
+
+// CHECK: shll $0, 305419896
+// CHECK: encoding: [0xc1,0x25,0x78,0x56,0x34,0x12,0x00]
+ shll $0,0x12345678
+
+// CHECK: shlb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0xa4,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ shlb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlb $127, 69
+// CHECK: encoding: [0xc0,0x25,0x45,0x00,0x00,0x00,0x7f]
+ shlb $0x7f,0x45
+
+// CHECK: shlb $127, 32493
+// CHECK: encoding: [0xc0,0x25,0xed,0x7e,0x00,0x00,0x7f]
+ shlb $0x7f,0x7eed
+
+// CHECK: shlb $127, 3133065982
+// CHECK: encoding: [0xc0,0x25,0xfe,0xca,0xbe,0xba,0x7f]
+ shlb $0x7f,0xbabecafe
+
+// CHECK: shlb $127, 305419896
+// CHECK: encoding: [0xc0,0x25,0x78,0x56,0x34,0x12,0x7f]
+ shlb $0x7f,0x12345678
+
+// CHECK: shll 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ shll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shlw 32493
+// CHECK: encoding: [0x66,0xd1,0x25,0xed,0x7e,0x00,0x00]
+ shlw 0x7eed
+
+// CHECK: shll 3133065982
+// CHECK: encoding: [0xd1,0x25,0xfe,0xca,0xbe,0xba]
+ shll 0xbabecafe
+
+// CHECK: shll 305419896
+// CHECK: encoding: [0xd1,0x25,0x78,0x56,0x34,0x12]
+ shll 0x12345678
+
+// CHECK: shrl $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0xac,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ shrl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrl $0, 69
+// CHECK: encoding: [0xc1,0x2d,0x45,0x00,0x00,0x00,0x00]
+ shrl $0,0x45
+
+// CHECK: shrl $0, 32493
+// CHECK: encoding: [0xc1,0x2d,0xed,0x7e,0x00,0x00,0x00]
+ shrl $0,0x7eed
+
+// CHECK: shrl $0, 3133065982
+// CHECK: encoding: [0xc1,0x2d,0xfe,0xca,0xbe,0xba,0x00]
+ shrl $0,0xbabecafe
+
+// CHECK: shrl $0, 305419896
+// CHECK: encoding: [0xc1,0x2d,0x78,0x56,0x34,0x12,0x00]
+ shrl $0,0x12345678
+
+// CHECK: shrb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0xac,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ shrb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrb $127, 69
+// CHECK: encoding: [0xc0,0x2d,0x45,0x00,0x00,0x00,0x7f]
+ shrb $0x7f,0x45
+
+// CHECK: shrb $127, 32493
+// CHECK: encoding: [0xc0,0x2d,0xed,0x7e,0x00,0x00,0x7f]
+ shrb $0x7f,0x7eed
+
+// CHECK: shrb $127, 3133065982
+// CHECK: encoding: [0xc0,0x2d,0xfe,0xca,0xbe,0xba,0x7f]
+ shrb $0x7f,0xbabecafe
+
+// CHECK: shrb $127, 305419896
+// CHECK: encoding: [0xc0,0x2d,0x78,0x56,0x34,0x12,0x7f]
+ shrb $0x7f,0x12345678
+
+// CHECK: shrl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ shrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: shrw 32493
+// CHECK: encoding: [0x66,0xd1,0x2d,0xed,0x7e,0x00,0x00]
+ shrw 0x7eed
+
+// CHECK: shrl 3133065982
+// CHECK: encoding: [0xd1,0x2d,0xfe,0xca,0xbe,0xba]
+ shrl 0xbabecafe
+
+// CHECK: shrl 305419896
+// CHECK: encoding: [0xd1,0x2d,0x78,0x56,0x34,0x12]
+ shrl 0x12345678
+
+// CHECK: sarl $0, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc1,0xbc,0xcb,0xef,0xbe,0xad,0xde,0x00]
+ sarl $0,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarl $0, 69
+// CHECK: encoding: [0xc1,0x3d,0x45,0x00,0x00,0x00,0x00]
+ sarl $0,0x45
+
+// CHECK: sarl $0, 32493
+// CHECK: encoding: [0xc1,0x3d,0xed,0x7e,0x00,0x00,0x00]
+ sarl $0,0x7eed
+
+// CHECK: sarl $0, 3133065982
+// CHECK: encoding: [0xc1,0x3d,0xfe,0xca,0xbe,0xba,0x00]
+ sarl $0,0xbabecafe
+
+// CHECK: sarl $0, 305419896
+// CHECK: encoding: [0xc1,0x3d,0x78,0x56,0x34,0x12,0x00]
+ sarl $0,0x12345678
+
+// CHECK: sarb $127, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xc0,0xbc,0xcb,0xef,0xbe,0xad,0xde,0x7f]
+ sarb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarb $127, 69
+// CHECK: encoding: [0xc0,0x3d,0x45,0x00,0x00,0x00,0x7f]
+ sarb $0x7f,0x45
+
+// CHECK: sarb $127, 32493
+// CHECK: encoding: [0xc0,0x3d,0xed,0x7e,0x00,0x00,0x7f]
+ sarb $0x7f,0x7eed
+
+// CHECK: sarb $127, 3133065982
+// CHECK: encoding: [0xc0,0x3d,0xfe,0xca,0xbe,0xba,0x7f]
+ sarb $0x7f,0xbabecafe
+
+// CHECK: sarb $127, 305419896
+// CHECK: encoding: [0xc0,0x3d,0x78,0x56,0x34,0x12,0x7f]
+ sarb $0x7f,0x12345678
+
+// CHECK: sarl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd1,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ sarl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sarw 32493
+// CHECK: encoding: [0x66,0xd1,0x3d,0xed,0x7e,0x00,0x00]
+ sarw 0x7eed
+
+// CHECK: sarl 3133065982
+// CHECK: encoding: [0xd1,0x3d,0xfe,0xca,0xbe,0xba]
+ sarl 0xbabecafe
+
+// CHECK: sarl 305419896
+// CHECK: encoding: [0xd1,0x3d,0x78,0x56,0x34,0x12]
+ sarl 0x12345678
+
+// CHECK: call *%ecx
+// CHECK: encoding: [0xff,0xd1]
+ call *%ecx
+
+// CHECK: call *3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ call *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: call *3135175374
+// CHECK: encoding: [0xff,0x15,0xce,0xfa,0xde,0xba]
+ call *0xbadeface
+
+// CHECK: call *3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ call *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: call *3135175374
+// CHECK: encoding: [0xff,0x15,0xce,0xfa,0xde,0xba]
+ call *0xbadeface
+
+// CHECK: lcallw *32493
+// CHECK: encoding: [0x66,0xff,0x1d,0xed,0x7e,0x00,0x00]
+ lcallw *0x7eed
+
+// CHECK: jmp *3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ jmp *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: jmp *3135175374
+// CHECK: encoding: [0xff,0x25,0xce,0xfa,0xde,0xba]
+ jmp *0xbadeface
+
+// CHECK: jmp *3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ jmp *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: jmp *3135175374
+// CHECK: encoding: [0xff,0x25,0xce,0xfa,0xde,0xba]
+ jmp *0xbadeface
+
+// CHECK: ljmpl *3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xff,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ ljmpl *0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ljmpw *32493
+// CHECK: encoding: [0x66,0xff,0x2d,0xed,0x7e,0x00,0x00]
+ ljmpw *0x7eed
+
+// CHECK: ljmpl *3133065982
+// CHECK: encoding: [0xff,0x2d,0xfe,0xca,0xbe,0xba]
+ ljmpl *0xbabecafe
+
+// CHECK: ljmpl *305419896
+// CHECK: encoding: [0xff,0x2d,0x78,0x56,0x34,0x12]
+ ljmpl *0x12345678
+
+// CHECK: ret
+// CHECK: encoding: [0xc3]
+ ret
+
+// CHECK: lret
+// CHECK: encoding: [0xcb]
+ lret
+
+// CHECK: leave
+// CHECK: encoding: [0xc9]
+ leave
+
+// CHECK: seto %bl
+// CHECK: encoding: [0x0f,0x90,0xc3]
+ seto %bl
+
+// CHECK: seto 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x90,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ seto 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: seto 32493
+// CHECK: encoding: [0x0f,0x90,0x05,0xed,0x7e,0x00,0x00]
+ seto 0x7eed
+
+// CHECK: seto 3133065982
+// CHECK: encoding: [0x0f,0x90,0x05,0xfe,0xca,0xbe,0xba]
+ seto 0xbabecafe
+
+// CHECK: seto 305419896
+// CHECK: encoding: [0x0f,0x90,0x05,0x78,0x56,0x34,0x12]
+ seto 0x12345678
+
+// CHECK: setno %bl
+// CHECK: encoding: [0x0f,0x91,0xc3]
+ setno %bl
+
+// CHECK: setno 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x91,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setno 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setno 32493
+// CHECK: encoding: [0x0f,0x91,0x05,0xed,0x7e,0x00,0x00]
+ setno 0x7eed
+
+// CHECK: setno 3133065982
+// CHECK: encoding: [0x0f,0x91,0x05,0xfe,0xca,0xbe,0xba]
+ setno 0xbabecafe
+
+// CHECK: setno 305419896
+// CHECK: encoding: [0x0f,0x91,0x05,0x78,0x56,0x34,0x12]
+ setno 0x12345678
+
+// CHECK: setb %bl
+// CHECK: encoding: [0x0f,0x92,0xc3]
+ setb %bl
+
+// CHECK: setb 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x92,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setb 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setb 32493
+// CHECK: encoding: [0x0f,0x92,0x05,0xed,0x7e,0x00,0x00]
+ setb 0x7eed
+
+// CHECK: setb 3133065982
+// CHECK: encoding: [0x0f,0x92,0x05,0xfe,0xca,0xbe,0xba]
+ setb 0xbabecafe
+
+// CHECK: setb 305419896
+// CHECK: encoding: [0x0f,0x92,0x05,0x78,0x56,0x34,0x12]
+ setb 0x12345678
+
+// CHECK: setae %bl
+// CHECK: encoding: [0x0f,0x93,0xc3]
+ setae %bl
+
+// CHECK: setae 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x93,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setae 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setae 32493
+// CHECK: encoding: [0x0f,0x93,0x05,0xed,0x7e,0x00,0x00]
+ setae 0x7eed
+
+// CHECK: setae 3133065982
+// CHECK: encoding: [0x0f,0x93,0x05,0xfe,0xca,0xbe,0xba]
+ setae 0xbabecafe
+
+// CHECK: setae 305419896
+// CHECK: encoding: [0x0f,0x93,0x05,0x78,0x56,0x34,0x12]
+ setae 0x12345678
+
+// CHECK: sete %bl
+// CHECK: encoding: [0x0f,0x94,0xc3]
+ sete %bl
+
+// CHECK: sete 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x94,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ sete 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sete 32493
+// CHECK: encoding: [0x0f,0x94,0x05,0xed,0x7e,0x00,0x00]
+ sete 0x7eed
+
+// CHECK: sete 3133065982
+// CHECK: encoding: [0x0f,0x94,0x05,0xfe,0xca,0xbe,0xba]
+ sete 0xbabecafe
+
+// CHECK: sete 305419896
+// CHECK: encoding: [0x0f,0x94,0x05,0x78,0x56,0x34,0x12]
+ sete 0x12345678
+
+// CHECK: setne %bl
+// CHECK: encoding: [0x0f,0x95,0xc3]
+ setne %bl
+
+// CHECK: setne 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x95,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setne 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setne 32493
+// CHECK: encoding: [0x0f,0x95,0x05,0xed,0x7e,0x00,0x00]
+ setne 0x7eed
+
+// CHECK: setne 3133065982
+// CHECK: encoding: [0x0f,0x95,0x05,0xfe,0xca,0xbe,0xba]
+ setne 0xbabecafe
+
+// CHECK: setne 305419896
+// CHECK: encoding: [0x0f,0x95,0x05,0x78,0x56,0x34,0x12]
+ setne 0x12345678
+
+// CHECK: setbe %bl
+// CHECK: encoding: [0x0f,0x96,0xc3]
+ setbe %bl
+
+// CHECK: setbe 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x96,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setbe 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setbe 32493
+// CHECK: encoding: [0x0f,0x96,0x05,0xed,0x7e,0x00,0x00]
+ setbe 0x7eed
+
+// CHECK: setbe 3133065982
+// CHECK: encoding: [0x0f,0x96,0x05,0xfe,0xca,0xbe,0xba]
+ setbe 0xbabecafe
+
+// CHECK: setbe 305419896
+// CHECK: encoding: [0x0f,0x96,0x05,0x78,0x56,0x34,0x12]
+ setbe 0x12345678
+
+// CHECK: seta %bl
+// CHECK: encoding: [0x0f,0x97,0xc3]
+ seta %bl
+
+// CHECK: seta 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x97,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ seta 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: seta 32493
+// CHECK: encoding: [0x0f,0x97,0x05,0xed,0x7e,0x00,0x00]
+ seta 0x7eed
+
+// CHECK: seta 3133065982
+// CHECK: encoding: [0x0f,0x97,0x05,0xfe,0xca,0xbe,0xba]
+ seta 0xbabecafe
+
+// CHECK: seta 305419896
+// CHECK: encoding: [0x0f,0x97,0x05,0x78,0x56,0x34,0x12]
+ seta 0x12345678
+
+// CHECK: sets %bl
+// CHECK: encoding: [0x0f,0x98,0xc3]
+ sets %bl
+
+// CHECK: sets 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x98,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ sets 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: sets 32493
+// CHECK: encoding: [0x0f,0x98,0x05,0xed,0x7e,0x00,0x00]
+ sets 0x7eed
+
+// CHECK: sets 3133065982
+// CHECK: encoding: [0x0f,0x98,0x05,0xfe,0xca,0xbe,0xba]
+ sets 0xbabecafe
+
+// CHECK: sets 305419896
+// CHECK: encoding: [0x0f,0x98,0x05,0x78,0x56,0x34,0x12]
+ sets 0x12345678
+
+// CHECK: setns %bl
+// CHECK: encoding: [0x0f,0x99,0xc3]
+ setns %bl
+
+// CHECK: setns 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x99,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setns 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setns 32493
+// CHECK: encoding: [0x0f,0x99,0x05,0xed,0x7e,0x00,0x00]
+ setns 0x7eed
+
+// CHECK: setns 3133065982
+// CHECK: encoding: [0x0f,0x99,0x05,0xfe,0xca,0xbe,0xba]
+ setns 0xbabecafe
+
+// CHECK: setns 305419896
+// CHECK: encoding: [0x0f,0x99,0x05,0x78,0x56,0x34,0x12]
+ setns 0x12345678
+
+// CHECK: setp %bl
+// CHECK: encoding: [0x0f,0x9a,0xc3]
+ setp %bl
+
+// CHECK: setp 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9a,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setp 32493
+// CHECK: encoding: [0x0f,0x9a,0x05,0xed,0x7e,0x00,0x00]
+ setp 0x7eed
+
+// CHECK: setp 3133065982
+// CHECK: encoding: [0x0f,0x9a,0x05,0xfe,0xca,0xbe,0xba]
+ setp 0xbabecafe
+
+// CHECK: setp 305419896
+// CHECK: encoding: [0x0f,0x9a,0x05,0x78,0x56,0x34,0x12]
+ setp 0x12345678
+
+// CHECK: setnp %bl
+// CHECK: encoding: [0x0f,0x9b,0xc3]
+ setnp %bl
+
+// CHECK: setnp 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9b,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setnp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setnp 32493
+// CHECK: encoding: [0x0f,0x9b,0x05,0xed,0x7e,0x00,0x00]
+ setnp 0x7eed
+
+// CHECK: setnp 3133065982
+// CHECK: encoding: [0x0f,0x9b,0x05,0xfe,0xca,0xbe,0xba]
+ setnp 0xbabecafe
+
+// CHECK: setnp 305419896
+// CHECK: encoding: [0x0f,0x9b,0x05,0x78,0x56,0x34,0x12]
+ setnp 0x12345678
+
+// CHECK: setl %bl
+// CHECK: encoding: [0x0f,0x9c,0xc3]
+ setl %bl
+
+// CHECK: setl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9c,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setl 32493
+// CHECK: encoding: [0x0f,0x9c,0x05,0xed,0x7e,0x00,0x00]
+ setl 0x7eed
+
+// CHECK: setl 3133065982
+// CHECK: encoding: [0x0f,0x9c,0x05,0xfe,0xca,0xbe,0xba]
+ setl 0xbabecafe
+
+// CHECK: setl 305419896
+// CHECK: encoding: [0x0f,0x9c,0x05,0x78,0x56,0x34,0x12]
+ setl 0x12345678
+
+// CHECK: setge %bl
+// CHECK: encoding: [0x0f,0x9d,0xc3]
+ setge %bl
+
+// CHECK: setge 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9d,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setge 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setge 32493
+// CHECK: encoding: [0x0f,0x9d,0x05,0xed,0x7e,0x00,0x00]
+ setge 0x7eed
+
+// CHECK: setge 3133065982
+// CHECK: encoding: [0x0f,0x9d,0x05,0xfe,0xca,0xbe,0xba]
+ setge 0xbabecafe
+
+// CHECK: setge 305419896
+// CHECK: encoding: [0x0f,0x9d,0x05,0x78,0x56,0x34,0x12]
+ setge 0x12345678
+
+// CHECK: setle %bl
+// CHECK: encoding: [0x0f,0x9e,0xc3]
+ setle %bl
+
+// CHECK: setle 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9e,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setle 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setle 32493
+// CHECK: encoding: [0x0f,0x9e,0x05,0xed,0x7e,0x00,0x00]
+ setle 0x7eed
+
+// CHECK: setle 3133065982
+// CHECK: encoding: [0x0f,0x9e,0x05,0xfe,0xca,0xbe,0xba]
+ setle 0xbabecafe
+
+// CHECK: setle 305419896
+// CHECK: encoding: [0x0f,0x9e,0x05,0x78,0x56,0x34,0x12]
+ setle 0x12345678
+
+// CHECK: setg %bl
+// CHECK: encoding: [0x0f,0x9f,0xc3]
+ setg %bl
+
+// CHECK: setg 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x9f,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ setg 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: setg 32493
+// CHECK: encoding: [0x0f,0x9f,0x05,0xed,0x7e,0x00,0x00]
+ setg 0x7eed
+
+// CHECK: setg 3133065982
+// CHECK: encoding: [0x0f,0x9f,0x05,0xfe,0xca,0xbe,0xba]
+ setg 0xbabecafe
+
+// CHECK: setg 305419896
+// CHECK: encoding: [0x0f,0x9f,0x05,0x78,0x56,0x34,0x12]
+ setg 0x12345678
+
+// CHECK: rsm
+// CHECK: encoding: [0x0f,0xaa]
+ rsm
+
+// CHECK: hlt
+// CHECK: encoding: [0xf4]
+ hlt
+
+// CHECK: nopl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x1f,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ nopl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: nopw 32493
+// CHECK: encoding: [0x66,0x0f,0x1f,0x05,0xed,0x7e,0x00,0x00]
+ nopw 0x7eed
+
+// CHECK: nopl 3133065982
+// CHECK: encoding: [0x0f,0x1f,0x05,0xfe,0xca,0xbe,0xba]
+ nopl 0xbabecafe
+
+// CHECK: nopl 305419896
+// CHECK: encoding: [0x0f,0x1f,0x05,0x78,0x56,0x34,0x12]
+ nopl 0x12345678
+
+// CHECK: nop
+// CHECK: encoding: [0x90]
+ nop
+
+// CHECK: lldtw 32493
+// CHECK: encoding: [0x0f,0x00,0x15,0xed,0x7e,0x00,0x00]
+ lldtw 0x7eed
+
+// CHECK: lmsww 32493
+// CHECK: encoding: [0x0f,0x01,0x35,0xed,0x7e,0x00,0x00]
+ lmsww 0x7eed
+
+// CHECK: ltrw 32493
+// CHECK: encoding: [0x0f,0x00,0x1d,0xed,0x7e,0x00,0x00]
+ ltrw 0x7eed
+
+// CHECK: sldtw 32493
+// CHECK: encoding: [0x0f,0x00,0x05,0xed,0x7e,0x00,0x00]
+ sldtw 0x7eed
+
+// CHECK: smsww 32493
+// CHECK: encoding: [0x0f,0x01,0x25,0xed,0x7e,0x00,0x00]
+ smsww 0x7eed
+
+// CHECK: strw 32493
+// CHECK: encoding: [0x0f,0x00,0x0d,0xed,0x7e,0x00,0x00]
+ strw 0x7eed
+
+// CHECK: verr %bx
+// CHECK: encoding: [0x0f,0x00,0xe3]
+ verr %bx
+
+// CHECK: verr 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x00,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ verr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: verr 3133065982
+// CHECK: encoding: [0x0f,0x00,0x25,0xfe,0xca,0xbe,0xba]
+ verr 0xbabecafe
+
+// CHECK: verr 305419896
+// CHECK: encoding: [0x0f,0x00,0x25,0x78,0x56,0x34,0x12]
+ verr 0x12345678
+
+// CHECK: verw %bx
+// CHECK: encoding: [0x0f,0x00,0xeb]
+ verw %bx
+
+// CHECK: verw 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x00,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ verw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: verw 3133065982
+// CHECK: encoding: [0x0f,0x00,0x2d,0xfe,0xca,0xbe,0xba]
+ verw 0xbabecafe
+
+// CHECK: verw 305419896
+// CHECK: encoding: [0x0f,0x00,0x2d,0x78,0x56,0x34,0x12]
+ verw 0x12345678
+
+// CHECK: fld %st(2)
+// CHECK: encoding: [0xd9,0xc2]
+ fld %st(2)
+
+// CHECK: fldl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdd,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ fldl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fldl 3133065982
+// CHECK: encoding: [0xdd,0x05,0xfe,0xca,0xbe,0xba]
+ fldl 0xbabecafe
+
+// CHECK: fldl 305419896
+// CHECK: encoding: [0xdd,0x05,0x78,0x56,0x34,0x12]
+ fldl 0x12345678
+
+// CHECK: fld %st(2)
+// CHECK: encoding: [0xd9,0xc2]
+ fld %st(2)
+
+// CHECK: fildl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ fildl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fildl 3133065982
+// CHECK: encoding: [0xdb,0x05,0xfe,0xca,0xbe,0xba]
+ fildl 0xbabecafe
+
+// CHECK: fildl 305419896
+// CHECK: encoding: [0xdb,0x05,0x78,0x56,0x34,0x12]
+ fildl 0x12345678
+
+// CHECK: fildll 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdf,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ fildll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fildll 32493
+// CHECK: encoding: [0xdf,0x2d,0xed,0x7e,0x00,0x00]
+ fildll 0x7eed
+
+// CHECK: fildll 3133065982
+// CHECK: encoding: [0xdf,0x2d,0xfe,0xca,0xbe,0xba]
+ fildll 0xbabecafe
+
+// CHECK: fildll 305419896
+// CHECK: encoding: [0xdf,0x2d,0x78,0x56,0x34,0x12]
+ fildll 0x12345678
+
+// CHECK: fldt 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ fldt 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fldt 32493
+// CHECK: encoding: [0xdb,0x2d,0xed,0x7e,0x00,0x00]
+ fldt 0x7eed
+
+// CHECK: fldt 3133065982
+// CHECK: encoding: [0xdb,0x2d,0xfe,0xca,0xbe,0xba]
+ fldt 0xbabecafe
+
+// CHECK: fldt 305419896
+// CHECK: encoding: [0xdb,0x2d,0x78,0x56,0x34,0x12]
+ fldt 0x12345678
+
+// CHECK: fbld 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdf,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ fbld 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fbld 32493
+// CHECK: encoding: [0xdf,0x25,0xed,0x7e,0x00,0x00]
+ fbld 0x7eed
+
+// CHECK: fbld 3133065982
+// CHECK: encoding: [0xdf,0x25,0xfe,0xca,0xbe,0xba]
+ fbld 0xbabecafe
+
+// CHECK: fbld 305419896
+// CHECK: encoding: [0xdf,0x25,0x78,0x56,0x34,0x12]
+ fbld 0x12345678
+
+// CHECK: fst %st(2)
+// CHECK: encoding: [0xdd,0xd2]
+ fst %st(2)
+
+// CHECK: fstl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdd,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ fstl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstl 3133065982
+// CHECK: encoding: [0xdd,0x15,0xfe,0xca,0xbe,0xba]
+ fstl 0xbabecafe
+
+// CHECK: fstl 305419896
+// CHECK: encoding: [0xdd,0x15,0x78,0x56,0x34,0x12]
+ fstl 0x12345678
+
+// CHECK: fst %st(2)
+// CHECK: encoding: [0xdd,0xd2]
+ fst %st(2)
+
+// CHECK: fistl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ fistl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistl 3133065982
+// CHECK: encoding: [0xdb,0x15,0xfe,0xca,0xbe,0xba]
+ fistl 0xbabecafe
+
+// CHECK: fistl 305419896
+// CHECK: encoding: [0xdb,0x15,0x78,0x56,0x34,0x12]
+ fistl 0x12345678
+
+// CHECK: fstp %st(2)
+// CHECK: encoding: [0xdd,0xda]
+ fstp %st(2)
+
+// CHECK: fstpl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdd,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ fstpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstpl 3133065982
+// CHECK: encoding: [0xdd,0x1d,0xfe,0xca,0xbe,0xba]
+ fstpl 0xbabecafe
+
+// CHECK: fstpl 305419896
+// CHECK: encoding: [0xdd,0x1d,0x78,0x56,0x34,0x12]
+ fstpl 0x12345678
+
+// CHECK: fstp %st(2)
+// CHECK: encoding: [0xdd,0xda]
+ fstp %st(2)
+
+// CHECK: fistpl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ fistpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistpl 3133065982
+// CHECK: encoding: [0xdb,0x1d,0xfe,0xca,0xbe,0xba]
+ fistpl 0xbabecafe
+
+// CHECK: fistpl 305419896
+// CHECK: encoding: [0xdb,0x1d,0x78,0x56,0x34,0x12]
+ fistpl 0x12345678
+
+// CHECK: fistpll 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdf,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fistpll 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fistpll 32493
+// CHECK: encoding: [0xdf,0x3d,0xed,0x7e,0x00,0x00]
+ fistpll 0x7eed
+
+// CHECK: fistpll 3133065982
+// CHECK: encoding: [0xdf,0x3d,0xfe,0xca,0xbe,0xba]
+ fistpll 0xbabecafe
+
+// CHECK: fistpll 305419896
+// CHECK: encoding: [0xdf,0x3d,0x78,0x56,0x34,0x12]
+ fistpll 0x12345678
+
+// CHECK: fstpt 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fstpt 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fstpt 32493
+// CHECK: encoding: [0xdb,0x3d,0xed,0x7e,0x00,0x00]
+ fstpt 0x7eed
+
+// CHECK: fstpt 3133065982
+// CHECK: encoding: [0xdb,0x3d,0xfe,0xca,0xbe,0xba]
+ fstpt 0xbabecafe
+
+// CHECK: fstpt 305419896
+// CHECK: encoding: [0xdb,0x3d,0x78,0x56,0x34,0x12]
+ fstpt 0x12345678
+
+// CHECK: fbstp 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdf,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ fbstp 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fbstp 32493
+// CHECK: encoding: [0xdf,0x35,0xed,0x7e,0x00,0x00]
+ fbstp 0x7eed
+
+// CHECK: fbstp 3133065982
+// CHECK: encoding: [0xdf,0x35,0xfe,0xca,0xbe,0xba]
+ fbstp 0xbabecafe
+
+// CHECK: fbstp 305419896
+// CHECK: encoding: [0xdf,0x35,0x78,0x56,0x34,0x12]
+ fbstp 0x12345678
+
+// CHECK: fxch %st(2)
+// CHECK: encoding: [0xd9,0xca]
+ fxch %st(2)
+
+// CHECK: fcom %st(2)
+// CHECK: encoding: [0xd8,0xd2]
+ fcom %st(2)
+
+// CHECK: fcom %st(2)
+// CHECK: encoding: [0xd8,0xd2]
+ fcom %st(2)
+
+// CHECK: ficoml 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ ficoml 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ficoml 3133065982
+// CHECK: encoding: [0xda,0x15,0xfe,0xca,0xbe,0xba]
+ ficoml 0xbabecafe
+
+// CHECK: ficoml 305419896
+// CHECK: encoding: [0xda,0x15,0x78,0x56,0x34,0x12]
+ ficoml 0x12345678
+
+// CHECK: fcomp %st(2)
+// CHECK: encoding: [0xd8,0xda]
+ fcomp %st(2)
+
+// CHECK: fcomp %st(2)
+// CHECK: encoding: [0xd8,0xda]
+ fcomp %st(2)
+
+// CHECK: ficompl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ ficompl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ficompl 3133065982
+// CHECK: encoding: [0xda,0x1d,0xfe,0xca,0xbe,0xba]
+ ficompl 0xbabecafe
+
+// CHECK: ficompl 305419896
+// CHECK: encoding: [0xda,0x1d,0x78,0x56,0x34,0x12]
+ ficompl 0x12345678
+
+// CHECK: fcompp
+// CHECK: encoding: [0xde,0xd9]
+ fcompp
+
+// CHECK: fucom %st(2)
+// CHECK: encoding: [0xdd,0xe2]
+ fucom %st(2)
+
+// CHECK: fucomp %st(2)
+// CHECK: encoding: [0xdd,0xea]
+ fucomp %st(2)
+
+// CHECK: fucompp
+// CHECK: encoding: [0xda,0xe9]
+ fucompp
+
+// CHECK: ftst
+// CHECK: encoding: [0xd9,0xe4]
+ ftst
+
+// CHECK: fxam
+// CHECK: encoding: [0xd9,0xe5]
+ fxam
+
+// CHECK: fld1
+// CHECK: encoding: [0xd9,0xe8]
+ fld1
+
+// CHECK: fldl2t
+// CHECK: encoding: [0xd9,0xe9]
+ fldl2t
+
+// CHECK: fldl2e
+// CHECK: encoding: [0xd9,0xea]
+ fldl2e
+
+// CHECK: fldpi
+// CHECK: encoding: [0xd9,0xeb]
+ fldpi
+
+// CHECK: fldlg2
+// CHECK: encoding: [0xd9,0xec]
+ fldlg2
+
+// CHECK: fldln2
+// CHECK: encoding: [0xd9,0xed]
+ fldln2
+
+// CHECK: fldz
+// CHECK: encoding: [0xd9,0xee]
+ fldz
+
+// CHECK: fadd %st(2)
+// CHECK: encoding: [0xd8,0xc2]
+ fadd %st(2)
+
+// CHECK: faddl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ faddl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: faddl 3133065982
+// CHECK: encoding: [0xdc,0x05,0xfe,0xca,0xbe,0xba]
+ faddl 0xbabecafe
+
+// CHECK: faddl 305419896
+// CHECK: encoding: [0xdc,0x05,0x78,0x56,0x34,0x12]
+ faddl 0x12345678
+
+// CHECK: fiaddl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ fiaddl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fiaddl 3133065982
+// CHECK: encoding: [0xda,0x05,0xfe,0xca,0xbe,0xba]
+ fiaddl 0xbabecafe
+
+// CHECK: fiaddl 305419896
+// CHECK: encoding: [0xda,0x05,0x78,0x56,0x34,0x12]
+ fiaddl 0x12345678
+
+// CHECK: faddp %st(2)
+// CHECK: encoding: [0xde,0xc2]
+ faddp %st(2)
+
+// CHECK: fsub %st(2)
+// CHECK: encoding: [0xd8,0xe2]
+ fsub %st(2)
+
+// CHECK: fsubl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ fsubl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fsubl 3133065982
+// CHECK: encoding: [0xdc,0x25,0xfe,0xca,0xbe,0xba]
+ fsubl 0xbabecafe
+
+// CHECK: fsubl 305419896
+// CHECK: encoding: [0xdc,0x25,0x78,0x56,0x34,0x12]
+ fsubl 0x12345678
+
+// CHECK: fisubl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0xa4,0xcb,0xef,0xbe,0xad,0xde]
+ fisubl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisubl 3133065982
+// CHECK: encoding: [0xda,0x25,0xfe,0xca,0xbe,0xba]
+ fisubl 0xbabecafe
+
+// CHECK: fisubl 305419896
+// CHECK: encoding: [0xda,0x25,0x78,0x56,0x34,0x12]
+ fisubl 0x12345678
+
+// CHECK: fsubp %st(2)
+// CHECK: encoding: [0xde,0xe2]
+ fsubp %st(2)
+
+// CHECK: fsubr %st(2)
+// CHECK: encoding: [0xd8,0xea]
+ fsubr %st(2)
+
+// CHECK: fsubrl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ fsubrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fsubrl 3133065982
+// CHECK: encoding: [0xdc,0x2d,0xfe,0xca,0xbe,0xba]
+ fsubrl 0xbabecafe
+
+// CHECK: fsubrl 305419896
+// CHECK: encoding: [0xdc,0x2d,0x78,0x56,0x34,0x12]
+ fsubrl 0x12345678
+
+// CHECK: fisubrl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ fisubrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisubrl 3133065982
+// CHECK: encoding: [0xda,0x2d,0xfe,0xca,0xbe,0xba]
+ fisubrl 0xbabecafe
+
+// CHECK: fisubrl 305419896
+// CHECK: encoding: [0xda,0x2d,0x78,0x56,0x34,0x12]
+ fisubrl 0x12345678
+
+// CHECK: fsubrp %st(2)
+// CHECK: encoding: [0xde,0xea]
+ fsubrp %st(2)
+
+// CHECK: fmul %st(2)
+// CHECK: encoding: [0xd8,0xca]
+ fmul %st(2)
+
+// CHECK: fmull 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ fmull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fmull 3133065982
+// CHECK: encoding: [0xdc,0x0d,0xfe,0xca,0xbe,0xba]
+ fmull 0xbabecafe
+
+// CHECK: fmull 305419896
+// CHECK: encoding: [0xdc,0x0d,0x78,0x56,0x34,0x12]
+ fmull 0x12345678
+
+// CHECK: fimull 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ fimull 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fimull 3133065982
+// CHECK: encoding: [0xda,0x0d,0xfe,0xca,0xbe,0xba]
+ fimull 0xbabecafe
+
+// CHECK: fimull 305419896
+// CHECK: encoding: [0xda,0x0d,0x78,0x56,0x34,0x12]
+ fimull 0x12345678
+
+// CHECK: fmulp %st(2)
+// CHECK: encoding: [0xde,0xca]
+ fmulp %st(2)
+
+// CHECK: fdiv %st(2)
+// CHECK: encoding: [0xd8,0xf2]
+ fdiv %st(2)
+
+// CHECK: fdivl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ fdivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fdivl 3133065982
+// CHECK: encoding: [0xdc,0x35,0xfe,0xca,0xbe,0xba]
+ fdivl 0xbabecafe
+
+// CHECK: fdivl 305419896
+// CHECK: encoding: [0xdc,0x35,0x78,0x56,0x34,0x12]
+ fdivl 0x12345678
+
+// CHECK: fidivl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ fidivl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fidivl 3133065982
+// CHECK: encoding: [0xda,0x35,0xfe,0xca,0xbe,0xba]
+ fidivl 0xbabecafe
+
+// CHECK: fidivl 305419896
+// CHECK: encoding: [0xda,0x35,0x78,0x56,0x34,0x12]
+ fidivl 0x12345678
+
+// CHECK: fdivp %st(2)
+// CHECK: encoding: [0xde,0xf2]
+ fdivp %st(2)
+
+// CHECK: fdivr %st(2)
+// CHECK: encoding: [0xd8,0xfa]
+ fdivr %st(2)
+
+// CHECK: fdivrl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdc,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fdivrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fdivrl 3133065982
+// CHECK: encoding: [0xdc,0x3d,0xfe,0xca,0xbe,0xba]
+ fdivrl 0xbabecafe
+
+// CHECK: fdivrl 305419896
+// CHECK: encoding: [0xdc,0x3d,0x78,0x56,0x34,0x12]
+ fdivrl 0x12345678
+
+// CHECK: fidivrl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xda,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fidivrl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fidivrl 3133065982
+// CHECK: encoding: [0xda,0x3d,0xfe,0xca,0xbe,0xba]
+ fidivrl 0xbabecafe
+
+// CHECK: fidivrl 305419896
+// CHECK: encoding: [0xda,0x3d,0x78,0x56,0x34,0x12]
+ fidivrl 0x12345678
+
+// CHECK: fdivrp %st(2)
+// CHECK: encoding: [0xde,0xfa]
+ fdivrp %st(2)
+
+// CHECK: f2xm1
+// CHECK: encoding: [0xd9,0xf0]
+ f2xm1
+
+// CHECK: fyl2x
+// CHECK: encoding: [0xd9,0xf1]
+ fyl2x
+
+// CHECK: fptan
+// CHECK: encoding: [0xd9,0xf2]
+ fptan
+
+// CHECK: fpatan
+// CHECK: encoding: [0xd9,0xf3]
+ fpatan
+
+// CHECK: fxtract
+// CHECK: encoding: [0xd9,0xf4]
+ fxtract
+
+// CHECK: fprem1
+// CHECK: encoding: [0xd9,0xf5]
+ fprem1
+
+// CHECK: fdecstp
+// CHECK: encoding: [0xd9,0xf6]
+ fdecstp
+
+// CHECK: fincstp
+// CHECK: encoding: [0xd9,0xf7]
+ fincstp
+
+// CHECK: fprem
+// CHECK: encoding: [0xd9,0xf8]
+ fprem
+
+// CHECK: fyl2xp1
+// CHECK: encoding: [0xd9,0xf9]
+ fyl2xp1
+
+// CHECK: fsqrt
+// CHECK: encoding: [0xd9,0xfa]
+ fsqrt
+
+// CHECK: fsincos
+// CHECK: encoding: [0xd9,0xfb]
+ fsincos
+
+// CHECK: frndint
+// CHECK: encoding: [0xd9,0xfc]
+ frndint
+
+// CHECK: fscale
+// CHECK: encoding: [0xd9,0xfd]
+ fscale
+
+// CHECK: fsin
+// CHECK: encoding: [0xd9,0xfe]
+ fsin
+
+// CHECK: fcos
+// CHECK: encoding: [0xd9,0xff]
+ fcos
+
+// CHECK: fchs
+// CHECK: encoding: [0xd9,0xe0]
+ fchs
+
+// CHECK: fabs
+// CHECK: encoding: [0xd9,0xe1]
+ fabs
+
+// CHECK: fninit
+// CHECK: encoding: [0xdb,0xe3]
+ fninit
+
+// CHECK: fldcw 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd9,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ fldcw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fldcw 3133065982
+// CHECK: encoding: [0xd9,0x2d,0xfe,0xca,0xbe,0xba]
+ fldcw 0xbabecafe
+
+// CHECK: fldcw 305419896
+// CHECK: encoding: [0xd9,0x2d,0x78,0x56,0x34,0x12]
+ fldcw 0x12345678
+
+// CHECK: fnstcw 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xd9,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fnstcw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fnstcw 3133065982
+// CHECK: encoding: [0xd9,0x3d,0xfe,0xca,0xbe,0xba]
+ fnstcw 0xbabecafe
+
+// CHECK: fnstcw 305419896
+// CHECK: encoding: [0xd9,0x3d,0x78,0x56,0x34,0x12]
+ fnstcw 0x12345678
+
+// CHECK: fnstsw 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdd,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ fnstsw 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fnstsw 3133065982
+// CHECK: encoding: [0xdd,0x3d,0xfe,0xca,0xbe,0xba]
+ fnstsw 0xbabecafe
+
+// CHECK: fnstsw 305419896
+// CHECK: encoding: [0xdd,0x3d,0x78,0x56,0x34,0x12]
+ fnstsw 0x12345678
+
+// CHECK: fnclex
+// CHECK: encoding: [0xdb,0xe2]
+ fnclex
+
+// CHECK: fnstenv 32493
+// CHECK: encoding: [0xd9,0x35,0xed,0x7e,0x00,0x00]
+ fnstenv 0x7eed
+
+// CHECK: fldenv 32493
+// CHECK: encoding: [0xd9,0x25,0xed,0x7e,0x00,0x00]
+ fldenv 0x7eed
+
+// CHECK: fnsave 32493
+// CHECK: encoding: [0xdd,0x35,0xed,0x7e,0x00,0x00]
+ fnsave 0x7eed
+
+// CHECK: frstor 32493
+// CHECK: encoding: [0xdd,0x25,0xed,0x7e,0x00,0x00]
+ frstor 0x7eed
+
+// CHECK: ffree %st(2)
+// CHECK: encoding: [0xdd,0xc2]
+ ffree %st(2)
+
+// CHECK: fnop
+// CHECK: encoding: [0xd9,0xd0]
+ fnop
+
+// CHECK: invd
+// CHECK: encoding: [0x0f,0x08]
+ invd
+
+// CHECK: wbinvd
+// CHECK: encoding: [0x0f,0x09]
+ wbinvd
+
+// CHECK: cpuid
+// CHECK: encoding: [0x0f,0xa2]
+ cpuid
+
+// CHECK: wrmsr
+// CHECK: encoding: [0x0f,0x30]
+ wrmsr
+
+// CHECK: rdtsc
+// CHECK: encoding: [0x0f,0x31]
+ rdtsc
+
+// CHECK: rdmsr
+// CHECK: encoding: [0x0f,0x32]
+ rdmsr
+
+// CHECK: cmpxchg8b 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xc7,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ cmpxchg8b 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: cmpxchg8b 32493
+// CHECK: encoding: [0x0f,0xc7,0x0d,0xed,0x7e,0x00,0x00]
+ cmpxchg8b 0x7eed
+
+// CHECK: cmpxchg8b 3133065982
+// CHECK: encoding: [0x0f,0xc7,0x0d,0xfe,0xca,0xbe,0xba]
+ cmpxchg8b 0xbabecafe
+
+// CHECK: cmpxchg8b 305419896
+// CHECK: encoding: [0x0f,0xc7,0x0d,0x78,0x56,0x34,0x12]
+ cmpxchg8b 0x12345678
+
+// CHECK: sysenter
+// CHECK: encoding: [0x0f,0x34]
+ sysenter
+
+// CHECK: sysexit
+// CHECK: encoding: [0x0f,0x35]
+ sysexit
+
+// CHECK: fxsave 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xae,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ fxsave 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fxsave 32493
+// CHECK: encoding: [0x0f,0xae,0x05,0xed,0x7e,0x00,0x00]
+ fxsave 0x7eed
+
+// CHECK: fxsave 3133065982
+// CHECK: encoding: [0x0f,0xae,0x05,0xfe,0xca,0xbe,0xba]
+ fxsave 0xbabecafe
+
+// CHECK: fxsave 305419896
+// CHECK: encoding: [0x0f,0xae,0x05,0x78,0x56,0x34,0x12]
+ fxsave 0x12345678
+
+// CHECK: fxrstor 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xae,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ fxrstor 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fxrstor 32493
+// CHECK: encoding: [0x0f,0xae,0x0d,0xed,0x7e,0x00,0x00]
+ fxrstor 0x7eed
+
+// CHECK: fxrstor 3133065982
+// CHECK: encoding: [0x0f,0xae,0x0d,0xfe,0xca,0xbe,0xba]
+ fxrstor 0xbabecafe
+
+// CHECK: fxrstor 305419896
+// CHECK: encoding: [0x0f,0xae,0x0d,0x78,0x56,0x34,0x12]
+ fxrstor 0x12345678
+
+// CHECK: rdpmc
+// CHECK: encoding: [0x0f,0x33]
+ rdpmc
+
+// CHECK: ud2
+// CHECK: encoding: [0x0f,0x0b]
+ ud2
+
+// CHECK: fcmovb %st(2), %st(0)
+// CHECK: encoding: [0xda,0xc2]
+ fcmovb %st(2),%st
+
+// CHECK: fcmove %st(2), %st(0)
+// CHECK: encoding: [0xda,0xca]
+ fcmove %st(2),%st
+
+// CHECK: fcmovbe %st(2), %st(0)
+// CHECK: encoding: [0xda,0xd2]
+ fcmovbe %st(2),%st
+
+// CHECK: fcmovu %st(2), %st(0)
+// CHECK: encoding: [0xda,0xda]
+ fcmovu %st(2),%st
+
+// CHECK: fcmovnb %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xc2]
+ fcmovnb %st(2),%st
+
+// CHECK: fcmovne %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xca]
+ fcmovne %st(2),%st
+
+// CHECK: fcmovnbe %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xd2]
+ fcmovnbe %st(2),%st
+
+// CHECK: fcmovnu %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xda]
+ fcmovnu %st(2),%st
+
+// CHECK: fcomi %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xf2]
+ fcomi %st(2),%st
+
+// CHECK: fucomi %st(2), %st(0)
+// CHECK: encoding: [0xdb,0xea]
+ fucomi %st(2),%st
+
+// CHECK: fcomip %st(2), %st(0)
+// CHECK: encoding: [0xdf,0xf2]
+ fcomip %st(2),%st
+
+// CHECK: fucomip %st(2), %st(0)
+// CHECK: encoding: [0xdf,0xea]
+ fucomip %st(2),%st
+
+// CHECK: movnti %ecx, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xc3,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ movnti %ecx,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movnti %ecx, 69
+// CHECK: encoding: [0x0f,0xc3,0x0d,0x45,0x00,0x00,0x00]
+ movnti %ecx,0x45
+
+// CHECK: movnti %ecx, 32493
+// CHECK: encoding: [0x0f,0xc3,0x0d,0xed,0x7e,0x00,0x00]
+ movnti %ecx,0x7eed
+
+// CHECK: movnti %ecx, 3133065982
+// CHECK: encoding: [0x0f,0xc3,0x0d,0xfe,0xca,0xbe,0xba]
+ movnti %ecx,0xbabecafe
+
+// CHECK: movnti %ecx, 305419896
+// CHECK: encoding: [0x0f,0xc3,0x0d,0x78,0x56,0x34,0x12]
+ movnti %ecx,0x12345678
+
+// CHECK: clflush 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xae,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ clflush 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: clflush 32493
+// CHECK: encoding: [0x0f,0xae,0x3d,0xed,0x7e,0x00,0x00]
+ clflush 0x7eed
+
+// CHECK: clflush 3133065982
+// CHECK: encoding: [0x0f,0xae,0x3d,0xfe,0xca,0xbe,0xba]
+ clflush 0xbabecafe
+
+// CHECK: clflush 305419896
+// CHECK: encoding: [0x0f,0xae,0x3d,0x78,0x56,0x34,0x12]
+ clflush 0x12345678
+
+// CHECK: emms
+// CHECK: encoding: [0x0f,0x77]
+ emms
+
+// CHECK: movd %ecx, %mm3
+// CHECK: encoding: [0x0f,0x6e,0xd9]
+ movd %ecx,%mm3
+
+// CHECK: movd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x6e,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: movd 69, %mm3
+// CHECK: encoding: [0x0f,0x6e,0x1d,0x45,0x00,0x00,0x00]
+ movd 0x45,%mm3
+
+// CHECK: movd 32493, %mm3
+// CHECK: encoding: [0x0f,0x6e,0x1d,0xed,0x7e,0x00,0x00]
+ movd 0x7eed,%mm3
+
+// CHECK: movd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x6e,0x1d,0xfe,0xca,0xbe,0xba]
+ movd 0xbabecafe,%mm3
+
+// CHECK: movd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x6e,0x1d,0x78,0x56,0x34,0x12]
+ movd 0x12345678,%mm3
+
+// CHECK: movd %mm3, %ecx
+// CHECK: encoding: [0x0f,0x7e,0xd9]
+ movd %mm3,%ecx
+
+// CHECK: movd %mm3, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x7e,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movd %mm3,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movd %mm3, 69
+// CHECK: encoding: [0x0f,0x7e,0x1d,0x45,0x00,0x00,0x00]
+ movd %mm3,0x45
+
+// CHECK: movd %mm3, 32493
+// CHECK: encoding: [0x0f,0x7e,0x1d,0xed,0x7e,0x00,0x00]
+ movd %mm3,0x7eed
+
+// CHECK: movd %mm3, 3133065982
+// CHECK: encoding: [0x0f,0x7e,0x1d,0xfe,0xca,0xbe,0xba]
+ movd %mm3,0xbabecafe
+
+// CHECK: movd %mm3, 305419896
+// CHECK: encoding: [0x0f,0x7e,0x1d,0x78,0x56,0x34,0x12]
+ movd %mm3,0x12345678
+
+// CHECK: movd %ecx, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0xe9]
+ movd %ecx,%xmm5
+
+// CHECK: movd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0x2d,0x45,0x00,0x00,0x00]
+ movd 0x45,%xmm5
+
+// CHECK: movd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0x2d,0xed,0x7e,0x00,0x00]
+ movd 0x7eed,%xmm5
+
+// CHECK: movd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0x2d,0xfe,0xca,0xbe,0xba]
+ movd 0xbabecafe,%xmm5
+
+// CHECK: movd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6e,0x2d,0x78,0x56,0x34,0x12]
+ movd 0x12345678,%xmm5
+
+// CHECK: movd %xmm5, %ecx
+// CHECK: encoding: [0x66,0x0f,0x7e,0xe9]
+ movd %xmm5,%ecx
+
+// CHECK: movd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x7e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x7e,0x2d,0x45,0x00,0x00,0x00]
+ movd %xmm5,0x45
+
+// CHECK: movd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x7e,0x2d,0xed,0x7e,0x00,0x00]
+ movd %xmm5,0x7eed
+
+// CHECK: movd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x7e,0x2d,0xfe,0xca,0xbe,0xba]
+ movd %xmm5,0xbabecafe
+
+// CHECK: movd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x7e,0x2d,0x78,0x56,0x34,0x12]
+ movd %xmm5,0x12345678
+
+// CHECK: movq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x6f,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: movq 69, %mm3
+// CHECK: encoding: [0x0f,0x6f,0x1d,0x45,0x00,0x00,0x00]
+ movq 0x45,%mm3
+
+// CHECK: movq 32493, %mm3
+// CHECK: encoding: [0x0f,0x6f,0x1d,0xed,0x7e,0x00,0x00]
+ movq 0x7eed,%mm3
+
+// CHECK: movq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x6f,0x1d,0xfe,0xca,0xbe,0xba]
+ movq 0xbabecafe,%mm3
+
+// CHECK: movq 305419896, %mm3
+// CHECK: encoding: [0x0f,0x6f,0x1d,0x78,0x56,0x34,0x12]
+ movq 0x12345678,%mm3
+
+// CHECK: movq %mm3, %mm3
+// CHECK: encoding: [0x0f,0x6f,0xdb]
+ movq %mm3,%mm3
+
+// CHECK: movq %mm3, %mm3
+// CHECK: encoding: [0x0f,0x6f,0xdb]
+ movq %mm3,%mm3
+
+// CHECK: movq %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x7e,0xed]
+ movq %xmm5,%xmm5
+
+// CHECK: movq %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0xd6,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movq %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movq %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0xd6,0x2d,0x45,0x00,0x00,0x00]
+ movq %xmm5,0x45
+
+// CHECK: movq %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0xd6,0x2d,0xed,0x7e,0x00,0x00]
+ movq %xmm5,0x7eed
+
+// CHECK: movq %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0xd6,0x2d,0xfe,0xca,0xbe,0xba]
+ movq %xmm5,0xbabecafe
+
+// CHECK: movq %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0xd6,0x2d,0x78,0x56,0x34,0x12]
+ movq %xmm5,0x12345678
+
+// CHECK: movq %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x7e,0xed]
+ movq %xmm5,%xmm5
+
+// CHECK: packssdw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x6b,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ packssdw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: packssdw 69, %mm3
+// CHECK: encoding: [0x0f,0x6b,0x1d,0x45,0x00,0x00,0x00]
+ packssdw 0x45,%mm3
+
+// CHECK: packssdw 32493, %mm3
+// CHECK: encoding: [0x0f,0x6b,0x1d,0xed,0x7e,0x00,0x00]
+ packssdw 0x7eed,%mm3
+
+// CHECK: packssdw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x6b,0x1d,0xfe,0xca,0xbe,0xba]
+ packssdw 0xbabecafe,%mm3
+
+// CHECK: packssdw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x6b,0x1d,0x78,0x56,0x34,0x12]
+ packssdw 0x12345678,%mm3
+
+// CHECK: packssdw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x6b,0xdb]
+ packssdw %mm3,%mm3
+
+// CHECK: packssdw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ packssdw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packssdw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0x2d,0x45,0x00,0x00,0x00]
+ packssdw 0x45,%xmm5
+
+// CHECK: packssdw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0x2d,0xed,0x7e,0x00,0x00]
+ packssdw 0x7eed,%xmm5
+
+// CHECK: packssdw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0x2d,0xfe,0xca,0xbe,0xba]
+ packssdw 0xbabecafe,%xmm5
+
+// CHECK: packssdw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0x2d,0x78,0x56,0x34,0x12]
+ packssdw 0x12345678,%xmm5
+
+// CHECK: packssdw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6b,0xed]
+ packssdw %xmm5,%xmm5
+
+// CHECK: packsswb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x63,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ packsswb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: packsswb 69, %mm3
+// CHECK: encoding: [0x0f,0x63,0x1d,0x45,0x00,0x00,0x00]
+ packsswb 0x45,%mm3
+
+// CHECK: packsswb 32493, %mm3
+// CHECK: encoding: [0x0f,0x63,0x1d,0xed,0x7e,0x00,0x00]
+ packsswb 0x7eed,%mm3
+
+// CHECK: packsswb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x63,0x1d,0xfe,0xca,0xbe,0xba]
+ packsswb 0xbabecafe,%mm3
+
+// CHECK: packsswb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x63,0x1d,0x78,0x56,0x34,0x12]
+ packsswb 0x12345678,%mm3
+
+// CHECK: packsswb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x63,0xdb]
+ packsswb %mm3,%mm3
+
+// CHECK: packsswb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ packsswb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packsswb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0x2d,0x45,0x00,0x00,0x00]
+ packsswb 0x45,%xmm5
+
+// CHECK: packsswb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0x2d,0xed,0x7e,0x00,0x00]
+ packsswb 0x7eed,%xmm5
+
+// CHECK: packsswb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0x2d,0xfe,0xca,0xbe,0xba]
+ packsswb 0xbabecafe,%xmm5
+
+// CHECK: packsswb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0x2d,0x78,0x56,0x34,0x12]
+ packsswb 0x12345678,%xmm5
+
+// CHECK: packsswb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x63,0xed]
+ packsswb %xmm5,%xmm5
+
+// CHECK: packuswb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x67,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ packuswb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: packuswb 69, %mm3
+// CHECK: encoding: [0x0f,0x67,0x1d,0x45,0x00,0x00,0x00]
+ packuswb 0x45,%mm3
+
+// CHECK: packuswb 32493, %mm3
+// CHECK: encoding: [0x0f,0x67,0x1d,0xed,0x7e,0x00,0x00]
+ packuswb 0x7eed,%mm3
+
+// CHECK: packuswb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x67,0x1d,0xfe,0xca,0xbe,0xba]
+ packuswb 0xbabecafe,%mm3
+
+// CHECK: packuswb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x67,0x1d,0x78,0x56,0x34,0x12]
+ packuswb 0x12345678,%mm3
+
+// CHECK: packuswb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x67,0xdb]
+ packuswb %mm3,%mm3
+
+// CHECK: packuswb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ packuswb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packuswb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0x2d,0x45,0x00,0x00,0x00]
+ packuswb 0x45,%xmm5
+
+// CHECK: packuswb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0x2d,0xed,0x7e,0x00,0x00]
+ packuswb 0x7eed,%xmm5
+
+// CHECK: packuswb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0x2d,0xfe,0xca,0xbe,0xba]
+ packuswb 0xbabecafe,%xmm5
+
+// CHECK: packuswb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0x2d,0x78,0x56,0x34,0x12]
+ packuswb 0x12345678,%xmm5
+
+// CHECK: packuswb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x67,0xed]
+ packuswb %xmm5,%xmm5
+
+// CHECK: paddb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xfc,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddb 69, %mm3
+// CHECK: encoding: [0x0f,0xfc,0x1d,0x45,0x00,0x00,0x00]
+ paddb 0x45,%mm3
+
+// CHECK: paddb 32493, %mm3
+// CHECK: encoding: [0x0f,0xfc,0x1d,0xed,0x7e,0x00,0x00]
+ paddb 0x7eed,%mm3
+
+// CHECK: paddb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xfc,0x1d,0xfe,0xca,0xbe,0xba]
+ paddb 0xbabecafe,%mm3
+
+// CHECK: paddb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xfc,0x1d,0x78,0x56,0x34,0x12]
+ paddb 0x12345678,%mm3
+
+// CHECK: paddb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xfc,0xdb]
+ paddb %mm3,%mm3
+
+// CHECK: paddb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0x2d,0x45,0x00,0x00,0x00]
+ paddb 0x45,%xmm5
+
+// CHECK: paddb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0x2d,0xed,0x7e,0x00,0x00]
+ paddb 0x7eed,%xmm5
+
+// CHECK: paddb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0x2d,0xfe,0xca,0xbe,0xba]
+ paddb 0xbabecafe,%xmm5
+
+// CHECK: paddb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0x2d,0x78,0x56,0x34,0x12]
+ paddb 0x12345678,%xmm5
+
+// CHECK: paddb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfc,0xed]
+ paddb %xmm5,%xmm5
+
+// CHECK: paddw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xfd,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddw 69, %mm3
+// CHECK: encoding: [0x0f,0xfd,0x1d,0x45,0x00,0x00,0x00]
+ paddw 0x45,%mm3
+
+// CHECK: paddw 32493, %mm3
+// CHECK: encoding: [0x0f,0xfd,0x1d,0xed,0x7e,0x00,0x00]
+ paddw 0x7eed,%mm3
+
+// CHECK: paddw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xfd,0x1d,0xfe,0xca,0xbe,0xba]
+ paddw 0xbabecafe,%mm3
+
+// CHECK: paddw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xfd,0x1d,0x78,0x56,0x34,0x12]
+ paddw 0x12345678,%mm3
+
+// CHECK: paddw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xfd,0xdb]
+ paddw %mm3,%mm3
+
+// CHECK: paddw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0x2d,0x45,0x00,0x00,0x00]
+ paddw 0x45,%xmm5
+
+// CHECK: paddw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0x2d,0xed,0x7e,0x00,0x00]
+ paddw 0x7eed,%xmm5
+
+// CHECK: paddw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0x2d,0xfe,0xca,0xbe,0xba]
+ paddw 0xbabecafe,%xmm5
+
+// CHECK: paddw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0x2d,0x78,0x56,0x34,0x12]
+ paddw 0x12345678,%xmm5
+
+// CHECK: paddw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfd,0xed]
+ paddw %xmm5,%xmm5
+
+// CHECK: paddd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xfe,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddd 69, %mm3
+// CHECK: encoding: [0x0f,0xfe,0x1d,0x45,0x00,0x00,0x00]
+ paddd 0x45,%mm3
+
+// CHECK: paddd 32493, %mm3
+// CHECK: encoding: [0x0f,0xfe,0x1d,0xed,0x7e,0x00,0x00]
+ paddd 0x7eed,%mm3
+
+// CHECK: paddd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xfe,0x1d,0xfe,0xca,0xbe,0xba]
+ paddd 0xbabecafe,%mm3
+
+// CHECK: paddd 305419896, %mm3
+// CHECK: encoding: [0x0f,0xfe,0x1d,0x78,0x56,0x34,0x12]
+ paddd 0x12345678,%mm3
+
+// CHECK: paddd %mm3, %mm3
+// CHECK: encoding: [0x0f,0xfe,0xdb]
+ paddd %mm3,%mm3
+
+// CHECK: paddd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0x2d,0x45,0x00,0x00,0x00]
+ paddd 0x45,%xmm5
+
+// CHECK: paddd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0x2d,0xed,0x7e,0x00,0x00]
+ paddd 0x7eed,%xmm5
+
+// CHECK: paddd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0x2d,0xfe,0xca,0xbe,0xba]
+ paddd 0xbabecafe,%xmm5
+
+// CHECK: paddd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0x2d,0x78,0x56,0x34,0x12]
+ paddd 0x12345678,%xmm5
+
+// CHECK: paddd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfe,0xed]
+ paddd %xmm5,%xmm5
+
+// CHECK: paddq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd4,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddq 69, %mm3
+// CHECK: encoding: [0x0f,0xd4,0x1d,0x45,0x00,0x00,0x00]
+ paddq 0x45,%mm3
+
+// CHECK: paddq 32493, %mm3
+// CHECK: encoding: [0x0f,0xd4,0x1d,0xed,0x7e,0x00,0x00]
+ paddq 0x7eed,%mm3
+
+// CHECK: paddq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd4,0x1d,0xfe,0xca,0xbe,0xba]
+ paddq 0xbabecafe,%mm3
+
+// CHECK: paddq 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd4,0x1d,0x78,0x56,0x34,0x12]
+ paddq 0x12345678,%mm3
+
+// CHECK: paddq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd4,0xdb]
+ paddq %mm3,%mm3
+
+// CHECK: paddq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0x2d,0x45,0x00,0x00,0x00]
+ paddq 0x45,%xmm5
+
+// CHECK: paddq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0x2d,0xed,0x7e,0x00,0x00]
+ paddq 0x7eed,%xmm5
+
+// CHECK: paddq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0x2d,0xfe,0xca,0xbe,0xba]
+ paddq 0xbabecafe,%xmm5
+
+// CHECK: paddq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0x2d,0x78,0x56,0x34,0x12]
+ paddq 0x12345678,%xmm5
+
+// CHECK: paddq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd4,0xed]
+ paddq %xmm5,%xmm5
+
+// CHECK: paddsb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xec,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddsb 69, %mm3
+// CHECK: encoding: [0x0f,0xec,0x1d,0x45,0x00,0x00,0x00]
+ paddsb 0x45,%mm3
+
+// CHECK: paddsb 32493, %mm3
+// CHECK: encoding: [0x0f,0xec,0x1d,0xed,0x7e,0x00,0x00]
+ paddsb 0x7eed,%mm3
+
+// CHECK: paddsb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xec,0x1d,0xfe,0xca,0xbe,0xba]
+ paddsb 0xbabecafe,%mm3
+
+// CHECK: paddsb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xec,0x1d,0x78,0x56,0x34,0x12]
+ paddsb 0x12345678,%mm3
+
+// CHECK: paddsb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xec,0xdb]
+ paddsb %mm3,%mm3
+
+// CHECK: paddsb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddsb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0x2d,0x45,0x00,0x00,0x00]
+ paddsb 0x45,%xmm5
+
+// CHECK: paddsb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0x2d,0xed,0x7e,0x00,0x00]
+ paddsb 0x7eed,%xmm5
+
+// CHECK: paddsb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0x2d,0xfe,0xca,0xbe,0xba]
+ paddsb 0xbabecafe,%xmm5
+
+// CHECK: paddsb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0x2d,0x78,0x56,0x34,0x12]
+ paddsb 0x12345678,%xmm5
+
+// CHECK: paddsb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xec,0xed]
+ paddsb %xmm5,%xmm5
+
+// CHECK: paddsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xed,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddsw 69, %mm3
+// CHECK: encoding: [0x0f,0xed,0x1d,0x45,0x00,0x00,0x00]
+ paddsw 0x45,%mm3
+
+// CHECK: paddsw 32493, %mm3
+// CHECK: encoding: [0x0f,0xed,0x1d,0xed,0x7e,0x00,0x00]
+ paddsw 0x7eed,%mm3
+
+// CHECK: paddsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xed,0x1d,0xfe,0xca,0xbe,0xba]
+ paddsw 0xbabecafe,%mm3
+
+// CHECK: paddsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xed,0x1d,0x78,0x56,0x34,0x12]
+ paddsw 0x12345678,%mm3
+
+// CHECK: paddsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xed,0xdb]
+ paddsw %mm3,%mm3
+
+// CHECK: paddsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0x2d,0x45,0x00,0x00,0x00]
+ paddsw 0x45,%xmm5
+
+// CHECK: paddsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0x2d,0xed,0x7e,0x00,0x00]
+ paddsw 0x7eed,%xmm5
+
+// CHECK: paddsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0x2d,0xfe,0xca,0xbe,0xba]
+ paddsw 0xbabecafe,%xmm5
+
+// CHECK: paddsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0x2d,0x78,0x56,0x34,0x12]
+ paddsw 0x12345678,%xmm5
+
+// CHECK: paddsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xed,0xed]
+ paddsw %xmm5,%xmm5
+
+// CHECK: paddusb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xdc,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddusb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddusb 69, %mm3
+// CHECK: encoding: [0x0f,0xdc,0x1d,0x45,0x00,0x00,0x00]
+ paddusb 0x45,%mm3
+
+// CHECK: paddusb 32493, %mm3
+// CHECK: encoding: [0x0f,0xdc,0x1d,0xed,0x7e,0x00,0x00]
+ paddusb 0x7eed,%mm3
+
+// CHECK: paddusb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xdc,0x1d,0xfe,0xca,0xbe,0xba]
+ paddusb 0xbabecafe,%mm3
+
+// CHECK: paddusb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xdc,0x1d,0x78,0x56,0x34,0x12]
+ paddusb 0x12345678,%mm3
+
+// CHECK: paddusb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xdc,0xdb]
+ paddusb %mm3,%mm3
+
+// CHECK: paddusb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddusb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddusb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0x2d,0x45,0x00,0x00,0x00]
+ paddusb 0x45,%xmm5
+
+// CHECK: paddusb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0x2d,0xed,0x7e,0x00,0x00]
+ paddusb 0x7eed,%xmm5
+
+// CHECK: paddusb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0x2d,0xfe,0xca,0xbe,0xba]
+ paddusb 0xbabecafe,%xmm5
+
+// CHECK: paddusb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0x2d,0x78,0x56,0x34,0x12]
+ paddusb 0x12345678,%xmm5
+
+// CHECK: paddusb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdc,0xed]
+ paddusb %xmm5,%xmm5
+
+// CHECK: paddusw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xdd,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ paddusw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: paddusw 69, %mm3
+// CHECK: encoding: [0x0f,0xdd,0x1d,0x45,0x00,0x00,0x00]
+ paddusw 0x45,%mm3
+
+// CHECK: paddusw 32493, %mm3
+// CHECK: encoding: [0x0f,0xdd,0x1d,0xed,0x7e,0x00,0x00]
+ paddusw 0x7eed,%mm3
+
+// CHECK: paddusw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xdd,0x1d,0xfe,0xca,0xbe,0xba]
+ paddusw 0xbabecafe,%mm3
+
+// CHECK: paddusw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xdd,0x1d,0x78,0x56,0x34,0x12]
+ paddusw 0x12345678,%mm3
+
+// CHECK: paddusw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xdd,0xdb]
+ paddusw %mm3,%mm3
+
+// CHECK: paddusw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ paddusw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: paddusw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0x2d,0x45,0x00,0x00,0x00]
+ paddusw 0x45,%xmm5
+
+// CHECK: paddusw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0x2d,0xed,0x7e,0x00,0x00]
+ paddusw 0x7eed,%xmm5
+
+// CHECK: paddusw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0x2d,0xfe,0xca,0xbe,0xba]
+ paddusw 0xbabecafe,%xmm5
+
+// CHECK: paddusw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0x2d,0x78,0x56,0x34,0x12]
+ paddusw 0x12345678,%xmm5
+
+// CHECK: paddusw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdd,0xed]
+ paddusw %xmm5,%xmm5
+
+// CHECK: pand 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xdb,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pand 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pand 69, %mm3
+// CHECK: encoding: [0x0f,0xdb,0x1d,0x45,0x00,0x00,0x00]
+ pand 0x45,%mm3
+
+// CHECK: pand 32493, %mm3
+// CHECK: encoding: [0x0f,0xdb,0x1d,0xed,0x7e,0x00,0x00]
+ pand 0x7eed,%mm3
+
+// CHECK: pand 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xdb,0x1d,0xfe,0xca,0xbe,0xba]
+ pand 0xbabecafe,%mm3
+
+// CHECK: pand 305419896, %mm3
+// CHECK: encoding: [0x0f,0xdb,0x1d,0x78,0x56,0x34,0x12]
+ pand 0x12345678,%mm3
+
+// CHECK: pand %mm3, %mm3
+// CHECK: encoding: [0x0f,0xdb,0xdb]
+ pand %mm3,%mm3
+
+// CHECK: pand 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pand 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pand 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0x2d,0x45,0x00,0x00,0x00]
+ pand 0x45,%xmm5
+
+// CHECK: pand 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0x2d,0xed,0x7e,0x00,0x00]
+ pand 0x7eed,%xmm5
+
+// CHECK: pand 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0x2d,0xfe,0xca,0xbe,0xba]
+ pand 0xbabecafe,%xmm5
+
+// CHECK: pand 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0x2d,0x78,0x56,0x34,0x12]
+ pand 0x12345678,%xmm5
+
+// CHECK: pand %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdb,0xed]
+ pand %xmm5,%xmm5
+
+// CHECK: pandn 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xdf,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pandn 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pandn 69, %mm3
+// CHECK: encoding: [0x0f,0xdf,0x1d,0x45,0x00,0x00,0x00]
+ pandn 0x45,%mm3
+
+// CHECK: pandn 32493, %mm3
+// CHECK: encoding: [0x0f,0xdf,0x1d,0xed,0x7e,0x00,0x00]
+ pandn 0x7eed,%mm3
+
+// CHECK: pandn 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xdf,0x1d,0xfe,0xca,0xbe,0xba]
+ pandn 0xbabecafe,%mm3
+
+// CHECK: pandn 305419896, %mm3
+// CHECK: encoding: [0x0f,0xdf,0x1d,0x78,0x56,0x34,0x12]
+ pandn 0x12345678,%mm3
+
+// CHECK: pandn %mm3, %mm3
+// CHECK: encoding: [0x0f,0xdf,0xdb]
+ pandn %mm3,%mm3
+
+// CHECK: pandn 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pandn 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pandn 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0x2d,0x45,0x00,0x00,0x00]
+ pandn 0x45,%xmm5
+
+// CHECK: pandn 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0x2d,0xed,0x7e,0x00,0x00]
+ pandn 0x7eed,%xmm5
+
+// CHECK: pandn 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0x2d,0xfe,0xca,0xbe,0xba]
+ pandn 0xbabecafe,%xmm5
+
+// CHECK: pandn 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0x2d,0x78,0x56,0x34,0x12]
+ pandn 0x12345678,%xmm5
+
+// CHECK: pandn %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xdf,0xed]
+ pandn %xmm5,%xmm5
+
+// CHECK: pcmpeqb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x74,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpeqb 69, %mm3
+// CHECK: encoding: [0x0f,0x74,0x1d,0x45,0x00,0x00,0x00]
+ pcmpeqb 0x45,%mm3
+
+// CHECK: pcmpeqb 32493, %mm3
+// CHECK: encoding: [0x0f,0x74,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpeqb 0x7eed,%mm3
+
+// CHECK: pcmpeqb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x74,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpeqb 0xbabecafe,%mm3
+
+// CHECK: pcmpeqb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x74,0x1d,0x78,0x56,0x34,0x12]
+ pcmpeqb 0x12345678,%mm3
+
+// CHECK: pcmpeqb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x74,0xdb]
+ pcmpeqb %mm3,%mm3
+
+// CHECK: pcmpeqb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0x2d,0x45,0x00,0x00,0x00]
+ pcmpeqb 0x45,%xmm5
+
+// CHECK: pcmpeqb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpeqb 0x7eed,%xmm5
+
+// CHECK: pcmpeqb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpeqb 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0x2d,0x78,0x56,0x34,0x12]
+ pcmpeqb 0x12345678,%xmm5
+
+// CHECK: pcmpeqb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x74,0xed]
+ pcmpeqb %xmm5,%xmm5
+
+// CHECK: pcmpeqw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x75,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpeqw 69, %mm3
+// CHECK: encoding: [0x0f,0x75,0x1d,0x45,0x00,0x00,0x00]
+ pcmpeqw 0x45,%mm3
+
+// CHECK: pcmpeqw 32493, %mm3
+// CHECK: encoding: [0x0f,0x75,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpeqw 0x7eed,%mm3
+
+// CHECK: pcmpeqw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x75,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpeqw 0xbabecafe,%mm3
+
+// CHECK: pcmpeqw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x75,0x1d,0x78,0x56,0x34,0x12]
+ pcmpeqw 0x12345678,%mm3
+
+// CHECK: pcmpeqw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x75,0xdb]
+ pcmpeqw %mm3,%mm3
+
+// CHECK: pcmpeqw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0x2d,0x45,0x00,0x00,0x00]
+ pcmpeqw 0x45,%xmm5
+
+// CHECK: pcmpeqw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpeqw 0x7eed,%xmm5
+
+// CHECK: pcmpeqw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpeqw 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0x2d,0x78,0x56,0x34,0x12]
+ pcmpeqw 0x12345678,%xmm5
+
+// CHECK: pcmpeqw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x75,0xed]
+ pcmpeqw %xmm5,%xmm5
+
+// CHECK: pcmpeqd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x76,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpeqd 69, %mm3
+// CHECK: encoding: [0x0f,0x76,0x1d,0x45,0x00,0x00,0x00]
+ pcmpeqd 0x45,%mm3
+
+// CHECK: pcmpeqd 32493, %mm3
+// CHECK: encoding: [0x0f,0x76,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpeqd 0x7eed,%mm3
+
+// CHECK: pcmpeqd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x76,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpeqd 0xbabecafe,%mm3
+
+// CHECK: pcmpeqd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x76,0x1d,0x78,0x56,0x34,0x12]
+ pcmpeqd 0x12345678,%mm3
+
+// CHECK: pcmpeqd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x76,0xdb]
+ pcmpeqd %mm3,%mm3
+
+// CHECK: pcmpeqd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0x2d,0x45,0x00,0x00,0x00]
+ pcmpeqd 0x45,%xmm5
+
+// CHECK: pcmpeqd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpeqd 0x7eed,%xmm5
+
+// CHECK: pcmpeqd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpeqd 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0x2d,0x78,0x56,0x34,0x12]
+ pcmpeqd 0x12345678,%xmm5
+
+// CHECK: pcmpeqd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x76,0xed]
+ pcmpeqd %xmm5,%xmm5
+
+// CHECK: pcmpgtb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x64,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpgtb 69, %mm3
+// CHECK: encoding: [0x0f,0x64,0x1d,0x45,0x00,0x00,0x00]
+ pcmpgtb 0x45,%mm3
+
+// CHECK: pcmpgtb 32493, %mm3
+// CHECK: encoding: [0x0f,0x64,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpgtb 0x7eed,%mm3
+
+// CHECK: pcmpgtb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x64,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpgtb 0xbabecafe,%mm3
+
+// CHECK: pcmpgtb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x64,0x1d,0x78,0x56,0x34,0x12]
+ pcmpgtb 0x12345678,%mm3
+
+// CHECK: pcmpgtb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x64,0xdb]
+ pcmpgtb %mm3,%mm3
+
+// CHECK: pcmpgtb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0x2d,0x45,0x00,0x00,0x00]
+ pcmpgtb 0x45,%xmm5
+
+// CHECK: pcmpgtb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpgtb 0x7eed,%xmm5
+
+// CHECK: pcmpgtb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpgtb 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0x2d,0x78,0x56,0x34,0x12]
+ pcmpgtb 0x12345678,%xmm5
+
+// CHECK: pcmpgtb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x64,0xed]
+ pcmpgtb %xmm5,%xmm5
+
+// CHECK: pcmpgtw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x65,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpgtw 69, %mm3
+// CHECK: encoding: [0x0f,0x65,0x1d,0x45,0x00,0x00,0x00]
+ pcmpgtw 0x45,%mm3
+
+// CHECK: pcmpgtw 32493, %mm3
+// CHECK: encoding: [0x0f,0x65,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpgtw 0x7eed,%mm3
+
+// CHECK: pcmpgtw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x65,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpgtw 0xbabecafe,%mm3
+
+// CHECK: pcmpgtw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x65,0x1d,0x78,0x56,0x34,0x12]
+ pcmpgtw 0x12345678,%mm3
+
+// CHECK: pcmpgtw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x65,0xdb]
+ pcmpgtw %mm3,%mm3
+
+// CHECK: pcmpgtw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0x2d,0x45,0x00,0x00,0x00]
+ pcmpgtw 0x45,%xmm5
+
+// CHECK: pcmpgtw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpgtw 0x7eed,%xmm5
+
+// CHECK: pcmpgtw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpgtw 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0x2d,0x78,0x56,0x34,0x12]
+ pcmpgtw 0x12345678,%xmm5
+
+// CHECK: pcmpgtw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x65,0xed]
+ pcmpgtw %xmm5,%xmm5
+
+// CHECK: pcmpgtd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x66,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pcmpgtd 69, %mm3
+// CHECK: encoding: [0x0f,0x66,0x1d,0x45,0x00,0x00,0x00]
+ pcmpgtd 0x45,%mm3
+
+// CHECK: pcmpgtd 32493, %mm3
+// CHECK: encoding: [0x0f,0x66,0x1d,0xed,0x7e,0x00,0x00]
+ pcmpgtd 0x7eed,%mm3
+
+// CHECK: pcmpgtd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x66,0x1d,0xfe,0xca,0xbe,0xba]
+ pcmpgtd 0xbabecafe,%mm3
+
+// CHECK: pcmpgtd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x66,0x1d,0x78,0x56,0x34,0x12]
+ pcmpgtd 0x12345678,%mm3
+
+// CHECK: pcmpgtd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x66,0xdb]
+ pcmpgtd %mm3,%mm3
+
+// CHECK: pcmpgtd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0x2d,0x45,0x00,0x00,0x00]
+ pcmpgtd 0x45,%xmm5
+
+// CHECK: pcmpgtd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpgtd 0x7eed,%xmm5
+
+// CHECK: pcmpgtd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpgtd 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0x2d,0x78,0x56,0x34,0x12]
+ pcmpgtd 0x12345678,%xmm5
+
+// CHECK: pcmpgtd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x66,0xed]
+ pcmpgtd %xmm5,%xmm5
+
+// CHECK: pmaddwd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf5,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmaddwd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaddwd 69, %mm3
+// CHECK: encoding: [0x0f,0xf5,0x1d,0x45,0x00,0x00,0x00]
+ pmaddwd 0x45,%mm3
+
+// CHECK: pmaddwd 32493, %mm3
+// CHECK: encoding: [0x0f,0xf5,0x1d,0xed,0x7e,0x00,0x00]
+ pmaddwd 0x7eed,%mm3
+
+// CHECK: pmaddwd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf5,0x1d,0xfe,0xca,0xbe,0xba]
+ pmaddwd 0xbabecafe,%mm3
+
+// CHECK: pmaddwd 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf5,0x1d,0x78,0x56,0x34,0x12]
+ pmaddwd 0x12345678,%mm3
+
+// CHECK: pmaddwd %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf5,0xdb]
+ pmaddwd %mm3,%mm3
+
+// CHECK: pmaddwd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaddwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaddwd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0x2d,0x45,0x00,0x00,0x00]
+ pmaddwd 0x45,%xmm5
+
+// CHECK: pmaddwd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0x2d,0xed,0x7e,0x00,0x00]
+ pmaddwd 0x7eed,%xmm5
+
+// CHECK: pmaddwd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaddwd 0xbabecafe,%xmm5
+
+// CHECK: pmaddwd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0x2d,0x78,0x56,0x34,0x12]
+ pmaddwd 0x12345678,%xmm5
+
+// CHECK: pmaddwd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf5,0xed]
+ pmaddwd %xmm5,%xmm5
+
+// CHECK: pmulhw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe5,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmulhw 69, %mm3
+// CHECK: encoding: [0x0f,0xe5,0x1d,0x45,0x00,0x00,0x00]
+ pmulhw 0x45,%mm3
+
+// CHECK: pmulhw 32493, %mm3
+// CHECK: encoding: [0x0f,0xe5,0x1d,0xed,0x7e,0x00,0x00]
+ pmulhw 0x7eed,%mm3
+
+// CHECK: pmulhw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe5,0x1d,0xfe,0xca,0xbe,0xba]
+ pmulhw 0xbabecafe,%mm3
+
+// CHECK: pmulhw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe5,0x1d,0x78,0x56,0x34,0x12]
+ pmulhw 0x12345678,%mm3
+
+// CHECK: pmulhw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe5,0xdb]
+ pmulhw %mm3,%mm3
+
+// CHECK: pmulhw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulhw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0x2d,0x45,0x00,0x00,0x00]
+ pmulhw 0x45,%xmm5
+
+// CHECK: pmulhw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0x2d,0xed,0x7e,0x00,0x00]
+ pmulhw 0x7eed,%xmm5
+
+// CHECK: pmulhw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0x2d,0xfe,0xca,0xbe,0xba]
+ pmulhw 0xbabecafe,%xmm5
+
+// CHECK: pmulhw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0x2d,0x78,0x56,0x34,0x12]
+ pmulhw 0x12345678,%xmm5
+
+// CHECK: pmulhw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe5,0xed]
+ pmulhw %xmm5,%xmm5
+
+// CHECK: pmullw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd5,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmullw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmullw 69, %mm3
+// CHECK: encoding: [0x0f,0xd5,0x1d,0x45,0x00,0x00,0x00]
+ pmullw 0x45,%mm3
+
+// CHECK: pmullw 32493, %mm3
+// CHECK: encoding: [0x0f,0xd5,0x1d,0xed,0x7e,0x00,0x00]
+ pmullw 0x7eed,%mm3
+
+// CHECK: pmullw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd5,0x1d,0xfe,0xca,0xbe,0xba]
+ pmullw 0xbabecafe,%mm3
+
+// CHECK: pmullw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd5,0x1d,0x78,0x56,0x34,0x12]
+ pmullw 0x12345678,%mm3
+
+// CHECK: pmullw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd5,0xdb]
+ pmullw %mm3,%mm3
+
+// CHECK: pmullw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmullw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmullw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0x2d,0x45,0x00,0x00,0x00]
+ pmullw 0x45,%xmm5
+
+// CHECK: pmullw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0x2d,0xed,0x7e,0x00,0x00]
+ pmullw 0x7eed,%xmm5
+
+// CHECK: pmullw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0x2d,0xfe,0xca,0xbe,0xba]
+ pmullw 0xbabecafe,%xmm5
+
+// CHECK: pmullw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0x2d,0x78,0x56,0x34,0x12]
+ pmullw 0x12345678,%xmm5
+
+// CHECK: pmullw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd5,0xed]
+ pmullw %xmm5,%xmm5
+
+// CHECK: por 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xeb,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ por 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: por 69, %mm3
+// CHECK: encoding: [0x0f,0xeb,0x1d,0x45,0x00,0x00,0x00]
+ por 0x45,%mm3
+
+// CHECK: por 32493, %mm3
+// CHECK: encoding: [0x0f,0xeb,0x1d,0xed,0x7e,0x00,0x00]
+ por 0x7eed,%mm3
+
+// CHECK: por 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xeb,0x1d,0xfe,0xca,0xbe,0xba]
+ por 0xbabecafe,%mm3
+
+// CHECK: por 305419896, %mm3
+// CHECK: encoding: [0x0f,0xeb,0x1d,0x78,0x56,0x34,0x12]
+ por 0x12345678,%mm3
+
+// CHECK: por %mm3, %mm3
+// CHECK: encoding: [0x0f,0xeb,0xdb]
+ por %mm3,%mm3
+
+// CHECK: por 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ por 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: por 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0x2d,0x45,0x00,0x00,0x00]
+ por 0x45,%xmm5
+
+// CHECK: por 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0x2d,0xed,0x7e,0x00,0x00]
+ por 0x7eed,%xmm5
+
+// CHECK: por 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0x2d,0xfe,0xca,0xbe,0xba]
+ por 0xbabecafe,%xmm5
+
+// CHECK: por 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0x2d,0x78,0x56,0x34,0x12]
+ por 0x12345678,%xmm5
+
+// CHECK: por %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xeb,0xed]
+ por %xmm5,%xmm5
+
+// CHECK: psllw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf1,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psllw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psllw 69, %mm3
+// CHECK: encoding: [0x0f,0xf1,0x1d,0x45,0x00,0x00,0x00]
+ psllw 0x45,%mm3
+
+// CHECK: psllw 32493, %mm3
+// CHECK: encoding: [0x0f,0xf1,0x1d,0xed,0x7e,0x00,0x00]
+ psllw 0x7eed,%mm3
+
+// CHECK: psllw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf1,0x1d,0xfe,0xca,0xbe,0xba]
+ psllw 0xbabecafe,%mm3
+
+// CHECK: psllw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf1,0x1d,0x78,0x56,0x34,0x12]
+ psllw 0x12345678,%mm3
+
+// CHECK: psllw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf1,0xdb]
+ psllw %mm3,%mm3
+
+// CHECK: psllw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psllw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psllw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0x2d,0x45,0x00,0x00,0x00]
+ psllw 0x45,%xmm5
+
+// CHECK: psllw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0x2d,0xed,0x7e,0x00,0x00]
+ psllw 0x7eed,%xmm5
+
+// CHECK: psllw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0x2d,0xfe,0xca,0xbe,0xba]
+ psllw 0xbabecafe,%xmm5
+
+// CHECK: psllw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0x2d,0x78,0x56,0x34,0x12]
+ psllw 0x12345678,%xmm5
+
+// CHECK: psllw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf1,0xed]
+ psllw %xmm5,%xmm5
+
+// CHECK: psllw $127, %mm3
+// CHECK: encoding: [0x0f,0x71,0xf3,0x7f]
+ psllw $0x7f,%mm3
+
+// CHECK: psllw $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x71,0xf5,0x7f]
+ psllw $0x7f,%xmm5
+
+// CHECK: pslld 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf2,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pslld 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pslld 69, %mm3
+// CHECK: encoding: [0x0f,0xf2,0x1d,0x45,0x00,0x00,0x00]
+ pslld 0x45,%mm3
+
+// CHECK: pslld 32493, %mm3
+// CHECK: encoding: [0x0f,0xf2,0x1d,0xed,0x7e,0x00,0x00]
+ pslld 0x7eed,%mm3
+
+// CHECK: pslld 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf2,0x1d,0xfe,0xca,0xbe,0xba]
+ pslld 0xbabecafe,%mm3
+
+// CHECK: pslld 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf2,0x1d,0x78,0x56,0x34,0x12]
+ pslld 0x12345678,%mm3
+
+// CHECK: pslld %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf2,0xdb]
+ pslld %mm3,%mm3
+
+// CHECK: pslld 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pslld 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pslld 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0x2d,0x45,0x00,0x00,0x00]
+ pslld 0x45,%xmm5
+
+// CHECK: pslld 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0x2d,0xed,0x7e,0x00,0x00]
+ pslld 0x7eed,%xmm5
+
+// CHECK: pslld 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0x2d,0xfe,0xca,0xbe,0xba]
+ pslld 0xbabecafe,%xmm5
+
+// CHECK: pslld 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0x2d,0x78,0x56,0x34,0x12]
+ pslld 0x12345678,%xmm5
+
+// CHECK: pslld %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf2,0xed]
+ pslld %xmm5,%xmm5
+
+// CHECK: pslld $127, %mm3
+// CHECK: encoding: [0x0f,0x72,0xf3,0x7f]
+ pslld $0x7f,%mm3
+
+// CHECK: pslld $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x72,0xf5,0x7f]
+ pslld $0x7f,%xmm5
+
+// CHECK: psllq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf3,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psllq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psllq 69, %mm3
+// CHECK: encoding: [0x0f,0xf3,0x1d,0x45,0x00,0x00,0x00]
+ psllq 0x45,%mm3
+
+// CHECK: psllq 32493, %mm3
+// CHECK: encoding: [0x0f,0xf3,0x1d,0xed,0x7e,0x00,0x00]
+ psllq 0x7eed,%mm3
+
+// CHECK: psllq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf3,0x1d,0xfe,0xca,0xbe,0xba]
+ psllq 0xbabecafe,%mm3
+
+// CHECK: psllq 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf3,0x1d,0x78,0x56,0x34,0x12]
+ psllq 0x12345678,%mm3
+
+// CHECK: psllq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf3,0xdb]
+ psllq %mm3,%mm3
+
+// CHECK: psllq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psllq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psllq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0x2d,0x45,0x00,0x00,0x00]
+ psllq 0x45,%xmm5
+
+// CHECK: psllq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0x2d,0xed,0x7e,0x00,0x00]
+ psllq 0x7eed,%xmm5
+
+// CHECK: psllq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0x2d,0xfe,0xca,0xbe,0xba]
+ psllq 0xbabecafe,%xmm5
+
+// CHECK: psllq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0x2d,0x78,0x56,0x34,0x12]
+ psllq 0x12345678,%xmm5
+
+// CHECK: psllq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf3,0xed]
+ psllq %xmm5,%xmm5
+
+// CHECK: psllq $127, %mm3
+// CHECK: encoding: [0x0f,0x73,0xf3,0x7f]
+ psllq $0x7f,%mm3
+
+// CHECK: psllq $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x73,0xf5,0x7f]
+ psllq $0x7f,%xmm5
+
+// CHECK: psraw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe1,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psraw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psraw 69, %mm3
+// CHECK: encoding: [0x0f,0xe1,0x1d,0x45,0x00,0x00,0x00]
+ psraw 0x45,%mm3
+
+// CHECK: psraw 32493, %mm3
+// CHECK: encoding: [0x0f,0xe1,0x1d,0xed,0x7e,0x00,0x00]
+ psraw 0x7eed,%mm3
+
+// CHECK: psraw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe1,0x1d,0xfe,0xca,0xbe,0xba]
+ psraw 0xbabecafe,%mm3
+
+// CHECK: psraw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe1,0x1d,0x78,0x56,0x34,0x12]
+ psraw 0x12345678,%mm3
+
+// CHECK: psraw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe1,0xdb]
+ psraw %mm3,%mm3
+
+// CHECK: psraw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psraw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psraw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0x2d,0x45,0x00,0x00,0x00]
+ psraw 0x45,%xmm5
+
+// CHECK: psraw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0x2d,0xed,0x7e,0x00,0x00]
+ psraw 0x7eed,%xmm5
+
+// CHECK: psraw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0x2d,0xfe,0xca,0xbe,0xba]
+ psraw 0xbabecafe,%xmm5
+
+// CHECK: psraw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0x2d,0x78,0x56,0x34,0x12]
+ psraw 0x12345678,%xmm5
+
+// CHECK: psraw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe1,0xed]
+ psraw %xmm5,%xmm5
+
+// CHECK: psraw $127, %mm3
+// CHECK: encoding: [0x0f,0x71,0xe3,0x7f]
+ psraw $0x7f,%mm3
+
+// CHECK: psraw $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x71,0xe5,0x7f]
+ psraw $0x7f,%xmm5
+
+// CHECK: psrad 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe2,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psrad 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrad 69, %mm3
+// CHECK: encoding: [0x0f,0xe2,0x1d,0x45,0x00,0x00,0x00]
+ psrad 0x45,%mm3
+
+// CHECK: psrad 32493, %mm3
+// CHECK: encoding: [0x0f,0xe2,0x1d,0xed,0x7e,0x00,0x00]
+ psrad 0x7eed,%mm3
+
+// CHECK: psrad 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe2,0x1d,0xfe,0xca,0xbe,0xba]
+ psrad 0xbabecafe,%mm3
+
+// CHECK: psrad 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe2,0x1d,0x78,0x56,0x34,0x12]
+ psrad 0x12345678,%mm3
+
+// CHECK: psrad %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe2,0xdb]
+ psrad %mm3,%mm3
+
+// CHECK: psrad 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psrad 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrad 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0x2d,0x45,0x00,0x00,0x00]
+ psrad 0x45,%xmm5
+
+// CHECK: psrad 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0x2d,0xed,0x7e,0x00,0x00]
+ psrad 0x7eed,%xmm5
+
+// CHECK: psrad 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0x2d,0xfe,0xca,0xbe,0xba]
+ psrad 0xbabecafe,%xmm5
+
+// CHECK: psrad 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0x2d,0x78,0x56,0x34,0x12]
+ psrad 0x12345678,%xmm5
+
+// CHECK: psrad %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe2,0xed]
+ psrad %xmm5,%xmm5
+
+// CHECK: psrad $127, %mm3
+// CHECK: encoding: [0x0f,0x72,0xe3,0x7f]
+ psrad $0x7f,%mm3
+
+// CHECK: psrad $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x72,0xe5,0x7f]
+ psrad $0x7f,%xmm5
+
+// CHECK: psrlw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd1,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psrlw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrlw 69, %mm3
+// CHECK: encoding: [0x0f,0xd1,0x1d,0x45,0x00,0x00,0x00]
+ psrlw 0x45,%mm3
+
+// CHECK: psrlw 32493, %mm3
+// CHECK: encoding: [0x0f,0xd1,0x1d,0xed,0x7e,0x00,0x00]
+ psrlw 0x7eed,%mm3
+
+// CHECK: psrlw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd1,0x1d,0xfe,0xca,0xbe,0xba]
+ psrlw 0xbabecafe,%mm3
+
+// CHECK: psrlw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd1,0x1d,0x78,0x56,0x34,0x12]
+ psrlw 0x12345678,%mm3
+
+// CHECK: psrlw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd1,0xdb]
+ psrlw %mm3,%mm3
+
+// CHECK: psrlw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psrlw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrlw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0x2d,0x45,0x00,0x00,0x00]
+ psrlw 0x45,%xmm5
+
+// CHECK: psrlw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0x2d,0xed,0x7e,0x00,0x00]
+ psrlw 0x7eed,%xmm5
+
+// CHECK: psrlw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0x2d,0xfe,0xca,0xbe,0xba]
+ psrlw 0xbabecafe,%xmm5
+
+// CHECK: psrlw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0x2d,0x78,0x56,0x34,0x12]
+ psrlw 0x12345678,%xmm5
+
+// CHECK: psrlw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd1,0xed]
+ psrlw %xmm5,%xmm5
+
+// CHECK: psrlw $127, %mm3
+// CHECK: encoding: [0x0f,0x71,0xd3,0x7f]
+ psrlw $0x7f,%mm3
+
+// CHECK: psrlw $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x71,0xd5,0x7f]
+ psrlw $0x7f,%xmm5
+
+// CHECK: psrld 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd2,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psrld 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrld 69, %mm3
+// CHECK: encoding: [0x0f,0xd2,0x1d,0x45,0x00,0x00,0x00]
+ psrld 0x45,%mm3
+
+// CHECK: psrld 32493, %mm3
+// CHECK: encoding: [0x0f,0xd2,0x1d,0xed,0x7e,0x00,0x00]
+ psrld 0x7eed,%mm3
+
+// CHECK: psrld 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd2,0x1d,0xfe,0xca,0xbe,0xba]
+ psrld 0xbabecafe,%mm3
+
+// CHECK: psrld 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd2,0x1d,0x78,0x56,0x34,0x12]
+ psrld 0x12345678,%mm3
+
+// CHECK: psrld %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd2,0xdb]
+ psrld %mm3,%mm3
+
+// CHECK: psrld 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psrld 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrld 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0x2d,0x45,0x00,0x00,0x00]
+ psrld 0x45,%xmm5
+
+// CHECK: psrld 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0x2d,0xed,0x7e,0x00,0x00]
+ psrld 0x7eed,%xmm5
+
+// CHECK: psrld 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0x2d,0xfe,0xca,0xbe,0xba]
+ psrld 0xbabecafe,%xmm5
+
+// CHECK: psrld 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0x2d,0x78,0x56,0x34,0x12]
+ psrld 0x12345678,%xmm5
+
+// CHECK: psrld %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd2,0xed]
+ psrld %xmm5,%xmm5
+
+// CHECK: psrld $127, %mm3
+// CHECK: encoding: [0x0f,0x72,0xd3,0x7f]
+ psrld $0x7f,%mm3
+
+// CHECK: psrld $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x72,0xd5,0x7f]
+ psrld $0x7f,%xmm5
+
+// CHECK: psrlq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd3,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psrlq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psrlq 69, %mm3
+// CHECK: encoding: [0x0f,0xd3,0x1d,0x45,0x00,0x00,0x00]
+ psrlq 0x45,%mm3
+
+// CHECK: psrlq 32493, %mm3
+// CHECK: encoding: [0x0f,0xd3,0x1d,0xed,0x7e,0x00,0x00]
+ psrlq 0x7eed,%mm3
+
+// CHECK: psrlq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd3,0x1d,0xfe,0xca,0xbe,0xba]
+ psrlq 0xbabecafe,%mm3
+
+// CHECK: psrlq 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd3,0x1d,0x78,0x56,0x34,0x12]
+ psrlq 0x12345678,%mm3
+
+// CHECK: psrlq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd3,0xdb]
+ psrlq %mm3,%mm3
+
+// CHECK: psrlq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psrlq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psrlq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0x2d,0x45,0x00,0x00,0x00]
+ psrlq 0x45,%xmm5
+
+// CHECK: psrlq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0x2d,0xed,0x7e,0x00,0x00]
+ psrlq 0x7eed,%xmm5
+
+// CHECK: psrlq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0x2d,0xfe,0xca,0xbe,0xba]
+ psrlq 0xbabecafe,%xmm5
+
+// CHECK: psrlq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0x2d,0x78,0x56,0x34,0x12]
+ psrlq 0x12345678,%xmm5
+
+// CHECK: psrlq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd3,0xed]
+ psrlq %xmm5,%xmm5
+
+// CHECK: psrlq $127, %mm3
+// CHECK: encoding: [0x0f,0x73,0xd3,0x7f]
+ psrlq $0x7f,%mm3
+
+// CHECK: psrlq $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x73,0xd5,0x7f]
+ psrlq $0x7f,%xmm5
+
+// CHECK: psubb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf8,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubb 69, %mm3
+// CHECK: encoding: [0x0f,0xf8,0x1d,0x45,0x00,0x00,0x00]
+ psubb 0x45,%mm3
+
+// CHECK: psubb 32493, %mm3
+// CHECK: encoding: [0x0f,0xf8,0x1d,0xed,0x7e,0x00,0x00]
+ psubb 0x7eed,%mm3
+
+// CHECK: psubb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf8,0x1d,0xfe,0xca,0xbe,0xba]
+ psubb 0xbabecafe,%mm3
+
+// CHECK: psubb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf8,0x1d,0x78,0x56,0x34,0x12]
+ psubb 0x12345678,%mm3
+
+// CHECK: psubb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf8,0xdb]
+ psubb %mm3,%mm3
+
+// CHECK: psubb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0x2d,0x45,0x00,0x00,0x00]
+ psubb 0x45,%xmm5
+
+// CHECK: psubb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0x2d,0xed,0x7e,0x00,0x00]
+ psubb 0x7eed,%xmm5
+
+// CHECK: psubb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0x2d,0xfe,0xca,0xbe,0xba]
+ psubb 0xbabecafe,%xmm5
+
+// CHECK: psubb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0x2d,0x78,0x56,0x34,0x12]
+ psubb 0x12345678,%xmm5
+
+// CHECK: psubb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf8,0xed]
+ psubb %xmm5,%xmm5
+
+// CHECK: psubw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf9,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubw 69, %mm3
+// CHECK: encoding: [0x0f,0xf9,0x1d,0x45,0x00,0x00,0x00]
+ psubw 0x45,%mm3
+
+// CHECK: psubw 32493, %mm3
+// CHECK: encoding: [0x0f,0xf9,0x1d,0xed,0x7e,0x00,0x00]
+ psubw 0x7eed,%mm3
+
+// CHECK: psubw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf9,0x1d,0xfe,0xca,0xbe,0xba]
+ psubw 0xbabecafe,%mm3
+
+// CHECK: psubw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf9,0x1d,0x78,0x56,0x34,0x12]
+ psubw 0x12345678,%mm3
+
+// CHECK: psubw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf9,0xdb]
+ psubw %mm3,%mm3
+
+// CHECK: psubw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0x2d,0x45,0x00,0x00,0x00]
+ psubw 0x45,%xmm5
+
+// CHECK: psubw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0x2d,0xed,0x7e,0x00,0x00]
+ psubw 0x7eed,%xmm5
+
+// CHECK: psubw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0x2d,0xfe,0xca,0xbe,0xba]
+ psubw 0xbabecafe,%xmm5
+
+// CHECK: psubw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0x2d,0x78,0x56,0x34,0x12]
+ psubw 0x12345678,%xmm5
+
+// CHECK: psubw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf9,0xed]
+ psubw %xmm5,%xmm5
+
+// CHECK: psubd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xfa,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubd 69, %mm3
+// CHECK: encoding: [0x0f,0xfa,0x1d,0x45,0x00,0x00,0x00]
+ psubd 0x45,%mm3
+
+// CHECK: psubd 32493, %mm3
+// CHECK: encoding: [0x0f,0xfa,0x1d,0xed,0x7e,0x00,0x00]
+ psubd 0x7eed,%mm3
+
+// CHECK: psubd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xfa,0x1d,0xfe,0xca,0xbe,0xba]
+ psubd 0xbabecafe,%mm3
+
+// CHECK: psubd 305419896, %mm3
+// CHECK: encoding: [0x0f,0xfa,0x1d,0x78,0x56,0x34,0x12]
+ psubd 0x12345678,%mm3
+
+// CHECK: psubd %mm3, %mm3
+// CHECK: encoding: [0x0f,0xfa,0xdb]
+ psubd %mm3,%mm3
+
+// CHECK: psubd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0x2d,0x45,0x00,0x00,0x00]
+ psubd 0x45,%xmm5
+
+// CHECK: psubd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0x2d,0xed,0x7e,0x00,0x00]
+ psubd 0x7eed,%xmm5
+
+// CHECK: psubd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0x2d,0xfe,0xca,0xbe,0xba]
+ psubd 0xbabecafe,%xmm5
+
+// CHECK: psubd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0x2d,0x78,0x56,0x34,0x12]
+ psubd 0x12345678,%xmm5
+
+// CHECK: psubd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfa,0xed]
+ psubd %xmm5,%xmm5
+
+// CHECK: psubq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xfb,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubq 69, %mm3
+// CHECK: encoding: [0x0f,0xfb,0x1d,0x45,0x00,0x00,0x00]
+ psubq 0x45,%mm3
+
+// CHECK: psubq 32493, %mm3
+// CHECK: encoding: [0x0f,0xfb,0x1d,0xed,0x7e,0x00,0x00]
+ psubq 0x7eed,%mm3
+
+// CHECK: psubq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xfb,0x1d,0xfe,0xca,0xbe,0xba]
+ psubq 0xbabecafe,%mm3
+
+// CHECK: psubq 305419896, %mm3
+// CHECK: encoding: [0x0f,0xfb,0x1d,0x78,0x56,0x34,0x12]
+ psubq 0x12345678,%mm3
+
+// CHECK: psubq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xfb,0xdb]
+ psubq %mm3,%mm3
+
+// CHECK: psubq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0x2d,0x45,0x00,0x00,0x00]
+ psubq 0x45,%xmm5
+
+// CHECK: psubq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0x2d,0xed,0x7e,0x00,0x00]
+ psubq 0x7eed,%xmm5
+
+// CHECK: psubq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0x2d,0xfe,0xca,0xbe,0xba]
+ psubq 0xbabecafe,%xmm5
+
+// CHECK: psubq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0x2d,0x78,0x56,0x34,0x12]
+ psubq 0x12345678,%xmm5
+
+// CHECK: psubq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xfb,0xed]
+ psubq %xmm5,%xmm5
+
+// CHECK: psubsb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe8,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubsb 69, %mm3
+// CHECK: encoding: [0x0f,0xe8,0x1d,0x45,0x00,0x00,0x00]
+ psubsb 0x45,%mm3
+
+// CHECK: psubsb 32493, %mm3
+// CHECK: encoding: [0x0f,0xe8,0x1d,0xed,0x7e,0x00,0x00]
+ psubsb 0x7eed,%mm3
+
+// CHECK: psubsb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe8,0x1d,0xfe,0xca,0xbe,0xba]
+ psubsb 0xbabecafe,%mm3
+
+// CHECK: psubsb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe8,0x1d,0x78,0x56,0x34,0x12]
+ psubsb 0x12345678,%mm3
+
+// CHECK: psubsb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe8,0xdb]
+ psubsb %mm3,%mm3
+
+// CHECK: psubsb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubsb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0x2d,0x45,0x00,0x00,0x00]
+ psubsb 0x45,%xmm5
+
+// CHECK: psubsb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0x2d,0xed,0x7e,0x00,0x00]
+ psubsb 0x7eed,%xmm5
+
+// CHECK: psubsb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0x2d,0xfe,0xca,0xbe,0xba]
+ psubsb 0xbabecafe,%xmm5
+
+// CHECK: psubsb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0x2d,0x78,0x56,0x34,0x12]
+ psubsb 0x12345678,%xmm5
+
+// CHECK: psubsb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe8,0xed]
+ psubsb %xmm5,%xmm5
+
+// CHECK: psubsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe9,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubsw 69, %mm3
+// CHECK: encoding: [0x0f,0xe9,0x1d,0x45,0x00,0x00,0x00]
+ psubsw 0x45,%mm3
+
+// CHECK: psubsw 32493, %mm3
+// CHECK: encoding: [0x0f,0xe9,0x1d,0xed,0x7e,0x00,0x00]
+ psubsw 0x7eed,%mm3
+
+// CHECK: psubsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe9,0x1d,0xfe,0xca,0xbe,0xba]
+ psubsw 0xbabecafe,%mm3
+
+// CHECK: psubsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe9,0x1d,0x78,0x56,0x34,0x12]
+ psubsw 0x12345678,%mm3
+
+// CHECK: psubsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe9,0xdb]
+ psubsw %mm3,%mm3
+
+// CHECK: psubsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0x2d,0x45,0x00,0x00,0x00]
+ psubsw 0x45,%xmm5
+
+// CHECK: psubsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0x2d,0xed,0x7e,0x00,0x00]
+ psubsw 0x7eed,%xmm5
+
+// CHECK: psubsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0x2d,0xfe,0xca,0xbe,0xba]
+ psubsw 0xbabecafe,%xmm5
+
+// CHECK: psubsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0x2d,0x78,0x56,0x34,0x12]
+ psubsw 0x12345678,%xmm5
+
+// CHECK: psubsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe9,0xed]
+ psubsw %xmm5,%xmm5
+
+// CHECK: psubusb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd8,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubusb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubusb 69, %mm3
+// CHECK: encoding: [0x0f,0xd8,0x1d,0x45,0x00,0x00,0x00]
+ psubusb 0x45,%mm3
+
+// CHECK: psubusb 32493, %mm3
+// CHECK: encoding: [0x0f,0xd8,0x1d,0xed,0x7e,0x00,0x00]
+ psubusb 0x7eed,%mm3
+
+// CHECK: psubusb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd8,0x1d,0xfe,0xca,0xbe,0xba]
+ psubusb 0xbabecafe,%mm3
+
+// CHECK: psubusb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd8,0x1d,0x78,0x56,0x34,0x12]
+ psubusb 0x12345678,%mm3
+
+// CHECK: psubusb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd8,0xdb]
+ psubusb %mm3,%mm3
+
+// CHECK: psubusb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubusb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubusb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0x2d,0x45,0x00,0x00,0x00]
+ psubusb 0x45,%xmm5
+
+// CHECK: psubusb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0x2d,0xed,0x7e,0x00,0x00]
+ psubusb 0x7eed,%xmm5
+
+// CHECK: psubusb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0x2d,0xfe,0xca,0xbe,0xba]
+ psubusb 0xbabecafe,%xmm5
+
+// CHECK: psubusb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0x2d,0x78,0x56,0x34,0x12]
+ psubusb 0x12345678,%xmm5
+
+// CHECK: psubusb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd8,0xed]
+ psubusb %xmm5,%xmm5
+
+// CHECK: psubusw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xd9,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psubusw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psubusw 69, %mm3
+// CHECK: encoding: [0x0f,0xd9,0x1d,0x45,0x00,0x00,0x00]
+ psubusw 0x45,%mm3
+
+// CHECK: psubusw 32493, %mm3
+// CHECK: encoding: [0x0f,0xd9,0x1d,0xed,0x7e,0x00,0x00]
+ psubusw 0x7eed,%mm3
+
+// CHECK: psubusw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xd9,0x1d,0xfe,0xca,0xbe,0xba]
+ psubusw 0xbabecafe,%mm3
+
+// CHECK: psubusw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xd9,0x1d,0x78,0x56,0x34,0x12]
+ psubusw 0x12345678,%mm3
+
+// CHECK: psubusw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xd9,0xdb]
+ psubusw %mm3,%mm3
+
+// CHECK: psubusw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psubusw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psubusw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0x2d,0x45,0x00,0x00,0x00]
+ psubusw 0x45,%xmm5
+
+// CHECK: psubusw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0x2d,0xed,0x7e,0x00,0x00]
+ psubusw 0x7eed,%xmm5
+
+// CHECK: psubusw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0x2d,0xfe,0xca,0xbe,0xba]
+ psubusw 0xbabecafe,%xmm5
+
+// CHECK: psubusw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0x2d,0x78,0x56,0x34,0x12]
+ psubusw 0x12345678,%xmm5
+
+// CHECK: psubusw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd9,0xed]
+ psubusw %xmm5,%xmm5
+
+// CHECK: punpckhbw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x68,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhbw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckhbw 69, %mm3
+// CHECK: encoding: [0x0f,0x68,0x1d,0x45,0x00,0x00,0x00]
+ punpckhbw 0x45,%mm3
+
+// CHECK: punpckhbw 32493, %mm3
+// CHECK: encoding: [0x0f,0x68,0x1d,0xed,0x7e,0x00,0x00]
+ punpckhbw 0x7eed,%mm3
+
+// CHECK: punpckhbw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x68,0x1d,0xfe,0xca,0xbe,0xba]
+ punpckhbw 0xbabecafe,%mm3
+
+// CHECK: punpckhbw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x68,0x1d,0x78,0x56,0x34,0x12]
+ punpckhbw 0x12345678,%mm3
+
+// CHECK: punpckhbw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x68,0xdb]
+ punpckhbw %mm3,%mm3
+
+// CHECK: punpckhbw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhbw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0x2d,0x45,0x00,0x00,0x00]
+ punpckhbw 0x45,%xmm5
+
+// CHECK: punpckhbw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0x2d,0xed,0x7e,0x00,0x00]
+ punpckhbw 0x7eed,%xmm5
+
+// CHECK: punpckhbw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0x2d,0xfe,0xca,0xbe,0xba]
+ punpckhbw 0xbabecafe,%xmm5
+
+// CHECK: punpckhbw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0x2d,0x78,0x56,0x34,0x12]
+ punpckhbw 0x12345678,%xmm5
+
+// CHECK: punpckhbw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x68,0xed]
+ punpckhbw %xmm5,%xmm5
+
+// CHECK: punpckhwd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x69,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhwd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckhwd 69, %mm3
+// CHECK: encoding: [0x0f,0x69,0x1d,0x45,0x00,0x00,0x00]
+ punpckhwd 0x45,%mm3
+
+// CHECK: punpckhwd 32493, %mm3
+// CHECK: encoding: [0x0f,0x69,0x1d,0xed,0x7e,0x00,0x00]
+ punpckhwd 0x7eed,%mm3
+
+// CHECK: punpckhwd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x69,0x1d,0xfe,0xca,0xbe,0xba]
+ punpckhwd 0xbabecafe,%mm3
+
+// CHECK: punpckhwd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x69,0x1d,0x78,0x56,0x34,0x12]
+ punpckhwd 0x12345678,%mm3
+
+// CHECK: punpckhwd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x69,0xdb]
+ punpckhwd %mm3,%mm3
+
+// CHECK: punpckhwd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhwd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0x2d,0x45,0x00,0x00,0x00]
+ punpckhwd 0x45,%xmm5
+
+// CHECK: punpckhwd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0x2d,0xed,0x7e,0x00,0x00]
+ punpckhwd 0x7eed,%xmm5
+
+// CHECK: punpckhwd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0x2d,0xfe,0xca,0xbe,0xba]
+ punpckhwd 0xbabecafe,%xmm5
+
+// CHECK: punpckhwd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0x2d,0x78,0x56,0x34,0x12]
+ punpckhwd 0x12345678,%xmm5
+
+// CHECK: punpckhwd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x69,0xed]
+ punpckhwd %xmm5,%xmm5
+
+// CHECK: punpckhdq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x6a,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhdq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckhdq 69, %mm3
+// CHECK: encoding: [0x0f,0x6a,0x1d,0x45,0x00,0x00,0x00]
+ punpckhdq 0x45,%mm3
+
+// CHECK: punpckhdq 32493, %mm3
+// CHECK: encoding: [0x0f,0x6a,0x1d,0xed,0x7e,0x00,0x00]
+ punpckhdq 0x7eed,%mm3
+
+// CHECK: punpckhdq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x6a,0x1d,0xfe,0xca,0xbe,0xba]
+ punpckhdq 0xbabecafe,%mm3
+
+// CHECK: punpckhdq 305419896, %mm3
+// CHECK: encoding: [0x0f,0x6a,0x1d,0x78,0x56,0x34,0x12]
+ punpckhdq 0x12345678,%mm3
+
+// CHECK: punpckhdq %mm3, %mm3
+// CHECK: encoding: [0x0f,0x6a,0xdb]
+ punpckhdq %mm3,%mm3
+
+// CHECK: punpckhdq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhdq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0x2d,0x45,0x00,0x00,0x00]
+ punpckhdq 0x45,%xmm5
+
+// CHECK: punpckhdq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0x2d,0xed,0x7e,0x00,0x00]
+ punpckhdq 0x7eed,%xmm5
+
+// CHECK: punpckhdq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0x2d,0xfe,0xca,0xbe,0xba]
+ punpckhdq 0xbabecafe,%xmm5
+
+// CHECK: punpckhdq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0x2d,0x78,0x56,0x34,0x12]
+ punpckhdq 0x12345678,%xmm5
+
+// CHECK: punpckhdq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6a,0xed]
+ punpckhdq %xmm5,%xmm5
+
+// CHECK: punpcklbw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x60,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpcklbw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpcklbw 69, %mm3
+// CHECK: encoding: [0x0f,0x60,0x1d,0x45,0x00,0x00,0x00]
+ punpcklbw 0x45,%mm3
+
+// CHECK: punpcklbw 32493, %mm3
+// CHECK: encoding: [0x0f,0x60,0x1d,0xed,0x7e,0x00,0x00]
+ punpcklbw 0x7eed,%mm3
+
+// CHECK: punpcklbw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x60,0x1d,0xfe,0xca,0xbe,0xba]
+ punpcklbw 0xbabecafe,%mm3
+
+// CHECK: punpcklbw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x60,0x1d,0x78,0x56,0x34,0x12]
+ punpcklbw 0x12345678,%mm3
+
+// CHECK: punpcklbw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x60,0xdb]
+ punpcklbw %mm3,%mm3
+
+// CHECK: punpcklbw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpcklbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpcklbw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0x2d,0x45,0x00,0x00,0x00]
+ punpcklbw 0x45,%xmm5
+
+// CHECK: punpcklbw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0x2d,0xed,0x7e,0x00,0x00]
+ punpcklbw 0x7eed,%xmm5
+
+// CHECK: punpcklbw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0x2d,0xfe,0xca,0xbe,0xba]
+ punpcklbw 0xbabecafe,%xmm5
+
+// CHECK: punpcklbw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0x2d,0x78,0x56,0x34,0x12]
+ punpcklbw 0x12345678,%xmm5
+
+// CHECK: punpcklbw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x60,0xed]
+ punpcklbw %xmm5,%xmm5
+
+// CHECK: punpcklwd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x61,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpcklwd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpcklwd 69, %mm3
+// CHECK: encoding: [0x0f,0x61,0x1d,0x45,0x00,0x00,0x00]
+ punpcklwd 0x45,%mm3
+
+// CHECK: punpcklwd 32493, %mm3
+// CHECK: encoding: [0x0f,0x61,0x1d,0xed,0x7e,0x00,0x00]
+ punpcklwd 0x7eed,%mm3
+
+// CHECK: punpcklwd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x61,0x1d,0xfe,0xca,0xbe,0xba]
+ punpcklwd 0xbabecafe,%mm3
+
+// CHECK: punpcklwd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x61,0x1d,0x78,0x56,0x34,0x12]
+ punpcklwd 0x12345678,%mm3
+
+// CHECK: punpcklwd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x61,0xdb]
+ punpcklwd %mm3,%mm3
+
+// CHECK: punpcklwd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpcklwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpcklwd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0x2d,0x45,0x00,0x00,0x00]
+ punpcklwd 0x45,%xmm5
+
+// CHECK: punpcklwd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0x2d,0xed,0x7e,0x00,0x00]
+ punpcklwd 0x7eed,%xmm5
+
+// CHECK: punpcklwd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0x2d,0xfe,0xca,0xbe,0xba]
+ punpcklwd 0xbabecafe,%xmm5
+
+// CHECK: punpcklwd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0x2d,0x78,0x56,0x34,0x12]
+ punpcklwd 0x12345678,%xmm5
+
+// CHECK: punpcklwd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x61,0xed]
+ punpcklwd %xmm5,%xmm5
+
+// CHECK: punpckldq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x62,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ punpckldq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: punpckldq 69, %mm3
+// CHECK: encoding: [0x0f,0x62,0x1d,0x45,0x00,0x00,0x00]
+ punpckldq 0x45,%mm3
+
+// CHECK: punpckldq 32493, %mm3
+// CHECK: encoding: [0x0f,0x62,0x1d,0xed,0x7e,0x00,0x00]
+ punpckldq 0x7eed,%mm3
+
+// CHECK: punpckldq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x62,0x1d,0xfe,0xca,0xbe,0xba]
+ punpckldq 0xbabecafe,%mm3
+
+// CHECK: punpckldq 305419896, %mm3
+// CHECK: encoding: [0x0f,0x62,0x1d,0x78,0x56,0x34,0x12]
+ punpckldq 0x12345678,%mm3
+
+// CHECK: punpckldq %mm3, %mm3
+// CHECK: encoding: [0x0f,0x62,0xdb]
+ punpckldq %mm3,%mm3
+
+// CHECK: punpckldq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpckldq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckldq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0x2d,0x45,0x00,0x00,0x00]
+ punpckldq 0x45,%xmm5
+
+// CHECK: punpckldq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0x2d,0xed,0x7e,0x00,0x00]
+ punpckldq 0x7eed,%xmm5
+
+// CHECK: punpckldq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0x2d,0xfe,0xca,0xbe,0xba]
+ punpckldq 0xbabecafe,%xmm5
+
+// CHECK: punpckldq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0x2d,0x78,0x56,0x34,0x12]
+ punpckldq 0x12345678,%xmm5
+
+// CHECK: punpckldq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x62,0xed]
+ punpckldq %xmm5,%xmm5
+
+// CHECK: pxor 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xef,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pxor 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pxor 69, %mm3
+// CHECK: encoding: [0x0f,0xef,0x1d,0x45,0x00,0x00,0x00]
+ pxor 0x45,%mm3
+
+// CHECK: pxor 32493, %mm3
+// CHECK: encoding: [0x0f,0xef,0x1d,0xed,0x7e,0x00,0x00]
+ pxor 0x7eed,%mm3
+
+// CHECK: pxor 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xef,0x1d,0xfe,0xca,0xbe,0xba]
+ pxor 0xbabecafe,%mm3
+
+// CHECK: pxor 305419896, %mm3
+// CHECK: encoding: [0x0f,0xef,0x1d,0x78,0x56,0x34,0x12]
+ pxor 0x12345678,%mm3
+
+// CHECK: pxor %mm3, %mm3
+// CHECK: encoding: [0x0f,0xef,0xdb]
+ pxor %mm3,%mm3
+
+// CHECK: pxor 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pxor 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pxor 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0x2d,0x45,0x00,0x00,0x00]
+ pxor 0x45,%xmm5
+
+// CHECK: pxor 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0x2d,0xed,0x7e,0x00,0x00]
+ pxor 0x7eed,%xmm5
+
+// CHECK: pxor 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0x2d,0xfe,0xca,0xbe,0xba]
+ pxor 0xbabecafe,%xmm5
+
+// CHECK: pxor 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0x2d,0x78,0x56,0x34,0x12]
+ pxor 0x12345678,%xmm5
+
+// CHECK: pxor %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xef,0xed]
+ pxor %xmm5,%xmm5
+
+// CHECK: addps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x58,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addps 69, %xmm5
+// CHECK: encoding: [0x0f,0x58,0x2d,0x45,0x00,0x00,0x00]
+ addps 0x45,%xmm5
+
+// CHECK: addps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x58,0x2d,0xed,0x7e,0x00,0x00]
+ addps 0x7eed,%xmm5
+
+// CHECK: addps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x58,0x2d,0xfe,0xca,0xbe,0xba]
+ addps 0xbabecafe,%xmm5
+
+// CHECK: addps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x58,0x2d,0x78,0x56,0x34,0x12]
+ addps 0x12345678,%xmm5
+
+// CHECK: addps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x58,0xed]
+ addps %xmm5,%xmm5
+
+// CHECK: addss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0x2d,0x45,0x00,0x00,0x00]
+ addss 0x45,%xmm5
+
+// CHECK: addss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0x2d,0xed,0x7e,0x00,0x00]
+ addss 0x7eed,%xmm5
+
+// CHECK: addss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0x2d,0xfe,0xca,0xbe,0xba]
+ addss 0xbabecafe,%xmm5
+
+// CHECK: addss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0x2d,0x78,0x56,0x34,0x12]
+ addss 0x12345678,%xmm5
+
+// CHECK: addss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x58,0xed]
+ addss %xmm5,%xmm5
+
+// CHECK: andnps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x55,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ andnps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andnps 69, %xmm5
+// CHECK: encoding: [0x0f,0x55,0x2d,0x45,0x00,0x00,0x00]
+ andnps 0x45,%xmm5
+
+// CHECK: andnps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x55,0x2d,0xed,0x7e,0x00,0x00]
+ andnps 0x7eed,%xmm5
+
+// CHECK: andnps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x55,0x2d,0xfe,0xca,0xbe,0xba]
+ andnps 0xbabecafe,%xmm5
+
+// CHECK: andnps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x55,0x2d,0x78,0x56,0x34,0x12]
+ andnps 0x12345678,%xmm5
+
+// CHECK: andnps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x55,0xed]
+ andnps %xmm5,%xmm5
+
+// CHECK: andps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x54,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ andps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andps 69, %xmm5
+// CHECK: encoding: [0x0f,0x54,0x2d,0x45,0x00,0x00,0x00]
+ andps 0x45,%xmm5
+
+// CHECK: andps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x54,0x2d,0xed,0x7e,0x00,0x00]
+ andps 0x7eed,%xmm5
+
+// CHECK: andps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x54,0x2d,0xfe,0xca,0xbe,0xba]
+ andps 0xbabecafe,%xmm5
+
+// CHECK: andps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x54,0x2d,0x78,0x56,0x34,0x12]
+ andps 0x12345678,%xmm5
+
+// CHECK: andps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x54,0xed]
+ andps %xmm5,%xmm5
+
+// CHECK: comiss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x2f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ comiss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: comiss 69, %xmm5
+// CHECK: encoding: [0x0f,0x2f,0x2d,0x45,0x00,0x00,0x00]
+ comiss 0x45,%xmm5
+
+// CHECK: comiss 32493, %xmm5
+// CHECK: encoding: [0x0f,0x2f,0x2d,0xed,0x7e,0x00,0x00]
+ comiss 0x7eed,%xmm5
+
+// CHECK: comiss 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x2f,0x2d,0xfe,0xca,0xbe,0xba]
+ comiss 0xbabecafe,%xmm5
+
+// CHECK: comiss 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x2f,0x2d,0x78,0x56,0x34,0x12]
+ comiss 0x12345678,%xmm5
+
+// CHECK: comiss %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x2f,0xed]
+ comiss %xmm5,%xmm5
+
+// CHECK: cvtpi2ps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtpi2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpi2ps 69, %xmm5
+// CHECK: encoding: [0x0f,0x2a,0x2d,0x45,0x00,0x00,0x00]
+ cvtpi2ps 0x45,%xmm5
+
+// CHECK: cvtpi2ps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x2a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtpi2ps 0x7eed,%xmm5
+
+// CHECK: cvtpi2ps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x2a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtpi2ps 0xbabecafe,%xmm5
+
+// CHECK: cvtpi2ps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x2a,0x2d,0x78,0x56,0x34,0x12]
+ cvtpi2ps 0x12345678,%xmm5
+
+// CHECK: cvtpi2ps %mm3, %xmm5
+// CHECK: encoding: [0x0f,0x2a,0xeb]
+ cvtpi2ps %mm3,%xmm5
+
+// CHECK: cvtps2pi 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x2d,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ cvtps2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvtps2pi 69, %mm3
+// CHECK: encoding: [0x0f,0x2d,0x1d,0x45,0x00,0x00,0x00]
+ cvtps2pi 0x45,%mm3
+
+// CHECK: cvtps2pi 32493, %mm3
+// CHECK: encoding: [0x0f,0x2d,0x1d,0xed,0x7e,0x00,0x00]
+ cvtps2pi 0x7eed,%mm3
+
+// CHECK: cvtps2pi 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x2d,0x1d,0xfe,0xca,0xbe,0xba]
+ cvtps2pi 0xbabecafe,%mm3
+
+// CHECK: cvtps2pi 305419896, %mm3
+// CHECK: encoding: [0x0f,0x2d,0x1d,0x78,0x56,0x34,0x12]
+ cvtps2pi 0x12345678,%mm3
+
+// CHECK: cvtps2pi %xmm5, %mm3
+// CHECK: encoding: [0x0f,0x2d,0xdd]
+ cvtps2pi %xmm5,%mm3
+
+// CHECK: cvtsi2ss %ecx, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0xe9]
+ cvtsi2ss %ecx,%xmm5
+
+// CHECK: cvtsi2ss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtsi2ss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtsi2ss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0x2d,0x45,0x00,0x00,0x00]
+ cvtsi2ss 0x45,%xmm5
+
+// CHECK: cvtsi2ss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtsi2ss 0x7eed,%xmm5
+
+// CHECK: cvtsi2ss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtsi2ss 0xbabecafe,%xmm5
+
+// CHECK: cvtsi2ss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x2a,0x2d,0x78,0x56,0x34,0x12]
+ cvtsi2ss 0x12345678,%xmm5
+
+// CHECK: cvttps2pi 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x2c,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ cvttps2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvttps2pi 69, %mm3
+// CHECK: encoding: [0x0f,0x2c,0x1d,0x45,0x00,0x00,0x00]
+ cvttps2pi 0x45,%mm3
+
+// CHECK: cvttps2pi 32493, %mm3
+// CHECK: encoding: [0x0f,0x2c,0x1d,0xed,0x7e,0x00,0x00]
+ cvttps2pi 0x7eed,%mm3
+
+// CHECK: cvttps2pi 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x2c,0x1d,0xfe,0xca,0xbe,0xba]
+ cvttps2pi 0xbabecafe,%mm3
+
+// CHECK: cvttps2pi 305419896, %mm3
+// CHECK: encoding: [0x0f,0x2c,0x1d,0x78,0x56,0x34,0x12]
+ cvttps2pi 0x12345678,%mm3
+
+// CHECK: cvttps2pi %xmm5, %mm3
+// CHECK: encoding: [0x0f,0x2c,0xdd]
+ cvttps2pi %xmm5,%mm3
+
+// CHECK: cvttss2si 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ cvttss2si 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: cvttss2si 69, %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0x0d,0x45,0x00,0x00,0x00]
+ cvttss2si 0x45,%ecx
+
+// CHECK: cvttss2si 32493, %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0x0d,0xed,0x7e,0x00,0x00]
+ cvttss2si 0x7eed,%ecx
+
+// CHECK: cvttss2si 3133065982, %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0x0d,0xfe,0xca,0xbe,0xba]
+ cvttss2si 0xbabecafe,%ecx
+
+// CHECK: cvttss2si 305419896, %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0x0d,0x78,0x56,0x34,0x12]
+ cvttss2si 0x12345678,%ecx
+
+// CHECK: cvttss2si %xmm5, %ecx
+// CHECK: encoding: [0xf3,0x0f,0x2c,0xcd]
+ cvttss2si %xmm5,%ecx
+
+// CHECK: divps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ divps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divps 69, %xmm5
+// CHECK: encoding: [0x0f,0x5e,0x2d,0x45,0x00,0x00,0x00]
+ divps 0x45,%xmm5
+
+// CHECK: divps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5e,0x2d,0xed,0x7e,0x00,0x00]
+ divps 0x7eed,%xmm5
+
+// CHECK: divps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5e,0x2d,0xfe,0xca,0xbe,0xba]
+ divps 0xbabecafe,%xmm5
+
+// CHECK: divps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5e,0x2d,0x78,0x56,0x34,0x12]
+ divps 0x12345678,%xmm5
+
+// CHECK: divps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5e,0xed]
+ divps %xmm5,%xmm5
+
+// CHECK: divss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ divss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0x2d,0x45,0x00,0x00,0x00]
+ divss 0x45,%xmm5
+
+// CHECK: divss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0x2d,0xed,0x7e,0x00,0x00]
+ divss 0x7eed,%xmm5
+
+// CHECK: divss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0x2d,0xfe,0xca,0xbe,0xba]
+ divss 0xbabecafe,%xmm5
+
+// CHECK: divss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0x2d,0x78,0x56,0x34,0x12]
+ divss 0x12345678,%xmm5
+
+// CHECK: divss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5e,0xed]
+ divss %xmm5,%xmm5
+
+// CHECK: ldmxcsr 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xae,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ ldmxcsr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: ldmxcsr 32493
+// CHECK: encoding: [0x0f,0xae,0x15,0xed,0x7e,0x00,0x00]
+ ldmxcsr 0x7eed
+
+// CHECK: ldmxcsr 3133065982
+// CHECK: encoding: [0x0f,0xae,0x15,0xfe,0xca,0xbe,0xba]
+ ldmxcsr 0xbabecafe
+
+// CHECK: ldmxcsr 305419896
+// CHECK: encoding: [0x0f,0xae,0x15,0x78,0x56,0x34,0x12]
+ ldmxcsr 0x12345678
+
+// CHECK: maskmovq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf7,0xdb]
+ maskmovq %mm3,%mm3
+
+// CHECK: maxps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ maxps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxps 69, %xmm5
+// CHECK: encoding: [0x0f,0x5f,0x2d,0x45,0x00,0x00,0x00]
+ maxps 0x45,%xmm5
+
+// CHECK: maxps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5f,0x2d,0xed,0x7e,0x00,0x00]
+ maxps 0x7eed,%xmm5
+
+// CHECK: maxps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5f,0x2d,0xfe,0xca,0xbe,0xba]
+ maxps 0xbabecafe,%xmm5
+
+// CHECK: maxps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5f,0x2d,0x78,0x56,0x34,0x12]
+ maxps 0x12345678,%xmm5
+
+// CHECK: maxps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5f,0xed]
+ maxps %xmm5,%xmm5
+
+// CHECK: maxss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ maxss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0x2d,0x45,0x00,0x00,0x00]
+ maxss 0x45,%xmm5
+
+// CHECK: maxss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0x2d,0xed,0x7e,0x00,0x00]
+ maxss 0x7eed,%xmm5
+
+// CHECK: maxss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0x2d,0xfe,0xca,0xbe,0xba]
+ maxss 0xbabecafe,%xmm5
+
+// CHECK: maxss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0x2d,0x78,0x56,0x34,0x12]
+ maxss 0x12345678,%xmm5
+
+// CHECK: maxss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5f,0xed]
+ maxss %xmm5,%xmm5
+
+// CHECK: minps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ minps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minps 69, %xmm5
+// CHECK: encoding: [0x0f,0x5d,0x2d,0x45,0x00,0x00,0x00]
+ minps 0x45,%xmm5
+
+// CHECK: minps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5d,0x2d,0xed,0x7e,0x00,0x00]
+ minps 0x7eed,%xmm5
+
+// CHECK: minps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5d,0x2d,0xfe,0xca,0xbe,0xba]
+ minps 0xbabecafe,%xmm5
+
+// CHECK: minps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5d,0x2d,0x78,0x56,0x34,0x12]
+ minps 0x12345678,%xmm5
+
+// CHECK: minps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5d,0xed]
+ minps %xmm5,%xmm5
+
+// CHECK: minss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ minss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0x2d,0x45,0x00,0x00,0x00]
+ minss 0x45,%xmm5
+
+// CHECK: minss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0x2d,0xed,0x7e,0x00,0x00]
+ minss 0x7eed,%xmm5
+
+// CHECK: minss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0x2d,0xfe,0xca,0xbe,0xba]
+ minss 0xbabecafe,%xmm5
+
+// CHECK: minss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0x2d,0x78,0x56,0x34,0x12]
+ minss 0x12345678,%xmm5
+
+// CHECK: minss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5d,0xed]
+ minss %xmm5,%xmm5
+
+// CHECK: movaps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x28,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movaps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movaps 69, %xmm5
+// CHECK: encoding: [0x0f,0x28,0x2d,0x45,0x00,0x00,0x00]
+ movaps 0x45,%xmm5
+
+// CHECK: movaps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x28,0x2d,0xed,0x7e,0x00,0x00]
+ movaps 0x7eed,%xmm5
+
+// CHECK: movaps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x28,0x2d,0xfe,0xca,0xbe,0xba]
+ movaps 0xbabecafe,%xmm5
+
+// CHECK: movaps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x28,0x2d,0x78,0x56,0x34,0x12]
+ movaps 0x12345678,%xmm5
+
+// CHECK: movaps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x28,0xed]
+ movaps %xmm5,%xmm5
+
+// CHECK: movaps %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x29,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movaps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movaps %xmm5, 69
+// CHECK: encoding: [0x0f,0x29,0x2d,0x45,0x00,0x00,0x00]
+ movaps %xmm5,0x45
+
+// CHECK: movaps %xmm5, 32493
+// CHECK: encoding: [0x0f,0x29,0x2d,0xed,0x7e,0x00,0x00]
+ movaps %xmm5,0x7eed
+
+// CHECK: movaps %xmm5, 3133065982
+// CHECK: encoding: [0x0f,0x29,0x2d,0xfe,0xca,0xbe,0xba]
+ movaps %xmm5,0xbabecafe
+
+// CHECK: movaps %xmm5, 305419896
+// CHECK: encoding: [0x0f,0x29,0x2d,0x78,0x56,0x34,0x12]
+ movaps %xmm5,0x12345678
+
+// CHECK: movaps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x28,0xed]
+ movaps %xmm5,%xmm5
+
+// CHECK: movhlps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x12,0xed]
+ movhlps %xmm5,%xmm5
+
+// CHECK: movhps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x16,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movhps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movhps 69, %xmm5
+// CHECK: encoding: [0x0f,0x16,0x2d,0x45,0x00,0x00,0x00]
+ movhps 0x45,%xmm5
+
+// CHECK: movhps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x16,0x2d,0xed,0x7e,0x00,0x00]
+ movhps 0x7eed,%xmm5
+
+// CHECK: movhps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x16,0x2d,0xfe,0xca,0xbe,0xba]
+ movhps 0xbabecafe,%xmm5
+
+// CHECK: movhps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x16,0x2d,0x78,0x56,0x34,0x12]
+ movhps 0x12345678,%xmm5
+
+// CHECK: movhps %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x17,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movhps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movhps %xmm5, 69
+// CHECK: encoding: [0x0f,0x17,0x2d,0x45,0x00,0x00,0x00]
+ movhps %xmm5,0x45
+
+// CHECK: movhps %xmm5, 32493
+// CHECK: encoding: [0x0f,0x17,0x2d,0xed,0x7e,0x00,0x00]
+ movhps %xmm5,0x7eed
+
+// CHECK: movhps %xmm5, 3133065982
+// CHECK: encoding: [0x0f,0x17,0x2d,0xfe,0xca,0xbe,0xba]
+ movhps %xmm5,0xbabecafe
+
+// CHECK: movhps %xmm5, 305419896
+// CHECK: encoding: [0x0f,0x17,0x2d,0x78,0x56,0x34,0x12]
+ movhps %xmm5,0x12345678
+
+// CHECK: movlhps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x16,0xed]
+ movlhps %xmm5,%xmm5
+
+// CHECK: movlps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x12,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movlps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movlps 69, %xmm5
+// CHECK: encoding: [0x0f,0x12,0x2d,0x45,0x00,0x00,0x00]
+ movlps 0x45,%xmm5
+
+// CHECK: movlps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x12,0x2d,0xed,0x7e,0x00,0x00]
+ movlps 0x7eed,%xmm5
+
+// CHECK: movlps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x12,0x2d,0xfe,0xca,0xbe,0xba]
+ movlps 0xbabecafe,%xmm5
+
+// CHECK: movlps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x12,0x2d,0x78,0x56,0x34,0x12]
+ movlps 0x12345678,%xmm5
+
+// CHECK: movlps %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x13,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movlps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movlps %xmm5, 69
+// CHECK: encoding: [0x0f,0x13,0x2d,0x45,0x00,0x00,0x00]
+ movlps %xmm5,0x45
+
+// CHECK: movlps %xmm5, 32493
+// CHECK: encoding: [0x0f,0x13,0x2d,0xed,0x7e,0x00,0x00]
+ movlps %xmm5,0x7eed
+
+// CHECK: movlps %xmm5, 3133065982
+// CHECK: encoding: [0x0f,0x13,0x2d,0xfe,0xca,0xbe,0xba]
+ movlps %xmm5,0xbabecafe
+
+// CHECK: movlps %xmm5, 305419896
+// CHECK: encoding: [0x0f,0x13,0x2d,0x78,0x56,0x34,0x12]
+ movlps %xmm5,0x12345678
+
+// CHECK: movmskps %xmm5, %ecx
+// CHECK: encoding: [0x0f,0x50,0xcd]
+ movmskps %xmm5,%ecx
+
+// CHECK: movntps %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x2b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movntps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntps %xmm5, 69
+// CHECK: encoding: [0x0f,0x2b,0x2d,0x45,0x00,0x00,0x00]
+ movntps %xmm5,0x45
+
+// CHECK: movntps %xmm5, 32493
+// CHECK: encoding: [0x0f,0x2b,0x2d,0xed,0x7e,0x00,0x00]
+ movntps %xmm5,0x7eed
+
+// CHECK: movntps %xmm5, 3133065982
+// CHECK: encoding: [0x0f,0x2b,0x2d,0xfe,0xca,0xbe,0xba]
+ movntps %xmm5,0xbabecafe
+
+// CHECK: movntps %xmm5, 305419896
+// CHECK: encoding: [0x0f,0x2b,0x2d,0x78,0x56,0x34,0x12]
+ movntps %xmm5,0x12345678
+
+// CHECK: movntq %mm3, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xe7,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ movntq %mm3,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntq %mm3, 69
+// CHECK: encoding: [0x0f,0xe7,0x1d,0x45,0x00,0x00,0x00]
+ movntq %mm3,0x45
+
+// CHECK: movntq %mm3, 32493
+// CHECK: encoding: [0x0f,0xe7,0x1d,0xed,0x7e,0x00,0x00]
+ movntq %mm3,0x7eed
+
+// CHECK: movntq %mm3, 3133065982
+// CHECK: encoding: [0x0f,0xe7,0x1d,0xfe,0xca,0xbe,0xba]
+ movntq %mm3,0xbabecafe
+
+// CHECK: movntq %mm3, 305419896
+// CHECK: encoding: [0x0f,0xe7,0x1d,0x78,0x56,0x34,0x12]
+ movntq %mm3,0x12345678
+
+// CHECK: movntdq %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0xe7,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movntdq %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntdq %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0xe7,0x2d,0x45,0x00,0x00,0x00]
+ movntdq %xmm5,0x45
+
+// CHECK: movntdq %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0xe7,0x2d,0xed,0x7e,0x00,0x00]
+ movntdq %xmm5,0x7eed
+
+// CHECK: movntdq %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0xe7,0x2d,0xfe,0xca,0xbe,0xba]
+ movntdq %xmm5,0xbabecafe
+
+// CHECK: movntdq %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0xe7,0x2d,0x78,0x56,0x34,0x12]
+ movntdq %xmm5,0x12345678
+
+// CHECK: movss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0x2d,0x45,0x00,0x00,0x00]
+ movss 0x45,%xmm5
+
+// CHECK: movss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0x2d,0xed,0x7e,0x00,0x00]
+ movss 0x7eed,%xmm5
+
+// CHECK: movss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0x2d,0xfe,0xca,0xbe,0xba]
+ movss 0xbabecafe,%xmm5
+
+// CHECK: movss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0x2d,0x78,0x56,0x34,0x12]
+ movss 0x12345678,%xmm5
+
+// CHECK: movss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0xed]
+ movss %xmm5,%xmm5
+
+// CHECK: movss %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf3,0x0f,0x11,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movss %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movss %xmm5, 69
+// CHECK: encoding: [0xf3,0x0f,0x11,0x2d,0x45,0x00,0x00,0x00]
+ movss %xmm5,0x45
+
+// CHECK: movss %xmm5, 32493
+// CHECK: encoding: [0xf3,0x0f,0x11,0x2d,0xed,0x7e,0x00,0x00]
+ movss %xmm5,0x7eed
+
+// CHECK: movss %xmm5, 3133065982
+// CHECK: encoding: [0xf3,0x0f,0x11,0x2d,0xfe,0xca,0xbe,0xba]
+ movss %xmm5,0xbabecafe
+
+// CHECK: movss %xmm5, 305419896
+// CHECK: encoding: [0xf3,0x0f,0x11,0x2d,0x78,0x56,0x34,0x12]
+ movss %xmm5,0x12345678
+
+// CHECK: movss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x10,0xed]
+ movss %xmm5,%xmm5
+
+// CHECK: movups 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x10,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movups 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movups 69, %xmm5
+// CHECK: encoding: [0x0f,0x10,0x2d,0x45,0x00,0x00,0x00]
+ movups 0x45,%xmm5
+
+// CHECK: movups 32493, %xmm5
+// CHECK: encoding: [0x0f,0x10,0x2d,0xed,0x7e,0x00,0x00]
+ movups 0x7eed,%xmm5
+
+// CHECK: movups 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x10,0x2d,0xfe,0xca,0xbe,0xba]
+ movups 0xbabecafe,%xmm5
+
+// CHECK: movups 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x10,0x2d,0x78,0x56,0x34,0x12]
+ movups 0x12345678,%xmm5
+
+// CHECK: movups %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x10,0xed]
+ movups %xmm5,%xmm5
+
+// CHECK: movups %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x11,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movups %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movups %xmm5, 69
+// CHECK: encoding: [0x0f,0x11,0x2d,0x45,0x00,0x00,0x00]
+ movups %xmm5,0x45
+
+// CHECK: movups %xmm5, 32493
+// CHECK: encoding: [0x0f,0x11,0x2d,0xed,0x7e,0x00,0x00]
+ movups %xmm5,0x7eed
+
+// CHECK: movups %xmm5, 3133065982
+// CHECK: encoding: [0x0f,0x11,0x2d,0xfe,0xca,0xbe,0xba]
+ movups %xmm5,0xbabecafe
+
+// CHECK: movups %xmm5, 305419896
+// CHECK: encoding: [0x0f,0x11,0x2d,0x78,0x56,0x34,0x12]
+ movups %xmm5,0x12345678
+
+// CHECK: movups %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x10,0xed]
+ movups %xmm5,%xmm5
+
+// CHECK: mulps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x59,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ mulps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulps 69, %xmm5
+// CHECK: encoding: [0x0f,0x59,0x2d,0x45,0x00,0x00,0x00]
+ mulps 0x45,%xmm5
+
+// CHECK: mulps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x59,0x2d,0xed,0x7e,0x00,0x00]
+ mulps 0x7eed,%xmm5
+
+// CHECK: mulps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x59,0x2d,0xfe,0xca,0xbe,0xba]
+ mulps 0xbabecafe,%xmm5
+
+// CHECK: mulps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x59,0x2d,0x78,0x56,0x34,0x12]
+ mulps 0x12345678,%xmm5
+
+// CHECK: mulps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x59,0xed]
+ mulps %xmm5,%xmm5
+
+// CHECK: mulss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ mulss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0x2d,0x45,0x00,0x00,0x00]
+ mulss 0x45,%xmm5
+
+// CHECK: mulss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0x2d,0xed,0x7e,0x00,0x00]
+ mulss 0x7eed,%xmm5
+
+// CHECK: mulss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0x2d,0xfe,0xca,0xbe,0xba]
+ mulss 0xbabecafe,%xmm5
+
+// CHECK: mulss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0x2d,0x78,0x56,0x34,0x12]
+ mulss 0x12345678,%xmm5
+
+// CHECK: mulss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x59,0xed]
+ mulss %xmm5,%xmm5
+
+// CHECK: orps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x56,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ orps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: orps 69, %xmm5
+// CHECK: encoding: [0x0f,0x56,0x2d,0x45,0x00,0x00,0x00]
+ orps 0x45,%xmm5
+
+// CHECK: orps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x56,0x2d,0xed,0x7e,0x00,0x00]
+ orps 0x7eed,%xmm5
+
+// CHECK: orps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x56,0x2d,0xfe,0xca,0xbe,0xba]
+ orps 0xbabecafe,%xmm5
+
+// CHECK: orps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x56,0x2d,0x78,0x56,0x34,0x12]
+ orps 0x12345678,%xmm5
+
+// CHECK: orps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x56,0xed]
+ orps %xmm5,%xmm5
+
+// CHECK: pavgb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe0,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pavgb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pavgb 69, %mm3
+// CHECK: encoding: [0x0f,0xe0,0x1d,0x45,0x00,0x00,0x00]
+ pavgb 0x45,%mm3
+
+// CHECK: pavgb 32493, %mm3
+// CHECK: encoding: [0x0f,0xe0,0x1d,0xed,0x7e,0x00,0x00]
+ pavgb 0x7eed,%mm3
+
+// CHECK: pavgb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe0,0x1d,0xfe,0xca,0xbe,0xba]
+ pavgb 0xbabecafe,%mm3
+
+// CHECK: pavgb 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe0,0x1d,0x78,0x56,0x34,0x12]
+ pavgb 0x12345678,%mm3
+
+// CHECK: pavgb %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe0,0xdb]
+ pavgb %mm3,%mm3
+
+// CHECK: pavgb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pavgb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pavgb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0x2d,0x45,0x00,0x00,0x00]
+ pavgb 0x45,%xmm5
+
+// CHECK: pavgb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0x2d,0xed,0x7e,0x00,0x00]
+ pavgb 0x7eed,%xmm5
+
+// CHECK: pavgb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0x2d,0xfe,0xca,0xbe,0xba]
+ pavgb 0xbabecafe,%xmm5
+
+// CHECK: pavgb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0x2d,0x78,0x56,0x34,0x12]
+ pavgb 0x12345678,%xmm5
+
+// CHECK: pavgb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe0,0xed]
+ pavgb %xmm5,%xmm5
+
+// CHECK: pavgw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe3,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pavgw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pavgw 69, %mm3
+// CHECK: encoding: [0x0f,0xe3,0x1d,0x45,0x00,0x00,0x00]
+ pavgw 0x45,%mm3
+
+// CHECK: pavgw 32493, %mm3
+// CHECK: encoding: [0x0f,0xe3,0x1d,0xed,0x7e,0x00,0x00]
+ pavgw 0x7eed,%mm3
+
+// CHECK: pavgw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe3,0x1d,0xfe,0xca,0xbe,0xba]
+ pavgw 0xbabecafe,%mm3
+
+// CHECK: pavgw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe3,0x1d,0x78,0x56,0x34,0x12]
+ pavgw 0x12345678,%mm3
+
+// CHECK: pavgw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe3,0xdb]
+ pavgw %mm3,%mm3
+
+// CHECK: pavgw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pavgw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pavgw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0x2d,0x45,0x00,0x00,0x00]
+ pavgw 0x45,%xmm5
+
+// CHECK: pavgw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0x2d,0xed,0x7e,0x00,0x00]
+ pavgw 0x7eed,%xmm5
+
+// CHECK: pavgw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0x2d,0xfe,0xca,0xbe,0xba]
+ pavgw 0xbabecafe,%xmm5
+
+// CHECK: pavgw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0x2d,0x78,0x56,0x34,0x12]
+ pavgw 0x12345678,%xmm5
+
+// CHECK: pavgw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe3,0xed]
+ pavgw %xmm5,%xmm5
+
+// CHECK: pmaxsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xee,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaxsw 69, %mm3
+// CHECK: encoding: [0x0f,0xee,0x1d,0x45,0x00,0x00,0x00]
+ pmaxsw 0x45,%mm3
+
+// CHECK: pmaxsw 32493, %mm3
+// CHECK: encoding: [0x0f,0xee,0x1d,0xed,0x7e,0x00,0x00]
+ pmaxsw 0x7eed,%mm3
+
+// CHECK: pmaxsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xee,0x1d,0xfe,0xca,0xbe,0xba]
+ pmaxsw 0xbabecafe,%mm3
+
+// CHECK: pmaxsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xee,0x1d,0x78,0x56,0x34,0x12]
+ pmaxsw 0x12345678,%mm3
+
+// CHECK: pmaxsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xee,0xdb]
+ pmaxsw %mm3,%mm3
+
+// CHECK: pmaxsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0x2d,0x45,0x00,0x00,0x00]
+ pmaxsw 0x45,%xmm5
+
+// CHECK: pmaxsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxsw 0x7eed,%xmm5
+
+// CHECK: pmaxsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxsw 0xbabecafe,%xmm5
+
+// CHECK: pmaxsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0x2d,0x78,0x56,0x34,0x12]
+ pmaxsw 0x12345678,%xmm5
+
+// CHECK: pmaxsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xee,0xed]
+ pmaxsw %xmm5,%xmm5
+
+// CHECK: pmaxub 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xde,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxub 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaxub 69, %mm3
+// CHECK: encoding: [0x0f,0xde,0x1d,0x45,0x00,0x00,0x00]
+ pmaxub 0x45,%mm3
+
+// CHECK: pmaxub 32493, %mm3
+// CHECK: encoding: [0x0f,0xde,0x1d,0xed,0x7e,0x00,0x00]
+ pmaxub 0x7eed,%mm3
+
+// CHECK: pmaxub 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xde,0x1d,0xfe,0xca,0xbe,0xba]
+ pmaxub 0xbabecafe,%mm3
+
+// CHECK: pmaxub 305419896, %mm3
+// CHECK: encoding: [0x0f,0xde,0x1d,0x78,0x56,0x34,0x12]
+ pmaxub 0x12345678,%mm3
+
+// CHECK: pmaxub %mm3, %mm3
+// CHECK: encoding: [0x0f,0xde,0xdb]
+ pmaxub %mm3,%mm3
+
+// CHECK: pmaxub 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxub 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxub 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0x2d,0x45,0x00,0x00,0x00]
+ pmaxub 0x45,%xmm5
+
+// CHECK: pmaxub 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxub 0x7eed,%xmm5
+
+// CHECK: pmaxub 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxub 0xbabecafe,%xmm5
+
+// CHECK: pmaxub 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0x2d,0x78,0x56,0x34,0x12]
+ pmaxub 0x12345678,%xmm5
+
+// CHECK: pmaxub %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xde,0xed]
+ pmaxub %xmm5,%xmm5
+
+// CHECK: pminsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xea,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pminsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pminsw 69, %mm3
+// CHECK: encoding: [0x0f,0xea,0x1d,0x45,0x00,0x00,0x00]
+ pminsw 0x45,%mm3
+
+// CHECK: pminsw 32493, %mm3
+// CHECK: encoding: [0x0f,0xea,0x1d,0xed,0x7e,0x00,0x00]
+ pminsw 0x7eed,%mm3
+
+// CHECK: pminsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xea,0x1d,0xfe,0xca,0xbe,0xba]
+ pminsw 0xbabecafe,%mm3
+
+// CHECK: pminsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xea,0x1d,0x78,0x56,0x34,0x12]
+ pminsw 0x12345678,%mm3
+
+// CHECK: pminsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xea,0xdb]
+ pminsw %mm3,%mm3
+
+// CHECK: pminsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0x2d,0x45,0x00,0x00,0x00]
+ pminsw 0x45,%xmm5
+
+// CHECK: pminsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0x2d,0xed,0x7e,0x00,0x00]
+ pminsw 0x7eed,%xmm5
+
+// CHECK: pminsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0x2d,0xfe,0xca,0xbe,0xba]
+ pminsw 0xbabecafe,%xmm5
+
+// CHECK: pminsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0x2d,0x78,0x56,0x34,0x12]
+ pminsw 0x12345678,%xmm5
+
+// CHECK: pminsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xea,0xed]
+ pminsw %xmm5,%xmm5
+
+// CHECK: pminub 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xda,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pminub 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pminub 69, %mm3
+// CHECK: encoding: [0x0f,0xda,0x1d,0x45,0x00,0x00,0x00]
+ pminub 0x45,%mm3
+
+// CHECK: pminub 32493, %mm3
+// CHECK: encoding: [0x0f,0xda,0x1d,0xed,0x7e,0x00,0x00]
+ pminub 0x7eed,%mm3
+
+// CHECK: pminub 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xda,0x1d,0xfe,0xca,0xbe,0xba]
+ pminub 0xbabecafe,%mm3
+
+// CHECK: pminub 305419896, %mm3
+// CHECK: encoding: [0x0f,0xda,0x1d,0x78,0x56,0x34,0x12]
+ pminub 0x12345678,%mm3
+
+// CHECK: pminub %mm3, %mm3
+// CHECK: encoding: [0x0f,0xda,0xdb]
+ pminub %mm3,%mm3
+
+// CHECK: pminub 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminub 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminub 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0x2d,0x45,0x00,0x00,0x00]
+ pminub 0x45,%xmm5
+
+// CHECK: pminub 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0x2d,0xed,0x7e,0x00,0x00]
+ pminub 0x7eed,%xmm5
+
+// CHECK: pminub 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0x2d,0xfe,0xca,0xbe,0xba]
+ pminub 0xbabecafe,%xmm5
+
+// CHECK: pminub 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0x2d,0x78,0x56,0x34,0x12]
+ pminub 0x12345678,%xmm5
+
+// CHECK: pminub %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xda,0xed]
+ pminub %xmm5,%xmm5
+
+// CHECK: pmovmskb %mm3, %ecx
+// CHECK: encoding: [0x0f,0xd7,0xcb]
+ pmovmskb %mm3,%ecx
+
+// CHECK: pmovmskb %xmm5, %ecx
+// CHECK: encoding: [0x66,0x0f,0xd7,0xcd]
+ pmovmskb %xmm5,%ecx
+
+// CHECK: pmulhuw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xe4,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhuw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmulhuw 69, %mm3
+// CHECK: encoding: [0x0f,0xe4,0x1d,0x45,0x00,0x00,0x00]
+ pmulhuw 0x45,%mm3
+
+// CHECK: pmulhuw 32493, %mm3
+// CHECK: encoding: [0x0f,0xe4,0x1d,0xed,0x7e,0x00,0x00]
+ pmulhuw 0x7eed,%mm3
+
+// CHECK: pmulhuw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xe4,0x1d,0xfe,0xca,0xbe,0xba]
+ pmulhuw 0xbabecafe,%mm3
+
+// CHECK: pmulhuw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xe4,0x1d,0x78,0x56,0x34,0x12]
+ pmulhuw 0x12345678,%mm3
+
+// CHECK: pmulhuw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xe4,0xdb]
+ pmulhuw %mm3,%mm3
+
+// CHECK: pmulhuw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulhuw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0x2d,0x45,0x00,0x00,0x00]
+ pmulhuw 0x45,%xmm5
+
+// CHECK: pmulhuw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0x2d,0xed,0x7e,0x00,0x00]
+ pmulhuw 0x7eed,%xmm5
+
+// CHECK: pmulhuw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0x2d,0xfe,0xca,0xbe,0xba]
+ pmulhuw 0xbabecafe,%xmm5
+
+// CHECK: pmulhuw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0x2d,0x78,0x56,0x34,0x12]
+ pmulhuw 0x12345678,%xmm5
+
+// CHECK: pmulhuw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xe4,0xed]
+ pmulhuw %xmm5,%xmm5
+
+// CHECK: prefetchnta 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x18,0x84,0xcb,0xef,0xbe,0xad,0xde]
+ prefetchnta 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetchnta 32493
+// CHECK: encoding: [0x0f,0x18,0x05,0xed,0x7e,0x00,0x00]
+ prefetchnta 0x7eed
+
+// CHECK: prefetchnta 3133065982
+// CHECK: encoding: [0x0f,0x18,0x05,0xfe,0xca,0xbe,0xba]
+ prefetchnta 0xbabecafe
+
+// CHECK: prefetchnta 305419896
+// CHECK: encoding: [0x0f,0x18,0x05,0x78,0x56,0x34,0x12]
+ prefetchnta 0x12345678
+
+// CHECK: prefetcht0 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x18,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ prefetcht0 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht0 32493
+// CHECK: encoding: [0x0f,0x18,0x0d,0xed,0x7e,0x00,0x00]
+ prefetcht0 0x7eed
+
+// CHECK: prefetcht0 3133065982
+// CHECK: encoding: [0x0f,0x18,0x0d,0xfe,0xca,0xbe,0xba]
+ prefetcht0 0xbabecafe
+
+// CHECK: prefetcht0 305419896
+// CHECK: encoding: [0x0f,0x18,0x0d,0x78,0x56,0x34,0x12]
+ prefetcht0 0x12345678
+
+// CHECK: prefetcht1 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x18,0x94,0xcb,0xef,0xbe,0xad,0xde]
+ prefetcht1 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht1 32493
+// CHECK: encoding: [0x0f,0x18,0x15,0xed,0x7e,0x00,0x00]
+ prefetcht1 0x7eed
+
+// CHECK: prefetcht1 3133065982
+// CHECK: encoding: [0x0f,0x18,0x15,0xfe,0xca,0xbe,0xba]
+ prefetcht1 0xbabecafe
+
+// CHECK: prefetcht1 305419896
+// CHECK: encoding: [0x0f,0x18,0x15,0x78,0x56,0x34,0x12]
+ prefetcht1 0x12345678
+
+// CHECK: prefetcht2 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0x18,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ prefetcht2 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: prefetcht2 32493
+// CHECK: encoding: [0x0f,0x18,0x1d,0xed,0x7e,0x00,0x00]
+ prefetcht2 0x7eed
+
+// CHECK: prefetcht2 3133065982
+// CHECK: encoding: [0x0f,0x18,0x1d,0xfe,0xca,0xbe,0xba]
+ prefetcht2 0xbabecafe
+
+// CHECK: prefetcht2 305419896
+// CHECK: encoding: [0x0f,0x18,0x1d,0x78,0x56,0x34,0x12]
+ prefetcht2 0x12345678
+
+// CHECK: psadbw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf6,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psadbw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psadbw 69, %mm3
+// CHECK: encoding: [0x0f,0xf6,0x1d,0x45,0x00,0x00,0x00]
+ psadbw 0x45,%mm3
+
+// CHECK: psadbw 32493, %mm3
+// CHECK: encoding: [0x0f,0xf6,0x1d,0xed,0x7e,0x00,0x00]
+ psadbw 0x7eed,%mm3
+
+// CHECK: psadbw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf6,0x1d,0xfe,0xca,0xbe,0xba]
+ psadbw 0xbabecafe,%mm3
+
+// CHECK: psadbw 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf6,0x1d,0x78,0x56,0x34,0x12]
+ psadbw 0x12345678,%mm3
+
+// CHECK: psadbw %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf6,0xdb]
+ psadbw %mm3,%mm3
+
+// CHECK: psadbw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psadbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psadbw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0x2d,0x45,0x00,0x00,0x00]
+ psadbw 0x45,%xmm5
+
+// CHECK: psadbw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0x2d,0xed,0x7e,0x00,0x00]
+ psadbw 0x7eed,%xmm5
+
+// CHECK: psadbw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0x2d,0xfe,0xca,0xbe,0xba]
+ psadbw 0xbabecafe,%xmm5
+
+// CHECK: psadbw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0x2d,0x78,0x56,0x34,0x12]
+ psadbw 0x12345678,%xmm5
+
+// CHECK: psadbw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf6,0xed]
+ psadbw %xmm5,%xmm5
+
+// CHECK: rcpps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x53,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ rcpps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rcpps 69, %xmm5
+// CHECK: encoding: [0x0f,0x53,0x2d,0x45,0x00,0x00,0x00]
+ rcpps 0x45,%xmm5
+
+// CHECK: rcpps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x53,0x2d,0xed,0x7e,0x00,0x00]
+ rcpps 0x7eed,%xmm5
+
+// CHECK: rcpps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x53,0x2d,0xfe,0xca,0xbe,0xba]
+ rcpps 0xbabecafe,%xmm5
+
+// CHECK: rcpps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x53,0x2d,0x78,0x56,0x34,0x12]
+ rcpps 0x12345678,%xmm5
+
+// CHECK: rcpps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x53,0xed]
+ rcpps %xmm5,%xmm5
+
+// CHECK: rcpss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ rcpss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rcpss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0x2d,0x45,0x00,0x00,0x00]
+ rcpss 0x45,%xmm5
+
+// CHECK: rcpss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0x2d,0xed,0x7e,0x00,0x00]
+ rcpss 0x7eed,%xmm5
+
+// CHECK: rcpss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0x2d,0xfe,0xca,0xbe,0xba]
+ rcpss 0xbabecafe,%xmm5
+
+// CHECK: rcpss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0x2d,0x78,0x56,0x34,0x12]
+ rcpss 0x12345678,%xmm5
+
+// CHECK: rcpss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x53,0xed]
+ rcpss %xmm5,%xmm5
+
+// CHECK: rsqrtps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x52,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ rsqrtps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rsqrtps 69, %xmm5
+// CHECK: encoding: [0x0f,0x52,0x2d,0x45,0x00,0x00,0x00]
+ rsqrtps 0x45,%xmm5
+
+// CHECK: rsqrtps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x52,0x2d,0xed,0x7e,0x00,0x00]
+ rsqrtps 0x7eed,%xmm5
+
+// CHECK: rsqrtps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x52,0x2d,0xfe,0xca,0xbe,0xba]
+ rsqrtps 0xbabecafe,%xmm5
+
+// CHECK: rsqrtps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x52,0x2d,0x78,0x56,0x34,0x12]
+ rsqrtps 0x12345678,%xmm5
+
+// CHECK: rsqrtps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x52,0xed]
+ rsqrtps %xmm5,%xmm5
+
+// CHECK: rsqrtss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ rsqrtss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: rsqrtss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0x2d,0x45,0x00,0x00,0x00]
+ rsqrtss 0x45,%xmm5
+
+// CHECK: rsqrtss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0x2d,0xed,0x7e,0x00,0x00]
+ rsqrtss 0x7eed,%xmm5
+
+// CHECK: rsqrtss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0x2d,0xfe,0xca,0xbe,0xba]
+ rsqrtss 0xbabecafe,%xmm5
+
+// CHECK: rsqrtss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0x2d,0x78,0x56,0x34,0x12]
+ rsqrtss 0x12345678,%xmm5
+
+// CHECK: rsqrtss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x52,0xed]
+ rsqrtss %xmm5,%xmm5
+
+// CHECK: sqrtps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x51,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ sqrtps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtps 69, %xmm5
+// CHECK: encoding: [0x0f,0x51,0x2d,0x45,0x00,0x00,0x00]
+ sqrtps 0x45,%xmm5
+
+// CHECK: sqrtps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x51,0x2d,0xed,0x7e,0x00,0x00]
+ sqrtps 0x7eed,%xmm5
+
+// CHECK: sqrtps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x51,0x2d,0xfe,0xca,0xbe,0xba]
+ sqrtps 0xbabecafe,%xmm5
+
+// CHECK: sqrtps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x51,0x2d,0x78,0x56,0x34,0x12]
+ sqrtps 0x12345678,%xmm5
+
+// CHECK: sqrtps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x51,0xed]
+ sqrtps %xmm5,%xmm5
+
+// CHECK: sqrtss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ sqrtss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0x2d,0x45,0x00,0x00,0x00]
+ sqrtss 0x45,%xmm5
+
+// CHECK: sqrtss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0x2d,0xed,0x7e,0x00,0x00]
+ sqrtss 0x7eed,%xmm5
+
+// CHECK: sqrtss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0x2d,0xfe,0xca,0xbe,0xba]
+ sqrtss 0xbabecafe,%xmm5
+
+// CHECK: sqrtss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0x2d,0x78,0x56,0x34,0x12]
+ sqrtss 0x12345678,%xmm5
+
+// CHECK: sqrtss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x51,0xed]
+ sqrtss %xmm5,%xmm5
+
+// CHECK: stmxcsr 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xae,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ stmxcsr 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: stmxcsr 32493
+// CHECK: encoding: [0x0f,0xae,0x1d,0xed,0x7e,0x00,0x00]
+ stmxcsr 0x7eed
+
+// CHECK: stmxcsr 3133065982
+// CHECK: encoding: [0x0f,0xae,0x1d,0xfe,0xca,0xbe,0xba]
+ stmxcsr 0xbabecafe
+
+// CHECK: stmxcsr 305419896
+// CHECK: encoding: [0x0f,0xae,0x1d,0x78,0x56,0x34,0x12]
+ stmxcsr 0x12345678
+
+// CHECK: subps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ subps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subps 69, %xmm5
+// CHECK: encoding: [0x0f,0x5c,0x2d,0x45,0x00,0x00,0x00]
+ subps 0x45,%xmm5
+
+// CHECK: subps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5c,0x2d,0xed,0x7e,0x00,0x00]
+ subps 0x7eed,%xmm5
+
+// CHECK: subps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5c,0x2d,0xfe,0xca,0xbe,0xba]
+ subps 0xbabecafe,%xmm5
+
+// CHECK: subps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5c,0x2d,0x78,0x56,0x34,0x12]
+ subps 0x12345678,%xmm5
+
+// CHECK: subps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5c,0xed]
+ subps %xmm5,%xmm5
+
+// CHECK: subss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ subss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subss 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0x2d,0x45,0x00,0x00,0x00]
+ subss 0x45,%xmm5
+
+// CHECK: subss 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0x2d,0xed,0x7e,0x00,0x00]
+ subss 0x7eed,%xmm5
+
+// CHECK: subss 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0x2d,0xfe,0xca,0xbe,0xba]
+ subss 0xbabecafe,%xmm5
+
+// CHECK: subss 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0x2d,0x78,0x56,0x34,0x12]
+ subss 0x12345678,%xmm5
+
+// CHECK: subss %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5c,0xed]
+ subss %xmm5,%xmm5
+
+// CHECK: ucomiss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x2e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ ucomiss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ucomiss 69, %xmm5
+// CHECK: encoding: [0x0f,0x2e,0x2d,0x45,0x00,0x00,0x00]
+ ucomiss 0x45,%xmm5
+
+// CHECK: ucomiss 32493, %xmm5
+// CHECK: encoding: [0x0f,0x2e,0x2d,0xed,0x7e,0x00,0x00]
+ ucomiss 0x7eed,%xmm5
+
+// CHECK: ucomiss 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x2e,0x2d,0xfe,0xca,0xbe,0xba]
+ ucomiss 0xbabecafe,%xmm5
+
+// CHECK: ucomiss 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x2e,0x2d,0x78,0x56,0x34,0x12]
+ ucomiss 0x12345678,%xmm5
+
+// CHECK: ucomiss %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x2e,0xed]
+ ucomiss %xmm5,%xmm5
+
+// CHECK: unpckhps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x15,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ unpckhps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpckhps 69, %xmm5
+// CHECK: encoding: [0x0f,0x15,0x2d,0x45,0x00,0x00,0x00]
+ unpckhps 0x45,%xmm5
+
+// CHECK: unpckhps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x15,0x2d,0xed,0x7e,0x00,0x00]
+ unpckhps 0x7eed,%xmm5
+
+// CHECK: unpckhps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x15,0x2d,0xfe,0xca,0xbe,0xba]
+ unpckhps 0xbabecafe,%xmm5
+
+// CHECK: unpckhps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x15,0x2d,0x78,0x56,0x34,0x12]
+ unpckhps 0x12345678,%xmm5
+
+// CHECK: unpckhps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x15,0xed]
+ unpckhps %xmm5,%xmm5
+
+// CHECK: unpcklps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x14,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ unpcklps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpcklps 69, %xmm5
+// CHECK: encoding: [0x0f,0x14,0x2d,0x45,0x00,0x00,0x00]
+ unpcklps 0x45,%xmm5
+
+// CHECK: unpcklps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x14,0x2d,0xed,0x7e,0x00,0x00]
+ unpcklps 0x7eed,%xmm5
+
+// CHECK: unpcklps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x14,0x2d,0xfe,0xca,0xbe,0xba]
+ unpcklps 0xbabecafe,%xmm5
+
+// CHECK: unpcklps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x14,0x2d,0x78,0x56,0x34,0x12]
+ unpcklps 0x12345678,%xmm5
+
+// CHECK: unpcklps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x14,0xed]
+ unpcklps %xmm5,%xmm5
+
+// CHECK: xorps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x57,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ xorps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: xorps 69, %xmm5
+// CHECK: encoding: [0x0f,0x57,0x2d,0x45,0x00,0x00,0x00]
+ xorps 0x45,%xmm5
+
+// CHECK: xorps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x57,0x2d,0xed,0x7e,0x00,0x00]
+ xorps 0x7eed,%xmm5
+
+// CHECK: xorps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x57,0x2d,0xfe,0xca,0xbe,0xba]
+ xorps 0xbabecafe,%xmm5
+
+// CHECK: xorps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x57,0x2d,0x78,0x56,0x34,0x12]
+ xorps 0x12345678,%xmm5
+
+// CHECK: xorps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x57,0xed]
+ xorps %xmm5,%xmm5
+
+// CHECK: addpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0x2d,0x45,0x00,0x00,0x00]
+ addpd 0x45,%xmm5
+
+// CHECK: addpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0x2d,0xed,0x7e,0x00,0x00]
+ addpd 0x7eed,%xmm5
+
+// CHECK: addpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0x2d,0xfe,0xca,0xbe,0xba]
+ addpd 0xbabecafe,%xmm5
+
+// CHECK: addpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0x2d,0x78,0x56,0x34,0x12]
+ addpd 0x12345678,%xmm5
+
+// CHECK: addpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x58,0xed]
+ addpd %xmm5,%xmm5
+
+// CHECK: addsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0x2d,0x45,0x00,0x00,0x00]
+ addsd 0x45,%xmm5
+
+// CHECK: addsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0x2d,0xed,0x7e,0x00,0x00]
+ addsd 0x7eed,%xmm5
+
+// CHECK: addsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0x2d,0xfe,0xca,0xbe,0xba]
+ addsd 0xbabecafe,%xmm5
+
+// CHECK: addsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0x2d,0x78,0x56,0x34,0x12]
+ addsd 0x12345678,%xmm5
+
+// CHECK: addsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x58,0xed]
+ addsd %xmm5,%xmm5
+
+// CHECK: andnpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ andnpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andnpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0x2d,0x45,0x00,0x00,0x00]
+ andnpd 0x45,%xmm5
+
+// CHECK: andnpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0x2d,0xed,0x7e,0x00,0x00]
+ andnpd 0x7eed,%xmm5
+
+// CHECK: andnpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0x2d,0xfe,0xca,0xbe,0xba]
+ andnpd 0xbabecafe,%xmm5
+
+// CHECK: andnpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0x2d,0x78,0x56,0x34,0x12]
+ andnpd 0x12345678,%xmm5
+
+// CHECK: andnpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x55,0xed]
+ andnpd %xmm5,%xmm5
+
+// CHECK: andpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ andpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: andpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0x2d,0x45,0x00,0x00,0x00]
+ andpd 0x45,%xmm5
+
+// CHECK: andpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0x2d,0xed,0x7e,0x00,0x00]
+ andpd 0x7eed,%xmm5
+
+// CHECK: andpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0x2d,0xfe,0xca,0xbe,0xba]
+ andpd 0xbabecafe,%xmm5
+
+// CHECK: andpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0x2d,0x78,0x56,0x34,0x12]
+ andpd 0x12345678,%xmm5
+
+// CHECK: andpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x54,0xed]
+ andpd %xmm5,%xmm5
+
+// CHECK: comisd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ comisd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: comisd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0x2d,0x45,0x00,0x00,0x00]
+ comisd 0x45,%xmm5
+
+// CHECK: comisd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0x2d,0xed,0x7e,0x00,0x00]
+ comisd 0x7eed,%xmm5
+
+// CHECK: comisd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0x2d,0xfe,0xca,0xbe,0xba]
+ comisd 0xbabecafe,%xmm5
+
+// CHECK: comisd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0x2d,0x78,0x56,0x34,0x12]
+ comisd 0x12345678,%xmm5
+
+// CHECK: comisd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2f,0xed]
+ comisd %xmm5,%xmm5
+
+// CHECK: cvtpi2pd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtpi2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpi2pd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0x2d,0x45,0x00,0x00,0x00]
+ cvtpi2pd 0x45,%xmm5
+
+// CHECK: cvtpi2pd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtpi2pd 0x7eed,%xmm5
+
+// CHECK: cvtpi2pd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtpi2pd 0xbabecafe,%xmm5
+
+// CHECK: cvtpi2pd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0x2d,0x78,0x56,0x34,0x12]
+ cvtpi2pd 0x12345678,%xmm5
+
+// CHECK: cvtpi2pd %mm3, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2a,0xeb]
+ cvtpi2pd %mm3,%xmm5
+
+// CHECK: cvtsi2sd %ecx, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0xe9]
+ cvtsi2sd %ecx,%xmm5
+
+// CHECK: cvtsi2sd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtsi2sd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtsi2sd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0x2d,0x45,0x00,0x00,0x00]
+ cvtsi2sd 0x45,%xmm5
+
+// CHECK: cvtsi2sd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtsi2sd 0x7eed,%xmm5
+
+// CHECK: cvtsi2sd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtsi2sd 0xbabecafe,%xmm5
+
+// CHECK: cvtsi2sd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x2a,0x2d,0x78,0x56,0x34,0x12]
+ cvtsi2sd 0x12345678,%xmm5
+
+// CHECK: divpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ divpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0x2d,0x45,0x00,0x00,0x00]
+ divpd 0x45,%xmm5
+
+// CHECK: divpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0x2d,0xed,0x7e,0x00,0x00]
+ divpd 0x7eed,%xmm5
+
+// CHECK: divpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0x2d,0xfe,0xca,0xbe,0xba]
+ divpd 0xbabecafe,%xmm5
+
+// CHECK: divpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0x2d,0x78,0x56,0x34,0x12]
+ divpd 0x12345678,%xmm5
+
+// CHECK: divpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5e,0xed]
+ divpd %xmm5,%xmm5
+
+// CHECK: divsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ divsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: divsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0x2d,0x45,0x00,0x00,0x00]
+ divsd 0x45,%xmm5
+
+// CHECK: divsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0x2d,0xed,0x7e,0x00,0x00]
+ divsd 0x7eed,%xmm5
+
+// CHECK: divsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0x2d,0xfe,0xca,0xbe,0xba]
+ divsd 0xbabecafe,%xmm5
+
+// CHECK: divsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0x2d,0x78,0x56,0x34,0x12]
+ divsd 0x12345678,%xmm5
+
+// CHECK: divsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5e,0xed]
+ divsd %xmm5,%xmm5
+
+// CHECK: maxpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ maxpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0x2d,0x45,0x00,0x00,0x00]
+ maxpd 0x45,%xmm5
+
+// CHECK: maxpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0x2d,0xed,0x7e,0x00,0x00]
+ maxpd 0x7eed,%xmm5
+
+// CHECK: maxpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0x2d,0xfe,0xca,0xbe,0xba]
+ maxpd 0xbabecafe,%xmm5
+
+// CHECK: maxpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0x2d,0x78,0x56,0x34,0x12]
+ maxpd 0x12345678,%xmm5
+
+// CHECK: maxpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5f,0xed]
+ maxpd %xmm5,%xmm5
+
+// CHECK: maxsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ maxsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: maxsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0x2d,0x45,0x00,0x00,0x00]
+ maxsd 0x45,%xmm5
+
+// CHECK: maxsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0x2d,0xed,0x7e,0x00,0x00]
+ maxsd 0x7eed,%xmm5
+
+// CHECK: maxsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0x2d,0xfe,0xca,0xbe,0xba]
+ maxsd 0xbabecafe,%xmm5
+
+// CHECK: maxsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0x2d,0x78,0x56,0x34,0x12]
+ maxsd 0x12345678,%xmm5
+
+// CHECK: maxsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5f,0xed]
+ maxsd %xmm5,%xmm5
+
+// CHECK: minpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ minpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0x2d,0x45,0x00,0x00,0x00]
+ minpd 0x45,%xmm5
+
+// CHECK: minpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0x2d,0xed,0x7e,0x00,0x00]
+ minpd 0x7eed,%xmm5
+
+// CHECK: minpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0x2d,0xfe,0xca,0xbe,0xba]
+ minpd 0xbabecafe,%xmm5
+
+// CHECK: minpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0x2d,0x78,0x56,0x34,0x12]
+ minpd 0x12345678,%xmm5
+
+// CHECK: minpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5d,0xed]
+ minpd %xmm5,%xmm5
+
+// CHECK: minsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ minsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: minsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0x2d,0x45,0x00,0x00,0x00]
+ minsd 0x45,%xmm5
+
+// CHECK: minsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0x2d,0xed,0x7e,0x00,0x00]
+ minsd 0x7eed,%xmm5
+
+// CHECK: minsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0x2d,0xfe,0xca,0xbe,0xba]
+ minsd 0xbabecafe,%xmm5
+
+// CHECK: minsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0x2d,0x78,0x56,0x34,0x12]
+ minsd 0x12345678,%xmm5
+
+// CHECK: minsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5d,0xed]
+ minsd %xmm5,%xmm5
+
+// CHECK: movapd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movapd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movapd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0x2d,0x45,0x00,0x00,0x00]
+ movapd 0x45,%xmm5
+
+// CHECK: movapd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0x2d,0xed,0x7e,0x00,0x00]
+ movapd 0x7eed,%xmm5
+
+// CHECK: movapd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0x2d,0xfe,0xca,0xbe,0xba]
+ movapd 0xbabecafe,%xmm5
+
+// CHECK: movapd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0x2d,0x78,0x56,0x34,0x12]
+ movapd 0x12345678,%xmm5
+
+// CHECK: movapd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0xed]
+ movapd %xmm5,%xmm5
+
+// CHECK: movapd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x29,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movapd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movapd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x29,0x2d,0x45,0x00,0x00,0x00]
+ movapd %xmm5,0x45
+
+// CHECK: movapd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x29,0x2d,0xed,0x7e,0x00,0x00]
+ movapd %xmm5,0x7eed
+
+// CHECK: movapd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x29,0x2d,0xfe,0xca,0xbe,0xba]
+ movapd %xmm5,0xbabecafe
+
+// CHECK: movapd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x29,0x2d,0x78,0x56,0x34,0x12]
+ movapd %xmm5,0x12345678
+
+// CHECK: movapd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x28,0xed]
+ movapd %xmm5,%xmm5
+
+// CHECK: movhpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x16,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movhpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movhpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x16,0x2d,0x45,0x00,0x00,0x00]
+ movhpd 0x45,%xmm5
+
+// CHECK: movhpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x16,0x2d,0xed,0x7e,0x00,0x00]
+ movhpd 0x7eed,%xmm5
+
+// CHECK: movhpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x16,0x2d,0xfe,0xca,0xbe,0xba]
+ movhpd 0xbabecafe,%xmm5
+
+// CHECK: movhpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x16,0x2d,0x78,0x56,0x34,0x12]
+ movhpd 0x12345678,%xmm5
+
+// CHECK: movhpd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x17,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movhpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movhpd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x17,0x2d,0x45,0x00,0x00,0x00]
+ movhpd %xmm5,0x45
+
+// CHECK: movhpd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x17,0x2d,0xed,0x7e,0x00,0x00]
+ movhpd %xmm5,0x7eed
+
+// CHECK: movhpd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x17,0x2d,0xfe,0xca,0xbe,0xba]
+ movhpd %xmm5,0xbabecafe
+
+// CHECK: movhpd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x17,0x2d,0x78,0x56,0x34,0x12]
+ movhpd %xmm5,0x12345678
+
+// CHECK: movlpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x12,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movlpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movlpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x12,0x2d,0x45,0x00,0x00,0x00]
+ movlpd 0x45,%xmm5
+
+// CHECK: movlpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x12,0x2d,0xed,0x7e,0x00,0x00]
+ movlpd 0x7eed,%xmm5
+
+// CHECK: movlpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x12,0x2d,0xfe,0xca,0xbe,0xba]
+ movlpd 0xbabecafe,%xmm5
+
+// CHECK: movlpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x12,0x2d,0x78,0x56,0x34,0x12]
+ movlpd 0x12345678,%xmm5
+
+// CHECK: movlpd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x13,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movlpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movlpd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x13,0x2d,0x45,0x00,0x00,0x00]
+ movlpd %xmm5,0x45
+
+// CHECK: movlpd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x13,0x2d,0xed,0x7e,0x00,0x00]
+ movlpd %xmm5,0x7eed
+
+// CHECK: movlpd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x13,0x2d,0xfe,0xca,0xbe,0xba]
+ movlpd %xmm5,0xbabecafe
+
+// CHECK: movlpd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x13,0x2d,0x78,0x56,0x34,0x12]
+ movlpd %xmm5,0x12345678
+
+// CHECK: movmskpd %xmm5, %ecx
+// CHECK: encoding: [0x66,0x0f,0x50,0xcd]
+ movmskpd %xmm5,%ecx
+
+// CHECK: movntpd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x2b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movntpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movntpd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x2b,0x2d,0x45,0x00,0x00,0x00]
+ movntpd %xmm5,0x45
+
+// CHECK: movntpd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x2b,0x2d,0xed,0x7e,0x00,0x00]
+ movntpd %xmm5,0x7eed
+
+// CHECK: movntpd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x2b,0x2d,0xfe,0xca,0xbe,0xba]
+ movntpd %xmm5,0xbabecafe
+
+// CHECK: movntpd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x2b,0x2d,0x78,0x56,0x34,0x12]
+ movntpd %xmm5,0x12345678
+
+// CHECK: movsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0x2d,0x45,0x00,0x00,0x00]
+ movsd 0x45,%xmm5
+
+// CHECK: movsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0x2d,0xed,0x7e,0x00,0x00]
+ movsd 0x7eed,%xmm5
+
+// CHECK: movsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0x2d,0xfe,0xca,0xbe,0xba]
+ movsd 0xbabecafe,%xmm5
+
+// CHECK: movsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0x2d,0x78,0x56,0x34,0x12]
+ movsd 0x12345678,%xmm5
+
+// CHECK: movsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0xed]
+ movsd %xmm5,%xmm5
+
+// CHECK: movsd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf2,0x0f,0x11,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movsd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movsd %xmm5, 69
+// CHECK: encoding: [0xf2,0x0f,0x11,0x2d,0x45,0x00,0x00,0x00]
+ movsd %xmm5,0x45
+
+// CHECK: movsd %xmm5, 32493
+// CHECK: encoding: [0xf2,0x0f,0x11,0x2d,0xed,0x7e,0x00,0x00]
+ movsd %xmm5,0x7eed
+
+// CHECK: movsd %xmm5, 3133065982
+// CHECK: encoding: [0xf2,0x0f,0x11,0x2d,0xfe,0xca,0xbe,0xba]
+ movsd %xmm5,0xbabecafe
+
+// CHECK: movsd %xmm5, 305419896
+// CHECK: encoding: [0xf2,0x0f,0x11,0x2d,0x78,0x56,0x34,0x12]
+ movsd %xmm5,0x12345678
+
+// CHECK: movsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x10,0xed]
+ movsd %xmm5,%xmm5
+
+// CHECK: movupd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movupd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movupd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0x2d,0x45,0x00,0x00,0x00]
+ movupd 0x45,%xmm5
+
+// CHECK: movupd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0x2d,0xed,0x7e,0x00,0x00]
+ movupd 0x7eed,%xmm5
+
+// CHECK: movupd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0x2d,0xfe,0xca,0xbe,0xba]
+ movupd 0xbabecafe,%xmm5
+
+// CHECK: movupd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0x2d,0x78,0x56,0x34,0x12]
+ movupd 0x12345678,%xmm5
+
+// CHECK: movupd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0xed]
+ movupd %xmm5,%xmm5
+
+// CHECK: movupd %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x11,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movupd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movupd %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x11,0x2d,0x45,0x00,0x00,0x00]
+ movupd %xmm5,0x45
+
+// CHECK: movupd %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x11,0x2d,0xed,0x7e,0x00,0x00]
+ movupd %xmm5,0x7eed
+
+// CHECK: movupd %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x11,0x2d,0xfe,0xca,0xbe,0xba]
+ movupd %xmm5,0xbabecafe
+
+// CHECK: movupd %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x11,0x2d,0x78,0x56,0x34,0x12]
+ movupd %xmm5,0x12345678
+
+// CHECK: movupd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x10,0xed]
+ movupd %xmm5,%xmm5
+
+// CHECK: mulpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ mulpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0x2d,0x45,0x00,0x00,0x00]
+ mulpd 0x45,%xmm5
+
+// CHECK: mulpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0x2d,0xed,0x7e,0x00,0x00]
+ mulpd 0x7eed,%xmm5
+
+// CHECK: mulpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0x2d,0xfe,0xca,0xbe,0xba]
+ mulpd 0xbabecafe,%xmm5
+
+// CHECK: mulpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0x2d,0x78,0x56,0x34,0x12]
+ mulpd 0x12345678,%xmm5
+
+// CHECK: mulpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x59,0xed]
+ mulpd %xmm5,%xmm5
+
+// CHECK: mulsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ mulsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: mulsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0x2d,0x45,0x00,0x00,0x00]
+ mulsd 0x45,%xmm5
+
+// CHECK: mulsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0x2d,0xed,0x7e,0x00,0x00]
+ mulsd 0x7eed,%xmm5
+
+// CHECK: mulsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0x2d,0xfe,0xca,0xbe,0xba]
+ mulsd 0xbabecafe,%xmm5
+
+// CHECK: mulsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0x2d,0x78,0x56,0x34,0x12]
+ mulsd 0x12345678,%xmm5
+
+// CHECK: mulsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x59,0xed]
+ mulsd %xmm5,%xmm5
+
+// CHECK: orpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ orpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: orpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0x2d,0x45,0x00,0x00,0x00]
+ orpd 0x45,%xmm5
+
+// CHECK: orpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0x2d,0xed,0x7e,0x00,0x00]
+ orpd 0x7eed,%xmm5
+
+// CHECK: orpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0x2d,0xfe,0xca,0xbe,0xba]
+ orpd 0xbabecafe,%xmm5
+
+// CHECK: orpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0x2d,0x78,0x56,0x34,0x12]
+ orpd 0x12345678,%xmm5
+
+// CHECK: orpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x56,0xed]
+ orpd %xmm5,%xmm5
+
+// CHECK: sqrtpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ sqrtpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0x2d,0x45,0x00,0x00,0x00]
+ sqrtpd 0x45,%xmm5
+
+// CHECK: sqrtpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0x2d,0xed,0x7e,0x00,0x00]
+ sqrtpd 0x7eed,%xmm5
+
+// CHECK: sqrtpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0x2d,0xfe,0xca,0xbe,0xba]
+ sqrtpd 0xbabecafe,%xmm5
+
+// CHECK: sqrtpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0x2d,0x78,0x56,0x34,0x12]
+ sqrtpd 0x12345678,%xmm5
+
+// CHECK: sqrtpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x51,0xed]
+ sqrtpd %xmm5,%xmm5
+
+// CHECK: sqrtsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ sqrtsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: sqrtsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0x2d,0x45,0x00,0x00,0x00]
+ sqrtsd 0x45,%xmm5
+
+// CHECK: sqrtsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0x2d,0xed,0x7e,0x00,0x00]
+ sqrtsd 0x7eed,%xmm5
+
+// CHECK: sqrtsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0x2d,0xfe,0xca,0xbe,0xba]
+ sqrtsd 0xbabecafe,%xmm5
+
+// CHECK: sqrtsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0x2d,0x78,0x56,0x34,0x12]
+ sqrtsd 0x12345678,%xmm5
+
+// CHECK: sqrtsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x51,0xed]
+ sqrtsd %xmm5,%xmm5
+
+// CHECK: subpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ subpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0x2d,0x45,0x00,0x00,0x00]
+ subpd 0x45,%xmm5
+
+// CHECK: subpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0x2d,0xed,0x7e,0x00,0x00]
+ subpd 0x7eed,%xmm5
+
+// CHECK: subpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0x2d,0xfe,0xca,0xbe,0xba]
+ subpd 0xbabecafe,%xmm5
+
+// CHECK: subpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0x2d,0x78,0x56,0x34,0x12]
+ subpd 0x12345678,%xmm5
+
+// CHECK: subpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5c,0xed]
+ subpd %xmm5,%xmm5
+
+// CHECK: subsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ subsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: subsd 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0x2d,0x45,0x00,0x00,0x00]
+ subsd 0x45,%xmm5
+
+// CHECK: subsd 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0x2d,0xed,0x7e,0x00,0x00]
+ subsd 0x7eed,%xmm5
+
+// CHECK: subsd 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0x2d,0xfe,0xca,0xbe,0xba]
+ subsd 0xbabecafe,%xmm5
+
+// CHECK: subsd 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0x2d,0x78,0x56,0x34,0x12]
+ subsd 0x12345678,%xmm5
+
+// CHECK: subsd %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5c,0xed]
+ subsd %xmm5,%xmm5
+
+// CHECK: ucomisd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ ucomisd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ucomisd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0x2d,0x45,0x00,0x00,0x00]
+ ucomisd 0x45,%xmm5
+
+// CHECK: ucomisd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0x2d,0xed,0x7e,0x00,0x00]
+ ucomisd 0x7eed,%xmm5
+
+// CHECK: ucomisd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0x2d,0xfe,0xca,0xbe,0xba]
+ ucomisd 0xbabecafe,%xmm5
+
+// CHECK: ucomisd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0x2d,0x78,0x56,0x34,0x12]
+ ucomisd 0x12345678,%xmm5
+
+// CHECK: ucomisd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x2e,0xed]
+ ucomisd %xmm5,%xmm5
+
+// CHECK: unpckhpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ unpckhpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpckhpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0x2d,0x45,0x00,0x00,0x00]
+ unpckhpd 0x45,%xmm5
+
+// CHECK: unpckhpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0x2d,0xed,0x7e,0x00,0x00]
+ unpckhpd 0x7eed,%xmm5
+
+// CHECK: unpckhpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0x2d,0xfe,0xca,0xbe,0xba]
+ unpckhpd 0xbabecafe,%xmm5
+
+// CHECK: unpckhpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0x2d,0x78,0x56,0x34,0x12]
+ unpckhpd 0x12345678,%xmm5
+
+// CHECK: unpckhpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x15,0xed]
+ unpckhpd %xmm5,%xmm5
+
+// CHECK: unpcklpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ unpcklpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: unpcklpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0x2d,0x45,0x00,0x00,0x00]
+ unpcklpd 0x45,%xmm5
+
+// CHECK: unpcklpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0x2d,0xed,0x7e,0x00,0x00]
+ unpcklpd 0x7eed,%xmm5
+
+// CHECK: unpcklpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0x2d,0xfe,0xca,0xbe,0xba]
+ unpcklpd 0xbabecafe,%xmm5
+
+// CHECK: unpcklpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0x2d,0x78,0x56,0x34,0x12]
+ unpcklpd 0x12345678,%xmm5
+
+// CHECK: unpcklpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x14,0xed]
+ unpcklpd %xmm5,%xmm5
+
+// CHECK: xorpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ xorpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: xorpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0x2d,0x45,0x00,0x00,0x00]
+ xorpd 0x45,%xmm5
+
+// CHECK: xorpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0x2d,0xed,0x7e,0x00,0x00]
+ xorpd 0x7eed,%xmm5
+
+// CHECK: xorpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0x2d,0xfe,0xca,0xbe,0xba]
+ xorpd 0xbabecafe,%xmm5
+
+// CHECK: xorpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0x2d,0x78,0x56,0x34,0x12]
+ xorpd 0x12345678,%xmm5
+
+// CHECK: xorpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x57,0xed]
+ xorpd %xmm5,%xmm5
+
+// CHECK: cvtdq2pd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtdq2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtdq2pd 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0x2d,0x45,0x00,0x00,0x00]
+ cvtdq2pd 0x45,%xmm5
+
+// CHECK: cvtdq2pd 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0x2d,0xed,0x7e,0x00,0x00]
+ cvtdq2pd 0x7eed,%xmm5
+
+// CHECK: cvtdq2pd 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtdq2pd 0xbabecafe,%xmm5
+
+// CHECK: cvtdq2pd 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0x2d,0x78,0x56,0x34,0x12]
+ cvtdq2pd 0x12345678,%xmm5
+
+// CHECK: cvtdq2pd %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xe6,0xed]
+ cvtdq2pd %xmm5,%xmm5
+
+// CHECK: cvtpd2dq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtpd2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpd2dq 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0x2d,0x45,0x00,0x00,0x00]
+ cvtpd2dq 0x45,%xmm5
+
+// CHECK: cvtpd2dq 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0x2d,0xed,0x7e,0x00,0x00]
+ cvtpd2dq 0x7eed,%xmm5
+
+// CHECK: cvtpd2dq 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtpd2dq 0xbabecafe,%xmm5
+
+// CHECK: cvtpd2dq 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0x2d,0x78,0x56,0x34,0x12]
+ cvtpd2dq 0x12345678,%xmm5
+
+// CHECK: cvtpd2dq %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xe6,0xed]
+ cvtpd2dq %xmm5,%xmm5
+
+// CHECK: cvtdq2ps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtdq2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtdq2ps 69, %xmm5
+// CHECK: encoding: [0x0f,0x5b,0x2d,0x45,0x00,0x00,0x00]
+ cvtdq2ps 0x45,%xmm5
+
+// CHECK: cvtdq2ps 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5b,0x2d,0xed,0x7e,0x00,0x00]
+ cvtdq2ps 0x7eed,%xmm5
+
+// CHECK: cvtdq2ps 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5b,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtdq2ps 0xbabecafe,%xmm5
+
+// CHECK: cvtdq2ps 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5b,0x2d,0x78,0x56,0x34,0x12]
+ cvtdq2ps 0x12345678,%xmm5
+
+// CHECK: cvtdq2ps %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5b,0xed]
+ cvtdq2ps %xmm5,%xmm5
+
+// CHECK: cvtpd2pi 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ cvtpd2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvtpd2pi 69, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0x1d,0x45,0x00,0x00,0x00]
+ cvtpd2pi 0x45,%mm3
+
+// CHECK: cvtpd2pi 32493, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0x1d,0xed,0x7e,0x00,0x00]
+ cvtpd2pi 0x7eed,%mm3
+
+// CHECK: cvtpd2pi 3133065982, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0x1d,0xfe,0xca,0xbe,0xba]
+ cvtpd2pi 0xbabecafe,%mm3
+
+// CHECK: cvtpd2pi 305419896, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0x1d,0x78,0x56,0x34,0x12]
+ cvtpd2pi 0x12345678,%mm3
+
+// CHECK: cvtpd2pi %xmm5, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2d,0xdd]
+ cvtpd2pi %xmm5,%mm3
+
+// CHECK: cvtpd2ps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtpd2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtpd2ps 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0x2d,0x45,0x00,0x00,0x00]
+ cvtpd2ps 0x45,%xmm5
+
+// CHECK: cvtpd2ps 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtpd2ps 0x7eed,%xmm5
+
+// CHECK: cvtpd2ps 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtpd2ps 0xbabecafe,%xmm5
+
+// CHECK: cvtpd2ps 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0x2d,0x78,0x56,0x34,0x12]
+ cvtpd2ps 0x12345678,%xmm5
+
+// CHECK: cvtpd2ps %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5a,0xed]
+ cvtpd2ps %xmm5,%xmm5
+
+// CHECK: cvtps2pd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x0f,0x5a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtps2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtps2pd 69, %xmm5
+// CHECK: encoding: [0x0f,0x5a,0x2d,0x45,0x00,0x00,0x00]
+ cvtps2pd 0x45,%xmm5
+
+// CHECK: cvtps2pd 32493, %xmm5
+// CHECK: encoding: [0x0f,0x5a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtps2pd 0x7eed,%xmm5
+
+// CHECK: cvtps2pd 3133065982, %xmm5
+// CHECK: encoding: [0x0f,0x5a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtps2pd 0xbabecafe,%xmm5
+
+// CHECK: cvtps2pd 305419896, %xmm5
+// CHECK: encoding: [0x0f,0x5a,0x2d,0x78,0x56,0x34,0x12]
+ cvtps2pd 0x12345678,%xmm5
+
+// CHECK: cvtps2pd %xmm5, %xmm5
+// CHECK: encoding: [0x0f,0x5a,0xed]
+ cvtps2pd %xmm5,%xmm5
+
+// CHECK: cvtps2dq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtps2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtps2dq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0x2d,0x45,0x00,0x00,0x00]
+ cvtps2dq 0x45,%xmm5
+
+// CHECK: cvtps2dq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0x2d,0xed,0x7e,0x00,0x00]
+ cvtps2dq 0x7eed,%xmm5
+
+// CHECK: cvtps2dq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtps2dq 0xbabecafe,%xmm5
+
+// CHECK: cvtps2dq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0x2d,0x78,0x56,0x34,0x12]
+ cvtps2dq 0x12345678,%xmm5
+
+// CHECK: cvtps2dq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x5b,0xed]
+ cvtps2dq %xmm5,%xmm5
+
+// CHECK: cvtsd2ss 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtsd2ss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtsd2ss 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0x2d,0x45,0x00,0x00,0x00]
+ cvtsd2ss 0x45,%xmm5
+
+// CHECK: cvtsd2ss 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtsd2ss 0x7eed,%xmm5
+
+// CHECK: cvtsd2ss 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtsd2ss 0xbabecafe,%xmm5
+
+// CHECK: cvtsd2ss 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0x2d,0x78,0x56,0x34,0x12]
+ cvtsd2ss 0x12345678,%xmm5
+
+// CHECK: cvtsd2ss %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x5a,0xed]
+ cvtsd2ss %xmm5,%xmm5
+
+// CHECK: cvtss2sd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvtss2sd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvtss2sd 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0x2d,0x45,0x00,0x00,0x00]
+ cvtss2sd 0x45,%xmm5
+
+// CHECK: cvtss2sd 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0x2d,0xed,0x7e,0x00,0x00]
+ cvtss2sd 0x7eed,%xmm5
+
+// CHECK: cvtss2sd 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0x2d,0xfe,0xca,0xbe,0xba]
+ cvtss2sd 0xbabecafe,%xmm5
+
+// CHECK: cvtss2sd 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0x2d,0x78,0x56,0x34,0x12]
+ cvtss2sd 0x12345678,%xmm5
+
+// CHECK: cvtss2sd %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5a,0xed]
+ cvtss2sd %xmm5,%xmm5
+
+// CHECK: cvttpd2pi 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ cvttpd2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: cvttpd2pi 69, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0x1d,0x45,0x00,0x00,0x00]
+ cvttpd2pi 0x45,%mm3
+
+// CHECK: cvttpd2pi 32493, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0x1d,0xed,0x7e,0x00,0x00]
+ cvttpd2pi 0x7eed,%mm3
+
+// CHECK: cvttpd2pi 3133065982, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0x1d,0xfe,0xca,0xbe,0xba]
+ cvttpd2pi 0xbabecafe,%mm3
+
+// CHECK: cvttpd2pi 305419896, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0x1d,0x78,0x56,0x34,0x12]
+ cvttpd2pi 0x12345678,%mm3
+
+// CHECK: cvttpd2pi %xmm5, %mm3
+// CHECK: encoding: [0x66,0x0f,0x2c,0xdd]
+ cvttpd2pi %xmm5,%mm3
+
+// CHECK: cvttsd2si 3735928559(%ebx,%ecx,8), %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ cvttsd2si 0xdeadbeef(%ebx,%ecx,8),%ecx
+
+// CHECK: cvttsd2si 69, %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0x0d,0x45,0x00,0x00,0x00]
+ cvttsd2si 0x45,%ecx
+
+// CHECK: cvttsd2si 32493, %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0x0d,0xed,0x7e,0x00,0x00]
+ cvttsd2si 0x7eed,%ecx
+
+// CHECK: cvttsd2si 3133065982, %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0x0d,0xfe,0xca,0xbe,0xba]
+ cvttsd2si 0xbabecafe,%ecx
+
+// CHECK: cvttsd2si 305419896, %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0x0d,0x78,0x56,0x34,0x12]
+ cvttsd2si 0x12345678,%ecx
+
+// CHECK: cvttsd2si %xmm5, %ecx
+// CHECK: encoding: [0xf2,0x0f,0x2c,0xcd]
+ cvttsd2si %xmm5,%ecx
+
+// CHECK: cvttps2dq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ cvttps2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: cvttps2dq 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0x2d,0x45,0x00,0x00,0x00]
+ cvttps2dq 0x45,%xmm5
+
+// CHECK: cvttps2dq 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0x2d,0xed,0x7e,0x00,0x00]
+ cvttps2dq 0x7eed,%xmm5
+
+// CHECK: cvttps2dq 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0x2d,0xfe,0xca,0xbe,0xba]
+ cvttps2dq 0xbabecafe,%xmm5
+
+// CHECK: cvttps2dq 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0x2d,0x78,0x56,0x34,0x12]
+ cvttps2dq 0x12345678,%xmm5
+
+// CHECK: cvttps2dq %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x5b,0xed]
+ cvttps2dq %xmm5,%xmm5
+
+// CHECK: maskmovdqu %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf7,0xed]
+ maskmovdqu %xmm5,%xmm5
+
+// CHECK: movdqa 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movdqa 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movdqa 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0x2d,0x45,0x00,0x00,0x00]
+ movdqa 0x45,%xmm5
+
+// CHECK: movdqa 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0x2d,0xed,0x7e,0x00,0x00]
+ movdqa 0x7eed,%xmm5
+
+// CHECK: movdqa 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0x2d,0xfe,0xca,0xbe,0xba]
+ movdqa 0xbabecafe,%xmm5
+
+// CHECK: movdqa 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0x2d,0x78,0x56,0x34,0x12]
+ movdqa 0x12345678,%xmm5
+
+// CHECK: movdqa %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0xed]
+ movdqa %xmm5,%xmm5
+
+// CHECK: movdqa %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0x7f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movdqa %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movdqa %xmm5, 69
+// CHECK: encoding: [0x66,0x0f,0x7f,0x2d,0x45,0x00,0x00,0x00]
+ movdqa %xmm5,0x45
+
+// CHECK: movdqa %xmm5, 32493
+// CHECK: encoding: [0x66,0x0f,0x7f,0x2d,0xed,0x7e,0x00,0x00]
+ movdqa %xmm5,0x7eed
+
+// CHECK: movdqa %xmm5, 3133065982
+// CHECK: encoding: [0x66,0x0f,0x7f,0x2d,0xfe,0xca,0xbe,0xba]
+ movdqa %xmm5,0xbabecafe
+
+// CHECK: movdqa %xmm5, 305419896
+// CHECK: encoding: [0x66,0x0f,0x7f,0x2d,0x78,0x56,0x34,0x12]
+ movdqa %xmm5,0x12345678
+
+// CHECK: movdqa %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6f,0xed]
+ movdqa %xmm5,%xmm5
+
+// CHECK: movdqu 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x6f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movdqu 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movdqu 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x6f,0x2d,0x45,0x00,0x00,0x00]
+ movdqu 0x45,%xmm5
+
+// CHECK: movdqu 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x6f,0x2d,0xed,0x7e,0x00,0x00]
+ movdqu 0x7eed,%xmm5
+
+// CHECK: movdqu 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x6f,0x2d,0xfe,0xca,0xbe,0xba]
+ movdqu 0xbabecafe,%xmm5
+
+// CHECK: movdqu 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x6f,0x2d,0x78,0x56,0x34,0x12]
+ movdqu 0x12345678,%xmm5
+
+// CHECK: movdqu %xmm5, 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xf3,0x0f,0x7f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movdqu %xmm5,0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: movdqu %xmm5, 69
+// CHECK: encoding: [0xf3,0x0f,0x7f,0x2d,0x45,0x00,0x00,0x00]
+ movdqu %xmm5,0x45
+
+// CHECK: movdqu %xmm5, 32493
+// CHECK: encoding: [0xf3,0x0f,0x7f,0x2d,0xed,0x7e,0x00,0x00]
+ movdqu %xmm5,0x7eed
+
+// CHECK: movdqu %xmm5, 3133065982
+// CHECK: encoding: [0xf3,0x0f,0x7f,0x2d,0xfe,0xca,0xbe,0xba]
+ movdqu %xmm5,0xbabecafe
+
+// CHECK: movdqu %xmm5, 305419896
+// CHECK: encoding: [0xf3,0x0f,0x7f,0x2d,0x78,0x56,0x34,0x12]
+ movdqu %xmm5,0x12345678
+
+// CHECK: movdq2q %xmm5, %mm3
+// CHECK: encoding: [0xf2,0x0f,0xd6,0xdd]
+ movdq2q %xmm5,%mm3
+
+// CHECK: movq2dq %mm3, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0xd6,0xeb]
+ movq2dq %mm3,%xmm5
+
+// CHECK: pmuludq 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0xf4,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmuludq 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmuludq 69, %mm3
+// CHECK: encoding: [0x0f,0xf4,0x1d,0x45,0x00,0x00,0x00]
+ pmuludq 0x45,%mm3
+
+// CHECK: pmuludq 32493, %mm3
+// CHECK: encoding: [0x0f,0xf4,0x1d,0xed,0x7e,0x00,0x00]
+ pmuludq 0x7eed,%mm3
+
+// CHECK: pmuludq 3133065982, %mm3
+// CHECK: encoding: [0x0f,0xf4,0x1d,0xfe,0xca,0xbe,0xba]
+ pmuludq 0xbabecafe,%mm3
+
+// CHECK: pmuludq 305419896, %mm3
+// CHECK: encoding: [0x0f,0xf4,0x1d,0x78,0x56,0x34,0x12]
+ pmuludq 0x12345678,%mm3
+
+// CHECK: pmuludq %mm3, %mm3
+// CHECK: encoding: [0x0f,0xf4,0xdb]
+ pmuludq %mm3,%mm3
+
+// CHECK: pmuludq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmuludq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmuludq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0x2d,0x45,0x00,0x00,0x00]
+ pmuludq 0x45,%xmm5
+
+// CHECK: pmuludq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0x2d,0xed,0x7e,0x00,0x00]
+ pmuludq 0x7eed,%xmm5
+
+// CHECK: pmuludq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0x2d,0xfe,0xca,0xbe,0xba]
+ pmuludq 0xbabecafe,%xmm5
+
+// CHECK: pmuludq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0x2d,0x78,0x56,0x34,0x12]
+ pmuludq 0x12345678,%xmm5
+
+// CHECK: pmuludq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xf4,0xed]
+ pmuludq %xmm5,%xmm5
+
+// CHECK: pslldq $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x73,0xfd,0x7f]
+ pslldq $0x7f,%xmm5
+
+// CHECK: psrldq $127, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x73,0xdd,0x7f]
+ psrldq $0x7f,%xmm5
+
+// CHECK: punpckhqdq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpckhqdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpckhqdq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0x2d,0x45,0x00,0x00,0x00]
+ punpckhqdq 0x45,%xmm5
+
+// CHECK: punpckhqdq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0x2d,0xed,0x7e,0x00,0x00]
+ punpckhqdq 0x7eed,%xmm5
+
+// CHECK: punpckhqdq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0x2d,0xfe,0xca,0xbe,0xba]
+ punpckhqdq 0xbabecafe,%xmm5
+
+// CHECK: punpckhqdq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0x2d,0x78,0x56,0x34,0x12]
+ punpckhqdq 0x12345678,%xmm5
+
+// CHECK: punpckhqdq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6d,0xed]
+ punpckhqdq %xmm5,%xmm5
+
+// CHECK: punpcklqdq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ punpcklqdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: punpcklqdq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0x2d,0x45,0x00,0x00,0x00]
+ punpcklqdq 0x45,%xmm5
+
+// CHECK: punpcklqdq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0x2d,0xed,0x7e,0x00,0x00]
+ punpcklqdq 0x7eed,%xmm5
+
+// CHECK: punpcklqdq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0x2d,0xfe,0xca,0xbe,0xba]
+ punpcklqdq 0xbabecafe,%xmm5
+
+// CHECK: punpcklqdq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0x2d,0x78,0x56,0x34,0x12]
+ punpcklqdq 0x12345678,%xmm5
+
+// CHECK: punpcklqdq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x6c,0xed]
+ punpcklqdq %xmm5,%xmm5
+
+// CHECK: addsubpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addsubpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addsubpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0x2d,0x45,0x00,0x00,0x00]
+ addsubpd 0x45,%xmm5
+
+// CHECK: addsubpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0x2d,0xed,0x7e,0x00,0x00]
+ addsubpd 0x7eed,%xmm5
+
+// CHECK: addsubpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0x2d,0xfe,0xca,0xbe,0xba]
+ addsubpd 0xbabecafe,%xmm5
+
+// CHECK: addsubpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0x2d,0x78,0x56,0x34,0x12]
+ addsubpd 0x12345678,%xmm5
+
+// CHECK: addsubpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0xd0,0xed]
+ addsubpd %xmm5,%xmm5
+
+// CHECK: addsubps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ addsubps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: addsubps 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0x2d,0x45,0x00,0x00,0x00]
+ addsubps 0x45,%xmm5
+
+// CHECK: addsubps 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0x2d,0xed,0x7e,0x00,0x00]
+ addsubps 0x7eed,%xmm5
+
+// CHECK: addsubps 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0x2d,0xfe,0xca,0xbe,0xba]
+ addsubps 0xbabecafe,%xmm5
+
+// CHECK: addsubps 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0x2d,0x78,0x56,0x34,0x12]
+ addsubps 0x12345678,%xmm5
+
+// CHECK: addsubps %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xd0,0xed]
+ addsubps %xmm5,%xmm5
+
+// CHECK: fisttpl 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0xdb,0x8c,0xcb,0xef,0xbe,0xad,0xde]
+ fisttpl 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: fisttpl 3133065982
+// CHECK: encoding: [0xdb,0x0d,0xfe,0xca,0xbe,0xba]
+ fisttpl 0xbabecafe
+
+// CHECK: fisttpl 305419896
+// CHECK: encoding: [0xdb,0x0d,0x78,0x56,0x34,0x12]
+ fisttpl 0x12345678
+
+// CHECK: haddpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ haddpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: haddpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0x2d,0x45,0x00,0x00,0x00]
+ haddpd 0x45,%xmm5
+
+// CHECK: haddpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0x2d,0xed,0x7e,0x00,0x00]
+ haddpd 0x7eed,%xmm5
+
+// CHECK: haddpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0x2d,0xfe,0xca,0xbe,0xba]
+ haddpd 0xbabecafe,%xmm5
+
+// CHECK: haddpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0x2d,0x78,0x56,0x34,0x12]
+ haddpd 0x12345678,%xmm5
+
+// CHECK: haddpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7c,0xed]
+ haddpd %xmm5,%xmm5
+
+// CHECK: haddps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ haddps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: haddps 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0x2d,0x45,0x00,0x00,0x00]
+ haddps 0x45,%xmm5
+
+// CHECK: haddps 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0x2d,0xed,0x7e,0x00,0x00]
+ haddps 0x7eed,%xmm5
+
+// CHECK: haddps 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0x2d,0xfe,0xca,0xbe,0xba]
+ haddps 0xbabecafe,%xmm5
+
+// CHECK: haddps 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0x2d,0x78,0x56,0x34,0x12]
+ haddps 0x12345678,%xmm5
+
+// CHECK: haddps %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7c,0xed]
+ haddps %xmm5,%xmm5
+
+// CHECK: hsubpd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ hsubpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: hsubpd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0x2d,0x45,0x00,0x00,0x00]
+ hsubpd 0x45,%xmm5
+
+// CHECK: hsubpd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0x2d,0xed,0x7e,0x00,0x00]
+ hsubpd 0x7eed,%xmm5
+
+// CHECK: hsubpd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0x2d,0xfe,0xca,0xbe,0xba]
+ hsubpd 0xbabecafe,%xmm5
+
+// CHECK: hsubpd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0x2d,0x78,0x56,0x34,0x12]
+ hsubpd 0x12345678,%xmm5
+
+// CHECK: hsubpd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x7d,0xed]
+ hsubpd %xmm5,%xmm5
+
+// CHECK: hsubps 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ hsubps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: hsubps 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0x2d,0x45,0x00,0x00,0x00]
+ hsubps 0x45,%xmm5
+
+// CHECK: hsubps 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0x2d,0xed,0x7e,0x00,0x00]
+ hsubps 0x7eed,%xmm5
+
+// CHECK: hsubps 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0x2d,0xfe,0xca,0xbe,0xba]
+ hsubps 0xbabecafe,%xmm5
+
+// CHECK: hsubps 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0x2d,0x78,0x56,0x34,0x12]
+ hsubps 0x12345678,%xmm5
+
+// CHECK: hsubps %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x7d,0xed]
+ hsubps %xmm5,%xmm5
+
+// CHECK: lddqu 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xf0,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ lddqu 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: lddqu 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xf0,0x2d,0x45,0x00,0x00,0x00]
+ lddqu 0x45,%xmm5
+
+// CHECK: lddqu 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xf0,0x2d,0xed,0x7e,0x00,0x00]
+ lddqu 0x7eed,%xmm5
+
+// CHECK: lddqu 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xf0,0x2d,0xfe,0xca,0xbe,0xba]
+ lddqu 0xbabecafe,%xmm5
+
+// CHECK: lddqu 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0xf0,0x2d,0x78,0x56,0x34,0x12]
+ lddqu 0x12345678,%xmm5
+
+// CHECK: movddup 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movddup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movddup 69, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0x2d,0x45,0x00,0x00,0x00]
+ movddup 0x45,%xmm5
+
+// CHECK: movddup 32493, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0x2d,0xed,0x7e,0x00,0x00]
+ movddup 0x7eed,%xmm5
+
+// CHECK: movddup 3133065982, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0x2d,0xfe,0xca,0xbe,0xba]
+ movddup 0xbabecafe,%xmm5
+
+// CHECK: movddup 305419896, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0x2d,0x78,0x56,0x34,0x12]
+ movddup 0x12345678,%xmm5
+
+// CHECK: movddup %xmm5, %xmm5
+// CHECK: encoding: [0xf2,0x0f,0x12,0xed]
+ movddup %xmm5,%xmm5
+
+// CHECK: movshdup 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movshdup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movshdup 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0x2d,0x45,0x00,0x00,0x00]
+ movshdup 0x45,%xmm5
+
+// CHECK: movshdup 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0x2d,0xed,0x7e,0x00,0x00]
+ movshdup 0x7eed,%xmm5
+
+// CHECK: movshdup 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0x2d,0xfe,0xca,0xbe,0xba]
+ movshdup 0xbabecafe,%xmm5
+
+// CHECK: movshdup 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0x2d,0x78,0x56,0x34,0x12]
+ movshdup 0x12345678,%xmm5
+
+// CHECK: movshdup %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x16,0xed]
+ movshdup %xmm5,%xmm5
+
+// CHECK: movsldup 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movsldup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movsldup 69, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0x2d,0x45,0x00,0x00,0x00]
+ movsldup 0x45,%xmm5
+
+// CHECK: movsldup 32493, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0x2d,0xed,0x7e,0x00,0x00]
+ movsldup 0x7eed,%xmm5
+
+// CHECK: movsldup 3133065982, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0x2d,0xfe,0xca,0xbe,0xba]
+ movsldup 0xbabecafe,%xmm5
+
+// CHECK: movsldup 305419896, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0x2d,0x78,0x56,0x34,0x12]
+ movsldup 0x12345678,%xmm5
+
+// CHECK: movsldup %xmm5, %xmm5
+// CHECK: encoding: [0xf3,0x0f,0x12,0xed]
+ movsldup %xmm5,%xmm5
+
+// CHECK: vmclear 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x66,0x0f,0xc7,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ vmclear 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: vmclear 32493
+// CHECK: encoding: [0x66,0x0f,0xc7,0x35,0xed,0x7e,0x00,0x00]
+ vmclear 0x7eed
+
+// CHECK: vmclear 3133065982
+// CHECK: encoding: [0x66,0x0f,0xc7,0x35,0xfe,0xca,0xbe,0xba]
+ vmclear 0xbabecafe
+
+// CHECK: vmclear 305419896
+// CHECK: encoding: [0x66,0x0f,0xc7,0x35,0x78,0x56,0x34,0x12]
+ vmclear 0x12345678
+
+// CHECK: vmptrld 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xc7,0xb4,0xcb,0xef,0xbe,0xad,0xde]
+ vmptrld 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: vmptrld 32493
+// CHECK: encoding: [0x0f,0xc7,0x35,0xed,0x7e,0x00,0x00]
+ vmptrld 0x7eed
+
+// CHECK: vmptrld 3133065982
+// CHECK: encoding: [0x0f,0xc7,0x35,0xfe,0xca,0xbe,0xba]
+ vmptrld 0xbabecafe
+
+// CHECK: vmptrld 305419896
+// CHECK: encoding: [0x0f,0xc7,0x35,0x78,0x56,0x34,0x12]
+ vmptrld 0x12345678
+
+// CHECK: vmptrst 3735928559(%ebx,%ecx,8)
+// CHECK: encoding: [0x0f,0xc7,0xbc,0xcb,0xef,0xbe,0xad,0xde]
+ vmptrst 0xdeadbeef(%ebx,%ecx,8)
+
+// CHECK: vmptrst 32493
+// CHECK: encoding: [0x0f,0xc7,0x3d,0xed,0x7e,0x00,0x00]
+ vmptrst 0x7eed
+
+// CHECK: vmptrst 3133065982
+// CHECK: encoding: [0x0f,0xc7,0x3d,0xfe,0xca,0xbe,0xba]
+ vmptrst 0xbabecafe
+
+// CHECK: vmptrst 305419896
+// CHECK: encoding: [0x0f,0xc7,0x3d,0x78,0x56,0x34,0x12]
+ vmptrst 0x12345678
+
+// CHECK: phaddw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phaddw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phaddw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0x1d,0x45,0x00,0x00,0x00]
+ phaddw 0x45,%mm3
+
+// CHECK: phaddw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0x1d,0xed,0x7e,0x00,0x00]
+ phaddw 0x7eed,%mm3
+
+// CHECK: phaddw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0x1d,0xfe,0xca,0xbe,0xba]
+ phaddw 0xbabecafe,%mm3
+
+// CHECK: phaddw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0x1d,0x78,0x56,0x34,0x12]
+ phaddw 0x12345678,%mm3
+
+// CHECK: phaddw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x01,0xdb]
+ phaddw %mm3,%mm3
+
+// CHECK: phaddw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phaddw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phaddw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0x2d,0x45,0x00,0x00,0x00]
+ phaddw 0x45,%xmm5
+
+// CHECK: phaddw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0x2d,0xed,0x7e,0x00,0x00]
+ phaddw 0x7eed,%xmm5
+
+// CHECK: phaddw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0x2d,0xfe,0xca,0xbe,0xba]
+ phaddw 0xbabecafe,%xmm5
+
+// CHECK: phaddw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0x2d,0x78,0x56,0x34,0x12]
+ phaddw 0x12345678,%xmm5
+
+// CHECK: phaddw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x01,0xed]
+ phaddw %xmm5,%xmm5
+
+// CHECK: phaddd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phaddd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phaddd 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0x1d,0x45,0x00,0x00,0x00]
+ phaddd 0x45,%mm3
+
+// CHECK: phaddd 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0x1d,0xed,0x7e,0x00,0x00]
+ phaddd 0x7eed,%mm3
+
+// CHECK: phaddd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0x1d,0xfe,0xca,0xbe,0xba]
+ phaddd 0xbabecafe,%mm3
+
+// CHECK: phaddd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0x1d,0x78,0x56,0x34,0x12]
+ phaddd 0x12345678,%mm3
+
+// CHECK: phaddd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x02,0xdb]
+ phaddd %mm3,%mm3
+
+// CHECK: phaddd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phaddd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phaddd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0x2d,0x45,0x00,0x00,0x00]
+ phaddd 0x45,%xmm5
+
+// CHECK: phaddd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0x2d,0xed,0x7e,0x00,0x00]
+ phaddd 0x7eed,%xmm5
+
+// CHECK: phaddd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0x2d,0xfe,0xca,0xbe,0xba]
+ phaddd 0xbabecafe,%xmm5
+
+// CHECK: phaddd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0x2d,0x78,0x56,0x34,0x12]
+ phaddd 0x12345678,%xmm5
+
+// CHECK: phaddd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x02,0xed]
+ phaddd %xmm5,%xmm5
+
+// CHECK: phaddsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phaddsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phaddsw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0x1d,0x45,0x00,0x00,0x00]
+ phaddsw 0x45,%mm3
+
+// CHECK: phaddsw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0x1d,0xed,0x7e,0x00,0x00]
+ phaddsw 0x7eed,%mm3
+
+// CHECK: phaddsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0x1d,0xfe,0xca,0xbe,0xba]
+ phaddsw 0xbabecafe,%mm3
+
+// CHECK: phaddsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0x1d,0x78,0x56,0x34,0x12]
+ phaddsw 0x12345678,%mm3
+
+// CHECK: phaddsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x03,0xdb]
+ phaddsw %mm3,%mm3
+
+// CHECK: phaddsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phaddsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phaddsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0x2d,0x45,0x00,0x00,0x00]
+ phaddsw 0x45,%xmm5
+
+// CHECK: phaddsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0x2d,0xed,0x7e,0x00,0x00]
+ phaddsw 0x7eed,%xmm5
+
+// CHECK: phaddsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0x2d,0xfe,0xca,0xbe,0xba]
+ phaddsw 0xbabecafe,%xmm5
+
+// CHECK: phaddsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0x2d,0x78,0x56,0x34,0x12]
+ phaddsw 0x12345678,%xmm5
+
+// CHECK: phaddsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x03,0xed]
+ phaddsw %xmm5,%xmm5
+
+// CHECK: phsubw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phsubw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phsubw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0x1d,0x45,0x00,0x00,0x00]
+ phsubw 0x45,%mm3
+
+// CHECK: phsubw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0x1d,0xed,0x7e,0x00,0x00]
+ phsubw 0x7eed,%mm3
+
+// CHECK: phsubw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0x1d,0xfe,0xca,0xbe,0xba]
+ phsubw 0xbabecafe,%mm3
+
+// CHECK: phsubw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0x1d,0x78,0x56,0x34,0x12]
+ phsubw 0x12345678,%mm3
+
+// CHECK: phsubw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x05,0xdb]
+ phsubw %mm3,%mm3
+
+// CHECK: phsubw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phsubw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phsubw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0x2d,0x45,0x00,0x00,0x00]
+ phsubw 0x45,%xmm5
+
+// CHECK: phsubw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0x2d,0xed,0x7e,0x00,0x00]
+ phsubw 0x7eed,%xmm5
+
+// CHECK: phsubw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0x2d,0xfe,0xca,0xbe,0xba]
+ phsubw 0xbabecafe,%xmm5
+
+// CHECK: phsubw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0x2d,0x78,0x56,0x34,0x12]
+ phsubw 0x12345678,%xmm5
+
+// CHECK: phsubw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x05,0xed]
+ phsubw %xmm5,%xmm5
+
+// CHECK: phsubd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phsubd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phsubd 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0x1d,0x45,0x00,0x00,0x00]
+ phsubd 0x45,%mm3
+
+// CHECK: phsubd 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0x1d,0xed,0x7e,0x00,0x00]
+ phsubd 0x7eed,%mm3
+
+// CHECK: phsubd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0x1d,0xfe,0xca,0xbe,0xba]
+ phsubd 0xbabecafe,%mm3
+
+// CHECK: phsubd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0x1d,0x78,0x56,0x34,0x12]
+ phsubd 0x12345678,%mm3
+
+// CHECK: phsubd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x06,0xdb]
+ phsubd %mm3,%mm3
+
+// CHECK: phsubd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phsubd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phsubd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0x2d,0x45,0x00,0x00,0x00]
+ phsubd 0x45,%xmm5
+
+// CHECK: phsubd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0x2d,0xed,0x7e,0x00,0x00]
+ phsubd 0x7eed,%xmm5
+
+// CHECK: phsubd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0x2d,0xfe,0xca,0xbe,0xba]
+ phsubd 0xbabecafe,%xmm5
+
+// CHECK: phsubd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0x2d,0x78,0x56,0x34,0x12]
+ phsubd 0x12345678,%xmm5
+
+// CHECK: phsubd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x06,0xed]
+ phsubd %xmm5,%xmm5
+
+// CHECK: phsubsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ phsubsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: phsubsw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0x1d,0x45,0x00,0x00,0x00]
+ phsubsw 0x45,%mm3
+
+// CHECK: phsubsw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0x1d,0xed,0x7e,0x00,0x00]
+ phsubsw 0x7eed,%mm3
+
+// CHECK: phsubsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0x1d,0xfe,0xca,0xbe,0xba]
+ phsubsw 0xbabecafe,%mm3
+
+// CHECK: phsubsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0x1d,0x78,0x56,0x34,0x12]
+ phsubsw 0x12345678,%mm3
+
+// CHECK: phsubsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x07,0xdb]
+ phsubsw %mm3,%mm3
+
+// CHECK: phsubsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phsubsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phsubsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0x2d,0x45,0x00,0x00,0x00]
+ phsubsw 0x45,%xmm5
+
+// CHECK: phsubsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0x2d,0xed,0x7e,0x00,0x00]
+ phsubsw 0x7eed,%xmm5
+
+// CHECK: phsubsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0x2d,0xfe,0xca,0xbe,0xba]
+ phsubsw 0xbabecafe,%xmm5
+
+// CHECK: phsubsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0x2d,0x78,0x56,0x34,0x12]
+ phsubsw 0x12345678,%xmm5
+
+// CHECK: phsubsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x07,0xed]
+ phsubsw %xmm5,%xmm5
+
+// CHECK: pmaddubsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmaddubsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmaddubsw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0x1d,0x45,0x00,0x00,0x00]
+ pmaddubsw 0x45,%mm3
+
+// CHECK: pmaddubsw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0x1d,0xed,0x7e,0x00,0x00]
+ pmaddubsw 0x7eed,%mm3
+
+// CHECK: pmaddubsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0x1d,0xfe,0xca,0xbe,0xba]
+ pmaddubsw 0xbabecafe,%mm3
+
+// CHECK: pmaddubsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0x1d,0x78,0x56,0x34,0x12]
+ pmaddubsw 0x12345678,%mm3
+
+// CHECK: pmaddubsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x04,0xdb]
+ pmaddubsw %mm3,%mm3
+
+// CHECK: pmaddubsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaddubsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaddubsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0x2d,0x45,0x00,0x00,0x00]
+ pmaddubsw 0x45,%xmm5
+
+// CHECK: pmaddubsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0x2d,0xed,0x7e,0x00,0x00]
+ pmaddubsw 0x7eed,%xmm5
+
+// CHECK: pmaddubsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaddubsw 0xbabecafe,%xmm5
+
+// CHECK: pmaddubsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0x2d,0x78,0x56,0x34,0x12]
+ pmaddubsw 0x12345678,%xmm5
+
+// CHECK: pmaddubsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x04,0xed]
+ pmaddubsw %xmm5,%xmm5
+
+// CHECK: pmulhrsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhrsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pmulhrsw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0x1d,0x45,0x00,0x00,0x00]
+ pmulhrsw 0x45,%mm3
+
+// CHECK: pmulhrsw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0x1d,0xed,0x7e,0x00,0x00]
+ pmulhrsw 0x7eed,%mm3
+
+// CHECK: pmulhrsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0x1d,0xfe,0xca,0xbe,0xba]
+ pmulhrsw 0xbabecafe,%mm3
+
+// CHECK: pmulhrsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0x1d,0x78,0x56,0x34,0x12]
+ pmulhrsw 0x12345678,%mm3
+
+// CHECK: pmulhrsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0b,0xdb]
+ pmulhrsw %mm3,%mm3
+
+// CHECK: pmulhrsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmulhrsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulhrsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0x2d,0x45,0x00,0x00,0x00]
+ pmulhrsw 0x45,%xmm5
+
+// CHECK: pmulhrsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0x2d,0xed,0x7e,0x00,0x00]
+ pmulhrsw 0x7eed,%xmm5
+
+// CHECK: pmulhrsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0x2d,0xfe,0xca,0xbe,0xba]
+ pmulhrsw 0xbabecafe,%xmm5
+
+// CHECK: pmulhrsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0x2d,0x78,0x56,0x34,0x12]
+ pmulhrsw 0x12345678,%xmm5
+
+// CHECK: pmulhrsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0b,0xed]
+ pmulhrsw %xmm5,%xmm5
+
+// CHECK: pshufb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pshufb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pshufb 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0x1d,0x45,0x00,0x00,0x00]
+ pshufb 0x45,%mm3
+
+// CHECK: pshufb 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0x1d,0xed,0x7e,0x00,0x00]
+ pshufb 0x7eed,%mm3
+
+// CHECK: pshufb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0x1d,0xfe,0xca,0xbe,0xba]
+ pshufb 0xbabecafe,%mm3
+
+// CHECK: pshufb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0x1d,0x78,0x56,0x34,0x12]
+ pshufb 0x12345678,%mm3
+
+// CHECK: pshufb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x00,0xdb]
+ pshufb %mm3,%mm3
+
+// CHECK: pshufb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pshufb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pshufb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0x2d,0x45,0x00,0x00,0x00]
+ pshufb 0x45,%xmm5
+
+// CHECK: pshufb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0x2d,0xed,0x7e,0x00,0x00]
+ pshufb 0x7eed,%xmm5
+
+// CHECK: pshufb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0x2d,0xfe,0xca,0xbe,0xba]
+ pshufb 0xbabecafe,%xmm5
+
+// CHECK: pshufb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0x2d,0x78,0x56,0x34,0x12]
+ pshufb 0x12345678,%xmm5
+
+// CHECK: pshufb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x00,0xed]
+ pshufb %xmm5,%xmm5
+
+// CHECK: psignb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psignb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psignb 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0x1d,0x45,0x00,0x00,0x00]
+ psignb 0x45,%mm3
+
+// CHECK: psignb 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0x1d,0xed,0x7e,0x00,0x00]
+ psignb 0x7eed,%mm3
+
+// CHECK: psignb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0x1d,0xfe,0xca,0xbe,0xba]
+ psignb 0xbabecafe,%mm3
+
+// CHECK: psignb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0x1d,0x78,0x56,0x34,0x12]
+ psignb 0x12345678,%mm3
+
+// CHECK: psignb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x08,0xdb]
+ psignb %mm3,%mm3
+
+// CHECK: psignb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psignb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psignb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0x2d,0x45,0x00,0x00,0x00]
+ psignb 0x45,%xmm5
+
+// CHECK: psignb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0x2d,0xed,0x7e,0x00,0x00]
+ psignb 0x7eed,%xmm5
+
+// CHECK: psignb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0x2d,0xfe,0xca,0xbe,0xba]
+ psignb 0xbabecafe,%xmm5
+
+// CHECK: psignb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0x2d,0x78,0x56,0x34,0x12]
+ psignb 0x12345678,%xmm5
+
+// CHECK: psignb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x08,0xed]
+ psignb %xmm5,%xmm5
+
+// CHECK: psignw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psignw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psignw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0x1d,0x45,0x00,0x00,0x00]
+ psignw 0x45,%mm3
+
+// CHECK: psignw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0x1d,0xed,0x7e,0x00,0x00]
+ psignw 0x7eed,%mm3
+
+// CHECK: psignw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0x1d,0xfe,0xca,0xbe,0xba]
+ psignw 0xbabecafe,%mm3
+
+// CHECK: psignw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0x1d,0x78,0x56,0x34,0x12]
+ psignw 0x12345678,%mm3
+
+// CHECK: psignw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x09,0xdb]
+ psignw %mm3,%mm3
+
+// CHECK: psignw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psignw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psignw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0x2d,0x45,0x00,0x00,0x00]
+ psignw 0x45,%xmm5
+
+// CHECK: psignw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0x2d,0xed,0x7e,0x00,0x00]
+ psignw 0x7eed,%xmm5
+
+// CHECK: psignw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0x2d,0xfe,0xca,0xbe,0xba]
+ psignw 0xbabecafe,%xmm5
+
+// CHECK: psignw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0x2d,0x78,0x56,0x34,0x12]
+ psignw 0x12345678,%xmm5
+
+// CHECK: psignw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x09,0xed]
+ psignw %xmm5,%xmm5
+
+// CHECK: psignd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ psignd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: psignd 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0x1d,0x45,0x00,0x00,0x00]
+ psignd 0x45,%mm3
+
+// CHECK: psignd 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0x1d,0xed,0x7e,0x00,0x00]
+ psignd 0x7eed,%mm3
+
+// CHECK: psignd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0x1d,0xfe,0xca,0xbe,0xba]
+ psignd 0xbabecafe,%mm3
+
+// CHECK: psignd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0x1d,0x78,0x56,0x34,0x12]
+ psignd 0x12345678,%mm3
+
+// CHECK: psignd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x0a,0xdb]
+ psignd %mm3,%mm3
+
+// CHECK: psignd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ psignd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: psignd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0x2d,0x45,0x00,0x00,0x00]
+ psignd 0x45,%xmm5
+
+// CHECK: psignd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0x2d,0xed,0x7e,0x00,0x00]
+ psignd 0x7eed,%xmm5
+
+// CHECK: psignd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0x2d,0xfe,0xca,0xbe,0xba]
+ psignd 0xbabecafe,%xmm5
+
+// CHECK: psignd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0x2d,0x78,0x56,0x34,0x12]
+ psignd 0x12345678,%xmm5
+
+// CHECK: psignd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x0a,0xed]
+ psignd %xmm5,%xmm5
+
+// CHECK: pabsb 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pabsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsb 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0x1d,0x45,0x00,0x00,0x00]
+ pabsb 0x45,%mm3
+
+// CHECK: pabsb 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0x1d,0xed,0x7e,0x00,0x00]
+ pabsb 0x7eed,%mm3
+
+// CHECK: pabsb 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0x1d,0xfe,0xca,0xbe,0xba]
+ pabsb 0xbabecafe,%mm3
+
+// CHECK: pabsb 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0x1d,0x78,0x56,0x34,0x12]
+ pabsb 0x12345678,%mm3
+
+// CHECK: pabsb %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1c,0xdb]
+ pabsb %mm3,%mm3
+
+// CHECK: pabsb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pabsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0x2d,0x45,0x00,0x00,0x00]
+ pabsb 0x45,%xmm5
+
+// CHECK: pabsb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0x2d,0xed,0x7e,0x00,0x00]
+ pabsb 0x7eed,%xmm5
+
+// CHECK: pabsb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0x2d,0xfe,0xca,0xbe,0xba]
+ pabsb 0xbabecafe,%xmm5
+
+// CHECK: pabsb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0x2d,0x78,0x56,0x34,0x12]
+ pabsb 0x12345678,%xmm5
+
+// CHECK: pabsb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1c,0xed]
+ pabsb %xmm5,%xmm5
+
+// CHECK: pabsw 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pabsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsw 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0x1d,0x45,0x00,0x00,0x00]
+ pabsw 0x45,%mm3
+
+// CHECK: pabsw 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0x1d,0xed,0x7e,0x00,0x00]
+ pabsw 0x7eed,%mm3
+
+// CHECK: pabsw 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0x1d,0xfe,0xca,0xbe,0xba]
+ pabsw 0xbabecafe,%mm3
+
+// CHECK: pabsw 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0x1d,0x78,0x56,0x34,0x12]
+ pabsw 0x12345678,%mm3
+
+// CHECK: pabsw %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1d,0xdb]
+ pabsw %mm3,%mm3
+
+// CHECK: pabsw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pabsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0x2d,0x45,0x00,0x00,0x00]
+ pabsw 0x45,%xmm5
+
+// CHECK: pabsw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0x2d,0xed,0x7e,0x00,0x00]
+ pabsw 0x7eed,%xmm5
+
+// CHECK: pabsw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0x2d,0xfe,0xca,0xbe,0xba]
+ pabsw 0xbabecafe,%xmm5
+
+// CHECK: pabsw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0x2d,0x78,0x56,0x34,0x12]
+ pabsw 0x12345678,%xmm5
+
+// CHECK: pabsw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1d,0xed]
+ pabsw %xmm5,%xmm5
+
+// CHECK: pabsd 3735928559(%ebx,%ecx,8), %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0x9c,0xcb,0xef,0xbe,0xad,0xde]
+ pabsd 0xdeadbeef(%ebx,%ecx,8),%mm3
+
+// CHECK: pabsd 69, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0x1d,0x45,0x00,0x00,0x00]
+ pabsd 0x45,%mm3
+
+// CHECK: pabsd 32493, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0x1d,0xed,0x7e,0x00,0x00]
+ pabsd 0x7eed,%mm3
+
+// CHECK: pabsd 3133065982, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0x1d,0xfe,0xca,0xbe,0xba]
+ pabsd 0xbabecafe,%mm3
+
+// CHECK: pabsd 305419896, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0x1d,0x78,0x56,0x34,0x12]
+ pabsd 0x12345678,%mm3
+
+// CHECK: pabsd %mm3, %mm3
+// CHECK: encoding: [0x0f,0x38,0x1e,0xdb]
+ pabsd %mm3,%mm3
+
+// CHECK: pabsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pabsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pabsd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0x2d,0x45,0x00,0x00,0x00]
+ pabsd 0x45,%xmm5
+
+// CHECK: pabsd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0x2d,0xed,0x7e,0x00,0x00]
+ pabsd 0x7eed,%xmm5
+
+// CHECK: pabsd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0x2d,0xfe,0xca,0xbe,0xba]
+ pabsd 0xbabecafe,%xmm5
+
+// CHECK: pabsd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0x2d,0x78,0x56,0x34,0x12]
+ pabsd 0x12345678,%xmm5
+
+// CHECK: pabsd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x1e,0xed]
+ pabsd %xmm5,%xmm5
+
+// CHECK: femms
+// CHECK: encoding: [0x0f,0x0e]
+ femms
+
+// CHECK: movntdqa 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ movntdqa 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: movntdqa 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2a,0x2d,0x45,0x00,0x00,0x00]
+ movntdqa 0x45,%xmm5
+
+// CHECK: movntdqa 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2a,0x2d,0xed,0x7e,0x00,0x00]
+ movntdqa 0x7eed,%xmm5
+
+// CHECK: movntdqa 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2a,0x2d,0xfe,0xca,0xbe,0xba]
+ movntdqa 0xbabecafe,%xmm5
+
+// CHECK: movntdqa 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2a,0x2d,0x78,0x56,0x34,0x12]
+ movntdqa 0x12345678,%xmm5
+
+// CHECK: packusdw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ packusdw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: packusdw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0x2d,0x45,0x00,0x00,0x00]
+ packusdw 0x45,%xmm5
+
+// CHECK: packusdw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0x2d,0xed,0x7e,0x00,0x00]
+ packusdw 0x7eed,%xmm5
+
+// CHECK: packusdw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0x2d,0xfe,0xca,0xbe,0xba]
+ packusdw 0xbabecafe,%xmm5
+
+// CHECK: packusdw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0x2d,0x78,0x56,0x34,0x12]
+ packusdw 0x12345678,%xmm5
+
+// CHECK: packusdw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x2b,0xed]
+ packusdw %xmm5,%xmm5
+
+// CHECK: pcmpeqq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpeqq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpeqq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0x2d,0x45,0x00,0x00,0x00]
+ pcmpeqq 0x45,%xmm5
+
+// CHECK: pcmpeqq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpeqq 0x7eed,%xmm5
+
+// CHECK: pcmpeqq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpeqq 0xbabecafe,%xmm5
+
+// CHECK: pcmpeqq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0x2d,0x78,0x56,0x34,0x12]
+ pcmpeqq 0x12345678,%xmm5
+
+// CHECK: pcmpeqq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x29,0xed]
+ pcmpeqq %xmm5,%xmm5
+
+// CHECK: phminposuw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ phminposuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: phminposuw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0x2d,0x45,0x00,0x00,0x00]
+ phminposuw 0x45,%xmm5
+
+// CHECK: phminposuw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0x2d,0xed,0x7e,0x00,0x00]
+ phminposuw 0x7eed,%xmm5
+
+// CHECK: phminposuw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0x2d,0xfe,0xca,0xbe,0xba]
+ phminposuw 0xbabecafe,%xmm5
+
+// CHECK: phminposuw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0x2d,0x78,0x56,0x34,0x12]
+ phminposuw 0x12345678,%xmm5
+
+// CHECK: phminposuw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x41,0xed]
+ phminposuw %xmm5,%xmm5
+
+// CHECK: pmaxsb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxsb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0x2d,0x45,0x00,0x00,0x00]
+ pmaxsb 0x45,%xmm5
+
+// CHECK: pmaxsb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxsb 0x7eed,%xmm5
+
+// CHECK: pmaxsb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxsb 0xbabecafe,%xmm5
+
+// CHECK: pmaxsb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0x2d,0x78,0x56,0x34,0x12]
+ pmaxsb 0x12345678,%xmm5
+
+// CHECK: pmaxsb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3c,0xed]
+ pmaxsb %xmm5,%xmm5
+
+// CHECK: pmaxsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxsd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0x2d,0x45,0x00,0x00,0x00]
+ pmaxsd 0x45,%xmm5
+
+// CHECK: pmaxsd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxsd 0x7eed,%xmm5
+
+// CHECK: pmaxsd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxsd 0xbabecafe,%xmm5
+
+// CHECK: pmaxsd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0x2d,0x78,0x56,0x34,0x12]
+ pmaxsd 0x12345678,%xmm5
+
+// CHECK: pmaxsd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3d,0xed]
+ pmaxsd %xmm5,%xmm5
+
+// CHECK: pmaxud 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxud 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxud 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0x2d,0x45,0x00,0x00,0x00]
+ pmaxud 0x45,%xmm5
+
+// CHECK: pmaxud 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxud 0x7eed,%xmm5
+
+// CHECK: pmaxud 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxud 0xbabecafe,%xmm5
+
+// CHECK: pmaxud 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0x2d,0x78,0x56,0x34,0x12]
+ pmaxud 0x12345678,%xmm5
+
+// CHECK: pmaxud %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3f,0xed]
+ pmaxud %xmm5,%xmm5
+
+// CHECK: pmaxuw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmaxuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmaxuw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0x2d,0x45,0x00,0x00,0x00]
+ pmaxuw 0x45,%xmm5
+
+// CHECK: pmaxuw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0x2d,0xed,0x7e,0x00,0x00]
+ pmaxuw 0x7eed,%xmm5
+
+// CHECK: pmaxuw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0x2d,0xfe,0xca,0xbe,0xba]
+ pmaxuw 0xbabecafe,%xmm5
+
+// CHECK: pmaxuw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0x2d,0x78,0x56,0x34,0x12]
+ pmaxuw 0x12345678,%xmm5
+
+// CHECK: pmaxuw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3e,0xed]
+ pmaxuw %xmm5,%xmm5
+
+// CHECK: pminsb 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminsb 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0x2d,0x45,0x00,0x00,0x00]
+ pminsb 0x45,%xmm5
+
+// CHECK: pminsb 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0x2d,0xed,0x7e,0x00,0x00]
+ pminsb 0x7eed,%xmm5
+
+// CHECK: pminsb 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0x2d,0xfe,0xca,0xbe,0xba]
+ pminsb 0xbabecafe,%xmm5
+
+// CHECK: pminsb 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0x2d,0x78,0x56,0x34,0x12]
+ pminsb 0x12345678,%xmm5
+
+// CHECK: pminsb %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x38,0xed]
+ pminsb %xmm5,%xmm5
+
+// CHECK: pminsd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminsd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0x2d,0x45,0x00,0x00,0x00]
+ pminsd 0x45,%xmm5
+
+// CHECK: pminsd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0x2d,0xed,0x7e,0x00,0x00]
+ pminsd 0x7eed,%xmm5
+
+// CHECK: pminsd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0x2d,0xfe,0xca,0xbe,0xba]
+ pminsd 0xbabecafe,%xmm5
+
+// CHECK: pminsd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0x2d,0x78,0x56,0x34,0x12]
+ pminsd 0x12345678,%xmm5
+
+// CHECK: pminsd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x39,0xed]
+ pminsd %xmm5,%xmm5
+
+// CHECK: pminud 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminud 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminud 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0x2d,0x45,0x00,0x00,0x00]
+ pminud 0x45,%xmm5
+
+// CHECK: pminud 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0x2d,0xed,0x7e,0x00,0x00]
+ pminud 0x7eed,%xmm5
+
+// CHECK: pminud 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0x2d,0xfe,0xca,0xbe,0xba]
+ pminud 0xbabecafe,%xmm5
+
+// CHECK: pminud 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0x2d,0x78,0x56,0x34,0x12]
+ pminud 0x12345678,%xmm5
+
+// CHECK: pminud %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3b,0xed]
+ pminud %xmm5,%xmm5
+
+// CHECK: pminuw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pminuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pminuw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0x2d,0x45,0x00,0x00,0x00]
+ pminuw 0x45,%xmm5
+
+// CHECK: pminuw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0x2d,0xed,0x7e,0x00,0x00]
+ pminuw 0x7eed,%xmm5
+
+// CHECK: pminuw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0x2d,0xfe,0xca,0xbe,0xba]
+ pminuw 0xbabecafe,%xmm5
+
+// CHECK: pminuw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0x2d,0x78,0x56,0x34,0x12]
+ pminuw 0x12345678,%xmm5
+
+// CHECK: pminuw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x3a,0xed]
+ pminuw %xmm5,%xmm5
+
+// CHECK: pmovsxbw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxbw 0x45,%xmm5
+
+// CHECK: pmovsxbw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxbw 0x7eed,%xmm5
+
+// CHECK: pmovsxbw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxbw 0xbabecafe,%xmm5
+
+// CHECK: pmovsxbw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxbw 0x12345678,%xmm5
+
+// CHECK: pmovsxbw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x20,0xed]
+ pmovsxbw %xmm5,%xmm5
+
+// CHECK: pmovsxbd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxbd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxbd 0x45,%xmm5
+
+// CHECK: pmovsxbd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxbd 0x7eed,%xmm5
+
+// CHECK: pmovsxbd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxbd 0xbabecafe,%xmm5
+
+// CHECK: pmovsxbd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxbd 0x12345678,%xmm5
+
+// CHECK: pmovsxbd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x21,0xed]
+ pmovsxbd %xmm5,%xmm5
+
+// CHECK: pmovsxbq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxbq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxbq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxbq 0x45,%xmm5
+
+// CHECK: pmovsxbq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxbq 0x7eed,%xmm5
+
+// CHECK: pmovsxbq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxbq 0xbabecafe,%xmm5
+
+// CHECK: pmovsxbq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxbq 0x12345678,%xmm5
+
+// CHECK: pmovsxbq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x22,0xed]
+ pmovsxbq %xmm5,%xmm5
+
+// CHECK: pmovsxwd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxwd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxwd 0x45,%xmm5
+
+// CHECK: pmovsxwd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxwd 0x7eed,%xmm5
+
+// CHECK: pmovsxwd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxwd 0xbabecafe,%xmm5
+
+// CHECK: pmovsxwd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxwd 0x12345678,%xmm5
+
+// CHECK: pmovsxwd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x23,0xed]
+ pmovsxwd %xmm5,%xmm5
+
+// CHECK: pmovsxwq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxwq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxwq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxwq 0x45,%xmm5
+
+// CHECK: pmovsxwq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxwq 0x7eed,%xmm5
+
+// CHECK: pmovsxwq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxwq 0xbabecafe,%xmm5
+
+// CHECK: pmovsxwq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxwq 0x12345678,%xmm5
+
+// CHECK: pmovsxwq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x24,0xed]
+ pmovsxwq %xmm5,%xmm5
+
+// CHECK: pmovsxdq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovsxdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovsxdq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0x2d,0x45,0x00,0x00,0x00]
+ pmovsxdq 0x45,%xmm5
+
+// CHECK: pmovsxdq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0x2d,0xed,0x7e,0x00,0x00]
+ pmovsxdq 0x7eed,%xmm5
+
+// CHECK: pmovsxdq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovsxdq 0xbabecafe,%xmm5
+
+// CHECK: pmovsxdq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0x2d,0x78,0x56,0x34,0x12]
+ pmovsxdq 0x12345678,%xmm5
+
+// CHECK: pmovsxdq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x25,0xed]
+ pmovsxdq %xmm5,%xmm5
+
+// CHECK: pmovzxbw 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbw 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxbw 0x45,%xmm5
+
+// CHECK: pmovzxbw 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxbw 0x7eed,%xmm5
+
+// CHECK: pmovzxbw 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxbw 0xbabecafe,%xmm5
+
+// CHECK: pmovzxbw 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxbw 0x12345678,%xmm5
+
+// CHECK: pmovzxbw %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x30,0xed]
+ pmovzxbw %xmm5,%xmm5
+
+// CHECK: pmovzxbd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxbd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxbd 0x45,%xmm5
+
+// CHECK: pmovzxbd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxbd 0x7eed,%xmm5
+
+// CHECK: pmovzxbd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxbd 0xbabecafe,%xmm5
+
+// CHECK: pmovzxbd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxbd 0x12345678,%xmm5
+
+// CHECK: pmovzxbd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x31,0xed]
+ pmovzxbd %xmm5,%xmm5
+
+// CHECK: pmovzxbq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxbq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxbq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxbq 0x45,%xmm5
+
+// CHECK: pmovzxbq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxbq 0x7eed,%xmm5
+
+// CHECK: pmovzxbq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxbq 0xbabecafe,%xmm5
+
+// CHECK: pmovzxbq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxbq 0x12345678,%xmm5
+
+// CHECK: pmovzxbq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x32,0xed]
+ pmovzxbq %xmm5,%xmm5
+
+// CHECK: pmovzxwd 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxwd 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxwd 0x45,%xmm5
+
+// CHECK: pmovzxwd 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxwd 0x7eed,%xmm5
+
+// CHECK: pmovzxwd 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxwd 0xbabecafe,%xmm5
+
+// CHECK: pmovzxwd 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxwd 0x12345678,%xmm5
+
+// CHECK: pmovzxwd %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x33,0xed]
+ pmovzxwd %xmm5,%xmm5
+
+// CHECK: pmovzxwq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxwq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxwq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxwq 0x45,%xmm5
+
+// CHECK: pmovzxwq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxwq 0x7eed,%xmm5
+
+// CHECK: pmovzxwq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxwq 0xbabecafe,%xmm5
+
+// CHECK: pmovzxwq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxwq 0x12345678,%xmm5
+
+// CHECK: pmovzxwq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x34,0xed]
+ pmovzxwq %xmm5,%xmm5
+
+// CHECK: pmovzxdq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmovzxdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmovzxdq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0x2d,0x45,0x00,0x00,0x00]
+ pmovzxdq 0x45,%xmm5
+
+// CHECK: pmovzxdq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0x2d,0xed,0x7e,0x00,0x00]
+ pmovzxdq 0x7eed,%xmm5
+
+// CHECK: pmovzxdq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0x2d,0xfe,0xca,0xbe,0xba]
+ pmovzxdq 0xbabecafe,%xmm5
+
+// CHECK: pmovzxdq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0x2d,0x78,0x56,0x34,0x12]
+ pmovzxdq 0x12345678,%xmm5
+
+// CHECK: pmovzxdq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x35,0xed]
+ pmovzxdq %xmm5,%xmm5
+
+// CHECK: pmuldq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmuldq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmuldq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0x2d,0x45,0x00,0x00,0x00]
+ pmuldq 0x45,%xmm5
+
+// CHECK: pmuldq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0x2d,0xed,0x7e,0x00,0x00]
+ pmuldq 0x7eed,%xmm5
+
+// CHECK: pmuldq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0x2d,0xfe,0xca,0xbe,0xba]
+ pmuldq 0xbabecafe,%xmm5
+
+// CHECK: pmuldq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0x2d,0x78,0x56,0x34,0x12]
+ pmuldq 0x12345678,%xmm5
+
+// CHECK: pmuldq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x28,0xed]
+ pmuldq %xmm5,%xmm5
+
+// CHECK: pmulld 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pmulld 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pmulld 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0x2d,0x45,0x00,0x00,0x00]
+ pmulld 0x45,%xmm5
+
+// CHECK: pmulld 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0x2d,0xed,0x7e,0x00,0x00]
+ pmulld 0x7eed,%xmm5
+
+// CHECK: pmulld 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0x2d,0xfe,0xca,0xbe,0xba]
+ pmulld 0xbabecafe,%xmm5
+
+// CHECK: pmulld 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0x2d,0x78,0x56,0x34,0x12]
+ pmulld 0x12345678,%xmm5
+
+// CHECK: pmulld %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x40,0xed]
+ pmulld %xmm5,%xmm5
+
+// CHECK: ptest 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ ptest 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: ptest 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0x2d,0x45,0x00,0x00,0x00]
+ ptest 0x45,%xmm5
+
+// CHECK: ptest 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0x2d,0xed,0x7e,0x00,0x00]
+ ptest 0x7eed,%xmm5
+
+// CHECK: ptest 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0x2d,0xfe,0xca,0xbe,0xba]
+ ptest 0xbabecafe,%xmm5
+
+// CHECK: ptest 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0x2d,0x78,0x56,0x34,0x12]
+ ptest 0x12345678,%xmm5
+
+// CHECK: ptest %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x17,0xed]
+ ptest %xmm5,%xmm5
+
+// CHECK: pcmpgtq 3735928559(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0xac,0xcb,0xef,0xbe,0xad,0xde]
+ pcmpgtq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+
+// CHECK: pcmpgtq 69, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0x2d,0x45,0x00,0x00,0x00]
+ pcmpgtq 0x45,%xmm5
+
+// CHECK: pcmpgtq 32493, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0x2d,0xed,0x7e,0x00,0x00]
+ pcmpgtq 0x7eed,%xmm5
+
+// CHECK: pcmpgtq 3133065982, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0x2d,0xfe,0xca,0xbe,0xba]
+ pcmpgtq 0xbabecafe,%xmm5
+
+// CHECK: pcmpgtq 305419896, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0x2d,0x78,0x56,0x34,0x12]
+ pcmpgtq 0x12345678,%xmm5
+
+// CHECK: pcmpgtq %xmm5, %xmm5
+// CHECK: encoding: [0x66,0x0f,0x38,0x37,0xed]
+ pcmpgtq %xmm5,%xmm5
diff --git a/test/MC/AsmParser/X86/x86_32-new-encoder.s b/test/MC/AsmParser/X86/x86_32-new-encoder.s
new file mode 100644
index 0000000..6fd0cbb
--- /dev/null
+++ b/test/MC/AsmParser/X86/x86_32-new-encoder.s
@@ -0,0 +1,41 @@
+// RUN: llvm-mc -triple i386-unknown-unknown --show-encoding %s | FileCheck %s
+
+ lfence
+// CHECK: lfence
+// CHECK: encoding: [0x0f,0xae,0xe8]
+ mfence
+// CHECK: mfence
+// CHECK: encoding: [0x0f,0xae,0xf0]
+ monitor
+// CHECK: monitor
+// CHECK: encoding: [0x0f,0x01,0xc8]
+ mwait
+// CHECK: mwait
+// CHECK: encoding: [0x0f,0x01,0xc9]
+
+ vmcall
+// CHECK: vmcall
+// CHECK: encoding: [0x0f,0x01,0xc1]
+ vmlaunch
+// CHECK: vmlaunch
+// CHECK: encoding: [0x0f,0x01,0xc2]
+ vmresume
+// CHECK: vmresume
+// CHECK: encoding: [0x0f,0x01,0xc3]
+ vmxoff
+// CHECK: vmxoff
+// CHECK: encoding: [0x0f,0x01,0xc4]
+ swapgs
+// CHECK: swapgs
+// CHECK: encoding: [0x0f,0x01,0xf8]
+
+rdtscp
+// CHECK: rdtscp
+// CHECK: encoding: [0x0f,0x01,0xf9]
+
+
+// CHECK: movl %eax, 16(%ebp) # encoding: [0x89,0x45,0x10]
+ movl %eax, 16(%ebp)
+// CHECK: movl %eax, -16(%ebp) # encoding: [0x89,0x45,0xf0]
+ movl %eax, -16(%ebp)
+
diff --git a/test/MC/AsmParser/X86/x86_64-new-encoder.s b/test/MC/AsmParser/X86/x86_64-new-encoder.s
new file mode 100644
index 0000000..56ec0b3
--- /dev/null
+++ b/test/MC/AsmParser/X86/x86_64-new-encoder.s
@@ -0,0 +1,26 @@
+// RUN: llvm-mc -triple x86_64-unknown-unknown --show-encoding %s | FileCheck %s
+
+movl foo(%rip), %eax
+// CHECK: movl foo(%rip), %eax
+// CHECK: encoding: [0x8b,0x05,A,A,A,A]
+// CHECK: fixup A - offset: 2, value: foo-4, kind: reloc_riprel_4byte
+
+movb $12, foo(%rip)
+// CHECK: movb $12, foo(%rip)
+// CHECK: encoding: [0xc6,0x05,A,A,A,A,0x0c]
+// CHECK: fixup A - offset: 2, value: foo-5, kind: reloc_riprel_4byte
+
+movw $12, foo(%rip)
+// CHECK: movw $12, foo(%rip)
+// CHECK: encoding: [0x66,0xc7,0x05,A,A,A,A,0x0c,0x00]
+// CHECK: fixup A - offset: 3, value: foo-6, kind: reloc_riprel_4byte
+
+movl $12, foo(%rip)
+// CHECK: movl $12, foo(%rip)
+// CHECK: encoding: [0xc7,0x05,A,A,A,A,0x0c,0x00,0x00,0x00]
+// CHECK: fixup A - offset: 2, value: foo-8, kind: reloc_riprel_4byte
+
+movq $12, foo(%rip)
+// CHECK: movq $12, foo(%rip)
+// CHECK: encoding: [0x48,0xc7,0x05,A,A,A,A,0x0c,0x00,0x00,0x00]
+// CHECK: fixup A - offset: 3, value: foo-8, kind: reloc_riprel_4byte
diff --git a/test/MC/AsmParser/X86/x86_instructions.s b/test/MC/AsmParser/X86/x86_instructions.s
index ed806ee..b558c2e 100644
--- a/test/MC/AsmParser/X86/x86_instructions.s
+++ b/test/MC/AsmParser/X86/x86_instructions.s
@@ -1,5 +1,3 @@
-// FIXME: Switch back to FileCheck once we print actual instructions
-
// RUN: llvm-mc -triple x86_64-unknown-unknown %s | FileCheck %s
// CHECK: subb %al, %al
@@ -16,6 +14,12 @@
movl %eax, 10(%ebp, %ebx, 4)
// CHECK: movl %eax, 10(,%ebx,4)
movl %eax, 10(, %ebx, 4)
+
+// CHECK: movl 0, %eax
+ movl 0, %eax
+// CHECK: movl $0, %eax
+ movl $0, %eax
+
// CHECK: ret
ret
@@ -58,3 +62,84 @@
// FIXME: Check that this matches the correct instruction.
// CHECK: shldl %cl, %eax, %ebx
shldl %cl, %eax, %ebx
+
+// CHECK: shll $2, %eax
+ shll $2, %eax
+
+// CHECK: shll $2, %eax
+ sall $2, %eax
+
+// CHECK: rep
+// CHECK: insb
+ rep;insb
+
+// CHECK: rep
+// CHECK: outsb
+ rep;outsb
+
+// CHECK: rep
+// CHECK: movsb
+ rep;movsb
+
+// CHECK: rep
+// CHECK: lodsb
+ rep;lodsb
+
+// CHECK: rep
+// CHECK: stosb
+ rep;stosb
+
+// NOTE: repz and repe have the same opcode as rep
+// CHECK: rep
+// CHECK: cmpsb
+ repz;cmpsb
+
+// NOTE: repnz has the same opcode as repne
+// CHECK: repne
+// CHECK: cmpsb
+ repnz;cmpsb
+
+// NOTE: repe and repz have the same opcode as rep
+// CHECK: rep
+// CHECK: scasb
+ repe;scasb
+
+// CHECK: repne
+// CHECK: scasb
+ repne;scasb
+
+// CHECK: lock
+// CHECK: cmpxchgb %al, (%ebx)
+ lock;cmpxchgb %al, 0(%ebx)
+
+// CHECK: cs
+// CHECK: movb (%eax), %al
+ cs;movb 0(%eax), %al
+
+// CHECK: ss
+// CHECK: movb (%eax), %al
+ ss;movb 0(%eax), %al
+
+// CHECK: ds
+// CHECK: movb (%eax), %al
+ ds;movb 0(%eax), %al
+
+// CHECK: es
+// CHECK: movb (%eax), %al
+ es;movb 0(%eax), %al
+
+// CHECK: fs
+// CHECK: movb (%eax), %al
+ fs;movb 0(%eax), %al
+
+// CHECK: gs
+// CHECK: movb (%eax), %al
+ gs;movb 0(%eax), %al
+
+// CHECK: fadd %st(0)
+// CHECK: fadd %st(1)
+// CHECK: fadd %st(7)
+
+fadd %st(0)
+fadd %st(1)
+fadd %st(7)
diff --git a/test/MC/AsmParser/X86/x86_operands.s b/test/MC/AsmParser/X86/x86_operands.s
index 433c9bf..edddd1f 100644
--- a/test/MC/AsmParser/X86/x86_operands.s
+++ b/test/MC/AsmParser/X86/x86_operands.s
@@ -5,28 +5,28 @@
# Immediates
# CHECK: addl $1, %eax
addl $1, %eax
-# CHECK: addl $1+2, %eax
+# CHECK: addl $3, %eax
addl $(1+2), %eax
# CHECK: addl $a, %eax
addl $a, %eax
-# CHECK: addl $1+2, %eax
+# CHECK: addl $3, %eax
addl $1 + 2, %eax
# Disambiguation
- # FIXME: Add back when we can match this.
- #addl $1, 4+4
- # FIXME: Add back when we can match this.
- #addl $1, (4+4)
-# CHECK: addl $1, 4+4(%eax)
+# CHECK: addl $1, 8
+ addl $1, 4+4
+# CHECK: addl $1, 8
+ addl $1, (4+4)
+# CHECK: addl $1, 8(%eax)
addl $1, 4+4(%eax)
-# CHECK: addl $1, 4+4(%eax)
+# CHECK: addl $1, 8(%eax)
addl $1, (4+4)(%eax)
# CHECK: addl $1, 8(%eax)
addl $1, 8(%eax)
-# CHECK: addl $1, 0(%eax)
+# CHECK: addl $1, (%eax)
addl $1, (%eax)
-# CHECK: addl $1, 4+4(,%eax)
+# CHECK: addl $1, 8(,%eax)
addl $1, (4+4)(,%eax)
# Indirect Memory Operands
diff --git a/test/MC/AsmParser/conditional_asm.s b/test/MC/AsmParser/conditional_asm.s
index b8a514f..f619ef9 100644
--- a/test/MC/AsmParser/conditional_asm.s
+++ b/test/MC/AsmParser/conditional_asm.s
@@ -1,6 +1,6 @@
# RUN: llvm-mc -triple i386-unknown-unknown %s -I %p | FileCheck %s
-# CHECK: .byte 1+1
+# CHECK: .byte 2
.if 1+2
.if 1-1
.byte 1
diff --git a/test/MC/AsmParser/directive_file.s b/test/MC/AsmParser/directive_file.s
index ec0b954..3160d5c 100644
--- a/test/MC/AsmParser/directive_file.s
+++ b/test/MC/AsmParser/directive_file.s
@@ -1,5 +1,8 @@
-# RUN: llvm-mc -triple i386-unknown-unknown %s
-# FIXME: Actually test the output.
+# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
.file "hello"
.file 1 "world"
+
+# CHECK: .file "hello"
+# CHECK: .file 1 "world"
+
diff --git a/test/MC/AsmParser/exprs.s b/test/MC/AsmParser/exprs.s
index 5fa4a37..62b11c2 100644
--- a/test/MC/AsmParser/exprs.s
+++ b/test/MC/AsmParser/exprs.s
@@ -60,3 +60,4 @@ n:
nop
+ movw $8, (42)+66(%eax)
diff --git a/test/MC/AsmParser/labels.s b/test/MC/AsmParser/labels.s
index 456d61f..3bc7e63 100644
--- a/test/MC/AsmParser/labels.s
+++ b/test/MC/AsmParser/labels.s
@@ -21,7 +21,7 @@ foo:
// CHECK: b$c = 10
"b$c" = 10
// CHECK: addl $10, %eax
- addl "b$c", %eax
+ addl $"b$c", %eax
// CHECK: "a 0" = 11
.set "a 0", 11
diff --git a/test/MC/Disassembler/simple-tests.txt b/test/MC/Disassembler/simple-tests.txt
index 1e3249f..11c077d 100644
--- a/test/MC/Disassembler/simple-tests.txt
+++ b/test/MC/Disassembler/simple-tests.txt
@@ -13,3 +13,32 @@
# CHECK: callq -1234
0xe8 0x2e 0xfb 0xff 0xff
+# CHECK: lfence
+0x0f 0xae 0xe8
+
+# CHECK: mfence
+0x0f 0xae 0xf0
+
+# CHECK: monitor
+0x0f 0x01 0xc8
+
+# CHECK: mwait
+0x0f 0x01 0xc9
+
+# CHECK: vmcall
+0x0f 0x01 0xc1
+
+# CHECK: vmlaunch
+0x0f 0x01 0xc2
+
+# CHECK: vmresume
+0x0f 0x01 0xc3
+
+# CHECK: vmxoff
+0x0f 0x01 0xc4
+
+# CHECK: swapgs
+0x0f 0x01 0xf8
+
+# CHECK: rdtscp
+0x0f 0x01 0xf9 \ No newline at end of file
diff --git a/test/MC/MachO/Darwin/dg.exp b/test/MC/MachO/Darwin/dg.exp
new file mode 100644
index 0000000..0f34b63
--- /dev/null
+++ b/test/MC/MachO/Darwin/dg.exp
@@ -0,0 +1,5 @@
+load_lib llvm.exp
+
+if { [llvm_supports_darwin_and_target X86] } {
+ RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{s}]]
+}
diff --git a/test/MC/MachO/Darwin/x86_32_diff_as.s b/test/MC/MachO/Darwin/x86_32_diff_as.s
new file mode 100644
index 0000000..dd5fb55
--- /dev/null
+++ b/test/MC/MachO/Darwin/x86_32_diff_as.s
@@ -0,0 +1,550 @@
+// Validate that we can assemble this file exactly like the platform
+// assembler.
+//
+// RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown -o %t.mc.o %s
+// RUN: as -arch i386 -o %t.as.o %s
+// RUN: diff %t.mc.o %t.as.o
+
+ movb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ movw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+ movl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+ movl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+ movsbl 0xdeadbeef(%ebx,%ecx,8),%ecx
+ movswl 0xdeadbeef(%ebx,%ecx,8),%ecx
+ movzbl 0xdeadbeef(%ebx,%ecx,8),%ecx
+ movzwl 0xdeadbeef(%ebx,%ecx,8),%ecx
+ pushl 0xdeadbeef(%ebx,%ecx,8)
+ popl 0xdeadbeef(%ebx,%ecx,8)
+ lahf
+ sahf
+ addb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+ addb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ addw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+ addl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+ addl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+ incl 0xdeadbeef(%ebx,%ecx,8)
+ subb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+ subb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ subw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+ subl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+ subl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+ decl 0xdeadbeef(%ebx,%ecx,8)
+ sbbw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+ sbbl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+ sbbl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+ cmpb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+ cmpb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ cmpw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+ cmpl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+ cmpl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+ testb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ testw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+ testl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+ testl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+ andb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+ andb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ andw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+ andl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+ andl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+ orb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+ orb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ orw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+ orl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+ orl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+ xorb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+ xorb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ xorw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+ xorl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+ xorl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+ adcb $0xfe,0xdeadbeef(%ebx,%ecx,8)
+ adcb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ adcw $0x7ace,0xdeadbeef(%ebx,%ecx,8)
+ adcl $0x7afebabe,0xdeadbeef(%ebx,%ecx,8)
+ adcl $0x13572468,0xdeadbeef(%ebx,%ecx,8)
+ negl 0xdeadbeef(%ebx,%ecx,8)
+ notl 0xdeadbeef(%ebx,%ecx,8)
+ cbtw
+ cwtl
+ cwtd
+ cltd
+ mull 0xdeadbeef(%ebx,%ecx,8)
+ imull 0xdeadbeef(%ebx,%ecx,8)
+ divl 0xdeadbeef(%ebx,%ecx,8)
+ idivl 0xdeadbeef(%ebx,%ecx,8)
+ roll $0,0xdeadbeef(%ebx,%ecx,8)
+ rolb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ roll 0xdeadbeef(%ebx,%ecx,8)
+ rorl $0,0xdeadbeef(%ebx,%ecx,8)
+ rorb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ rorl 0xdeadbeef(%ebx,%ecx,8)
+ shll $0,0xdeadbeef(%ebx,%ecx,8)
+ shlb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ shll 0xdeadbeef(%ebx,%ecx,8)
+ shrl $0,0xdeadbeef(%ebx,%ecx,8)
+ shrb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ shrl 0xdeadbeef(%ebx,%ecx,8)
+ sarl $0,0xdeadbeef(%ebx,%ecx,8)
+ sarb $0x7f,0xdeadbeef(%ebx,%ecx,8)
+ sarl 0xdeadbeef(%ebx,%ecx,8)
+ call *%ecx
+ call *0xdeadbeef(%ebx,%ecx,8)
+ call *0xdeadbeef(%ebx,%ecx,8)
+ jmp *0xdeadbeef(%ebx,%ecx,8)
+ jmp *0xdeadbeef(%ebx,%ecx,8)
+ ljmpl *0xdeadbeef(%ebx,%ecx,8)
+ lret
+ leave
+ seto %bl
+ seto 0xdeadbeef(%ebx,%ecx,8)
+ setno %bl
+ setno 0xdeadbeef(%ebx,%ecx,8)
+ setb %bl
+ setb 0xdeadbeef(%ebx,%ecx,8)
+ setae %bl
+ setae 0xdeadbeef(%ebx,%ecx,8)
+ sete %bl
+ sete 0xdeadbeef(%ebx,%ecx,8)
+ setne %bl
+ setne 0xdeadbeef(%ebx,%ecx,8)
+ setbe %bl
+ setbe 0xdeadbeef(%ebx,%ecx,8)
+ seta %bl
+ seta 0xdeadbeef(%ebx,%ecx,8)
+ sets %bl
+ sets 0xdeadbeef(%ebx,%ecx,8)
+ setns %bl
+ setns 0xdeadbeef(%ebx,%ecx,8)
+ setp %bl
+ setp 0xdeadbeef(%ebx,%ecx,8)
+ setnp %bl
+ setnp 0xdeadbeef(%ebx,%ecx,8)
+ setl %bl
+ setl 0xdeadbeef(%ebx,%ecx,8)
+ setge %bl
+ setge 0xdeadbeef(%ebx,%ecx,8)
+ setle %bl
+ setle 0xdeadbeef(%ebx,%ecx,8)
+ setg %bl
+ setg 0xdeadbeef(%ebx,%ecx,8)
+ nopl 0xdeadbeef(%ebx,%ecx,8)
+ nop
+ fldl 0xdeadbeef(%ebx,%ecx,8)
+ fildl 0xdeadbeef(%ebx,%ecx,8)
+ fildll 0xdeadbeef(%ebx,%ecx,8)
+ fldt 0xdeadbeef(%ebx,%ecx,8)
+ fbld 0xdeadbeef(%ebx,%ecx,8)
+ fstl 0xdeadbeef(%ebx,%ecx,8)
+ fistl 0xdeadbeef(%ebx,%ecx,8)
+ fstpl 0xdeadbeef(%ebx,%ecx,8)
+ fistpl 0xdeadbeef(%ebx,%ecx,8)
+ fistpll 0xdeadbeef(%ebx,%ecx,8)
+ fstpt 0xdeadbeef(%ebx,%ecx,8)
+ fbstp 0xdeadbeef(%ebx,%ecx,8)
+ ficoml 0xdeadbeef(%ebx,%ecx,8)
+ ficompl 0xdeadbeef(%ebx,%ecx,8)
+ fucompp
+ ftst
+ fld1
+ fldz
+ faddl 0xdeadbeef(%ebx,%ecx,8)
+ fiaddl 0xdeadbeef(%ebx,%ecx,8)
+ fsubl 0xdeadbeef(%ebx,%ecx,8)
+ fisubl 0xdeadbeef(%ebx,%ecx,8)
+ fsubrl 0xdeadbeef(%ebx,%ecx,8)
+ fisubrl 0xdeadbeef(%ebx,%ecx,8)
+ fmull 0xdeadbeef(%ebx,%ecx,8)
+ fimull 0xdeadbeef(%ebx,%ecx,8)
+ fdivl 0xdeadbeef(%ebx,%ecx,8)
+ fidivl 0xdeadbeef(%ebx,%ecx,8)
+ fdivrl 0xdeadbeef(%ebx,%ecx,8)
+ fidivrl 0xdeadbeef(%ebx,%ecx,8)
+ fsqrt
+ fsin
+ fcos
+ fchs
+ fabs
+ fldcw 0xdeadbeef(%ebx,%ecx,8)
+ fnstcw 0xdeadbeef(%ebx,%ecx,8)
+ rdtsc
+ sysenter
+ sysexit
+ ud2
+ movnti %ecx,0xdeadbeef(%ebx,%ecx,8)
+ clflush 0xdeadbeef(%ebx,%ecx,8)
+ emms
+ movd %ecx,%mm3
+ movd 0xdeadbeef(%ebx,%ecx,8),%mm3
+ movd %ecx,%xmm5
+ movd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movd %xmm5,%ecx
+ movd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movq 0xdeadbeef(%ebx,%ecx,8),%mm3
+ movq %mm3,%mm3
+ movq %mm3,%mm3
+ movq %xmm5,%xmm5
+ movq %xmm5,%xmm5
+ packssdw %mm3,%mm3
+ packssdw %xmm5,%xmm5
+ packsswb %mm3,%mm3
+ packsswb %xmm5,%xmm5
+ packuswb %mm3,%mm3
+ packuswb %xmm5,%xmm5
+ paddb %mm3,%mm3
+ paddb %xmm5,%xmm5
+ paddw %mm3,%mm3
+ paddw %xmm5,%xmm5
+ paddd %mm3,%mm3
+ paddd %xmm5,%xmm5
+ paddq %mm3,%mm3
+ paddq %xmm5,%xmm5
+ paddsb %mm3,%mm3
+ paddsb %xmm5,%xmm5
+ paddsw %mm3,%mm3
+ paddsw %xmm5,%xmm5
+ paddusb %mm3,%mm3
+ paddusb %xmm5,%xmm5
+ paddusw %mm3,%mm3
+ paddusw %xmm5,%xmm5
+ pand %mm3,%mm3
+ pand %xmm5,%xmm5
+ pandn %mm3,%mm3
+ pandn %xmm5,%xmm5
+ pcmpeqb %mm3,%mm3
+ pcmpeqb %xmm5,%xmm5
+ pcmpeqw %mm3,%mm3
+ pcmpeqw %xmm5,%xmm5
+ pcmpeqd %mm3,%mm3
+ pcmpeqd %xmm5,%xmm5
+ pcmpgtb %mm3,%mm3
+ pcmpgtb %xmm5,%xmm5
+ pcmpgtw %mm3,%mm3
+ pcmpgtw %xmm5,%xmm5
+ pcmpgtd %mm3,%mm3
+ pcmpgtd %xmm5,%xmm5
+ pmaddwd %mm3,%mm3
+ pmaddwd %xmm5,%xmm5
+ pmulhw %mm3,%mm3
+ pmulhw %xmm5,%xmm5
+ pmullw %mm3,%mm3
+ pmullw %xmm5,%xmm5
+ por %mm3,%mm3
+ por %xmm5,%xmm5
+ psllw %mm3,%mm3
+ psllw %xmm5,%xmm5
+ psllw $0x7f,%mm3
+ psllw $0x7f,%xmm5
+ pslld %mm3,%mm3
+ pslld %xmm5,%xmm5
+ pslld $0x7f,%mm3
+ pslld $0x7f,%xmm5
+ psllq %mm3,%mm3
+ psllq %xmm5,%xmm5
+ psllq $0x7f,%mm3
+ psllq $0x7f,%xmm5
+ psraw %mm3,%mm3
+ psraw %xmm5,%xmm5
+ psraw $0x7f,%mm3
+ psraw $0x7f,%xmm5
+ psrad %mm3,%mm3
+ psrad %xmm5,%xmm5
+ psrad $0x7f,%mm3
+ psrad $0x7f,%xmm5
+ psrlw %mm3,%mm3
+ psrlw %xmm5,%xmm5
+ psrlw $0x7f,%mm3
+ psrlw $0x7f,%xmm5
+ psrld %mm3,%mm3
+ psrld %xmm5,%xmm5
+ psrld $0x7f,%mm3
+ psrld $0x7f,%xmm5
+ psrlq %mm3,%mm3
+ psrlq %xmm5,%xmm5
+ psrlq $0x7f,%mm3
+ psrlq $0x7f,%xmm5
+ psubb %mm3,%mm3
+ psubb %xmm5,%xmm5
+ psubw %mm3,%mm3
+ psubw %xmm5,%xmm5
+ psubd %mm3,%mm3
+ psubd %xmm5,%xmm5
+ psubq %mm3,%mm3
+ psubq %xmm5,%xmm5
+ psubsb %mm3,%mm3
+ psubsb %xmm5,%xmm5
+ psubsw %mm3,%mm3
+ psubsw %xmm5,%xmm5
+ psubusb %mm3,%mm3
+ psubusb %xmm5,%xmm5
+ psubusw %mm3,%mm3
+ psubusw %xmm5,%xmm5
+ punpckhbw %mm3,%mm3
+ punpckhbw %xmm5,%xmm5
+ punpckhwd %mm3,%mm3
+ punpckhwd %xmm5,%xmm5
+ punpckhdq %mm3,%mm3
+ punpckhdq %xmm5,%xmm5
+ punpcklbw %mm3,%mm3
+ punpcklbw %xmm5,%xmm5
+ punpcklwd %mm3,%mm3
+ punpcklwd %xmm5,%xmm5
+ punpckldq %mm3,%mm3
+ punpckldq %xmm5,%xmm5
+ pxor %mm3,%mm3
+ pxor %xmm5,%xmm5
+ addps %xmm5,%xmm5
+ addss %xmm5,%xmm5
+ andnps %xmm5,%xmm5
+ andps %xmm5,%xmm5
+ cvtpi2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ cvtpi2ps %mm3,%xmm5
+ cvtps2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+ cvtps2pi %xmm5,%mm3
+ cvtsi2ss %ecx,%xmm5
+ cvtsi2ss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ cvttps2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+ cvttps2pi %xmm5,%mm3
+ cvttss2si 0xdeadbeef(%ebx,%ecx,8),%ecx
+ cvttss2si %xmm5,%ecx
+ divps %xmm5,%xmm5
+ divss %xmm5,%xmm5
+ ldmxcsr 0xdeadbeef(%ebx,%ecx,8)
+ maskmovq %mm3,%mm3
+ maxps %xmm5,%xmm5
+ maxss %xmm5,%xmm5
+ minps %xmm5,%xmm5
+ minss %xmm5,%xmm5
+ movaps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movaps %xmm5,%xmm5
+ movaps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movaps %xmm5,%xmm5
+ movhlps %xmm5,%xmm5
+ movhps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movlhps %xmm5,%xmm5
+ movlps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movmskps %xmm5,%ecx
+ movntps %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movntq %mm3,0xdeadbeef(%ebx,%ecx,8)
+ movntdq %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movss %xmm5,%xmm5
+ movss %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movss %xmm5,%xmm5
+ movups 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movups %xmm5,%xmm5
+ movups %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movups %xmm5,%xmm5
+ mulps %xmm5,%xmm5
+ mulss %xmm5,%xmm5
+ orps %xmm5,%xmm5
+ pavgb %mm3,%mm3
+ pavgb %xmm5,%xmm5
+ pavgw %mm3,%mm3
+ pavgw %xmm5,%xmm5
+ pmaxsw %mm3,%mm3
+ pmaxsw %xmm5,%xmm5
+ pmaxub %mm3,%mm3
+ pmaxub %xmm5,%xmm5
+ pminsw %mm3,%mm3
+ pminsw %xmm5,%xmm5
+ pminub %mm3,%mm3
+ pminub %xmm5,%xmm5
+ pmovmskb %mm3,%ecx
+ pmovmskb %xmm5,%ecx
+ pmulhuw %mm3,%mm3
+ pmulhuw %xmm5,%xmm5
+ prefetchnta 0xdeadbeef(%ebx,%ecx,8)
+ prefetcht0 0xdeadbeef(%ebx,%ecx,8)
+ prefetcht1 0xdeadbeef(%ebx,%ecx,8)
+ prefetcht2 0xdeadbeef(%ebx,%ecx,8)
+ psadbw %mm3,%mm3
+ psadbw %xmm5,%xmm5
+ rcpps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ rcpps %xmm5,%xmm5
+ rcpss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ rcpss %xmm5,%xmm5
+ rsqrtps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ rsqrtps %xmm5,%xmm5
+ rsqrtss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ rsqrtss %xmm5,%xmm5
+ sqrtps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ sqrtps %xmm5,%xmm5
+ sqrtss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ sqrtss %xmm5,%xmm5
+ stmxcsr 0xdeadbeef(%ebx,%ecx,8)
+ subps %xmm5,%xmm5
+ subss %xmm5,%xmm5
+ ucomiss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ ucomiss %xmm5,%xmm5
+ unpckhps %xmm5,%xmm5
+ unpcklps %xmm5,%xmm5
+ xorps %xmm5,%xmm5
+ addpd %xmm5,%xmm5
+ addsd %xmm5,%xmm5
+ andnpd %xmm5,%xmm5
+ andpd %xmm5,%xmm5
+ comisd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ comisd %xmm5,%xmm5
+ cvtpi2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ cvtpi2pd %mm3,%xmm5
+ cvtsi2sd %ecx,%xmm5
+ cvtsi2sd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ divpd %xmm5,%xmm5
+ divsd %xmm5,%xmm5
+ maxpd %xmm5,%xmm5
+ maxsd %xmm5,%xmm5
+ minpd %xmm5,%xmm5
+ minsd %xmm5,%xmm5
+ movapd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movapd %xmm5,%xmm5
+ movapd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movapd %xmm5,%xmm5
+ movhpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movlpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movmskpd %xmm5,%ecx
+ movntpd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movsd %xmm5,%xmm5
+ movsd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movsd %xmm5,%xmm5
+ movupd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movupd %xmm5,%xmm5
+ movupd %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movupd %xmm5,%xmm5
+ mulpd %xmm5,%xmm5
+ mulsd %xmm5,%xmm5
+ orpd %xmm5,%xmm5
+ sqrtpd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ sqrtpd %xmm5,%xmm5
+ sqrtsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ sqrtsd %xmm5,%xmm5
+ subpd %xmm5,%xmm5
+ subsd %xmm5,%xmm5
+ ucomisd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ ucomisd %xmm5,%xmm5
+ unpckhpd %xmm5,%xmm5
+ unpcklpd %xmm5,%xmm5
+ xorpd %xmm5,%xmm5
+ cvtdq2pd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ cvtdq2pd %xmm5,%xmm5
+ cvtpd2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ cvtpd2dq %xmm5,%xmm5
+ cvtdq2ps 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ cvtdq2ps %xmm5,%xmm5
+ cvtpd2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+ cvtpd2pi %xmm5,%mm3
+ cvtps2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ cvtps2dq %xmm5,%xmm5
+ cvtsd2ss 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ cvtsd2ss %xmm5,%xmm5
+ cvtss2sd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ cvtss2sd %xmm5,%xmm5
+ cvttpd2pi 0xdeadbeef(%ebx,%ecx,8),%mm3
+ cvttpd2pi %xmm5,%mm3
+ cvttsd2si 0xdeadbeef(%ebx,%ecx,8),%ecx
+ cvttsd2si %xmm5,%ecx
+ maskmovdqu %xmm5,%xmm5
+ movdqa 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movdqa %xmm5,%xmm5
+ movdqa %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movdqa %xmm5,%xmm5
+ movdqu 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movdqu %xmm5,0xdeadbeef(%ebx,%ecx,8)
+ movdq2q %xmm5,%mm3
+ movq2dq %mm3,%xmm5
+ pmuludq %mm3,%mm3
+ pmuludq %xmm5,%xmm5
+ pslldq $0x7f,%xmm5
+ psrldq $0x7f,%xmm5
+ punpckhqdq %xmm5,%xmm5
+ punpcklqdq %xmm5,%xmm5
+ addsubpd %xmm5,%xmm5
+ addsubps %xmm5,%xmm5
+ haddpd %xmm5,%xmm5
+ haddps %xmm5,%xmm5
+ hsubpd %xmm5,%xmm5
+ hsubps %xmm5,%xmm5
+ lddqu 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movddup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movddup %xmm5,%xmm5
+ movshdup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movshdup %xmm5,%xmm5
+ movsldup 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ movsldup %xmm5,%xmm5
+ phaddw %mm3,%mm3
+ phaddw %xmm5,%xmm5
+ phaddd %mm3,%mm3
+ phaddd %xmm5,%xmm5
+ phaddsw %mm3,%mm3
+ phaddsw %xmm5,%xmm5
+ phsubw %mm3,%mm3
+ phsubw %xmm5,%xmm5
+ phsubd %mm3,%mm3
+ phsubd %xmm5,%xmm5
+ phsubsw %mm3,%mm3
+ phsubsw %xmm5,%xmm5
+ pmaddubsw %mm3,%mm3
+ pmaddubsw %xmm5,%xmm5
+ pmulhrsw %mm3,%mm3
+ pmulhrsw %xmm5,%xmm5
+ pshufb %mm3,%mm3
+ pshufb %xmm5,%xmm5
+ psignb %mm3,%mm3
+ psignb %xmm5,%xmm5
+ psignw %mm3,%mm3
+ psignw %xmm5,%xmm5
+ psignd %mm3,%mm3
+ psignd %xmm5,%xmm5
+ pabsb 0xdeadbeef(%ebx,%ecx,8),%mm3
+ pabsb %mm3,%mm3
+ pabsb 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pabsb %xmm5,%xmm5
+ pabsw 0xdeadbeef(%ebx,%ecx,8),%mm3
+ pabsw %mm3,%mm3
+ pabsw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pabsw %xmm5,%xmm5
+ pabsd 0xdeadbeef(%ebx,%ecx,8),%mm3
+ pabsd %mm3,%mm3
+ pabsd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pabsd %xmm5,%xmm5
+ femms
+ packusdw %xmm5,%xmm5
+ pcmpeqq %xmm5,%xmm5
+ phminposuw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ phminposuw %xmm5,%xmm5
+ pmaxsb %xmm5,%xmm5
+ pmaxsd %xmm5,%xmm5
+ pmaxud %xmm5,%xmm5
+ pmaxuw %xmm5,%xmm5
+ pminsb %xmm5,%xmm5
+ pminsd %xmm5,%xmm5
+ pminud %xmm5,%xmm5
+ pminuw %xmm5,%xmm5
+ pmovsxbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovsxbw %xmm5,%xmm5
+ pmovsxbd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovsxbd %xmm5,%xmm5
+ pmovsxbq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovsxbq %xmm5,%xmm5
+ pmovsxwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovsxwd %xmm5,%xmm5
+ pmovsxwq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovsxwq %xmm5,%xmm5
+ pmovsxdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovsxdq %xmm5,%xmm5
+ pmovzxbw 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovzxbw %xmm5,%xmm5
+ pmovzxbd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovzxbd %xmm5,%xmm5
+ pmovzxbq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovzxbq %xmm5,%xmm5
+ pmovzxwd 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovzxwd %xmm5,%xmm5
+ pmovzxwq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovzxwq %xmm5,%xmm5
+ pmovzxdq 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ pmovzxdq %xmm5,%xmm5
+ pmuldq %xmm5,%xmm5
+ pmulld %xmm5,%xmm5
+ ptest 0xdeadbeef(%ebx,%ecx,8),%xmm5
+ ptest %xmm5,%xmm5
+ pcmpgtq %xmm5,%xmm5
diff --git a/test/MC/MachO/section-flags.s b/test/MC/MachO/section-flags.s
new file mode 100644
index 0000000..8ac1bbf
--- /dev/null
+++ b/test/MC/MachO/section-flags.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump | FileCheck %s
+//
+// CHECK: # Section 0
+// CHECK: 'section_name', '__text
+// CHECK: 'flags', 0x80000000
+// CHECK: # Section 1
+// CHECK: 'section_name', '__data
+// CHECK: 'flags', 0x400
+
+ .text
+
+ .data
+f0:
+ movl $0, %eax
diff --git a/test/Other/2007-06-05-PassID.ll b/test/Other/2007-06-05-PassID.ll
index 7a03544..2554b8b 100644
--- a/test/Other/2007-06-05-PassID.ll
+++ b/test/Other/2007-06-05-PassID.ll
@@ -1,4 +1,4 @@
-;RUN: opt < %s -analyze -dot-cfg-only -disable-output 2>/dev/null
+;RUN: opt < %s -analyze -dot-cfg-only 2>/dev/null
;PR 1497
define void @foo() {
diff --git a/test/Other/2007-06-28-PassManager.ll b/test/Other/2007-06-28-PassManager.ll
index f162a40..0ed2759 100644
--- a/test/Other/2007-06-28-PassManager.ll
+++ b/test/Other/2007-06-28-PassManager.ll
@@ -1,6 +1,6 @@
-; RUN: opt < %s -analyze -inline -disable-output
+; RUN: opt < %s -analyze -inline
; PR1526
-; RUN: opt < %s -analyze -indvars -disable-output
+; RUN: opt < %s -analyze -indvars
; PR1539
define i32 @test1() {
ret i32 0
diff --git a/test/Other/constant-fold-gep.ll b/test/Other/constant-fold-gep.ll
new file mode 100644
index 0000000..2888b3d
--- /dev/null
+++ b/test/Other/constant-fold-gep.ll
@@ -0,0 +1,428 @@
+; "PLAIN" - No optimizations. This tests the target-independent
+; constant folder.
+; RUN: opt -S -o - < %s | FileCheck --check-prefix=PLAIN %s
+
+; "OPT" - Optimizations but no targetdata. This tests target-independent
+; folding in the optimizers.
+; RUN: opt -S -o - -instcombine -globalopt < %s | FileCheck --check-prefix=OPT %s
+
+; "TO" - Optimizations and targetdata. This tests target-dependent
+; folding in the optimizers.
+; RUN: opt -S -o - -instcombine -globalopt -default-data-layout="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" < %s | FileCheck --check-prefix=TO %s
+
+; "SCEV" - ScalarEvolution but no targetdata.
+; RUN: opt -analyze -scalar-evolution < %s | FileCheck --check-prefix=SCEV %s
+
+; ScalarEvolution with targetdata isn't interesting on these testcases
+; because ScalarEvolution doesn't attempt to duplicate all of instcombine's
+; and the constant folders' folding.
+
+; PLAIN: %0 = type { i1, double }
+; PLAIN: %1 = type { double, float, double, double }
+; PLAIN: %2 = type { i1, i1* }
+; PLAIN: %3 = type { i64, i64 }
+; OPT: %0 = type { i1, double }
+; OPT: %1 = type { double, float, double, double }
+; OPT: %2 = type { i1, i1* }
+; OPT: %3 = type { i64, i64 }
+
+; The automatic constant folder in opt does not have targetdata access, so
+; it can't fold gep arithmetic, in general. However, the constant folder run
+; from instcombine and global opt can use targetdata.
+
+; PLAIN: @G8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
+; PLAIN: @G1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
+; PLAIN: @F8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
+; PLAIN: @F1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
+; PLAIN: @H8 = global i8* getelementptr (i8* null, i32 -1)
+; PLAIN: @H1 = global i1* getelementptr (i1* null, i32 -1)
+; OPT: @G8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
+; OPT: @G1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
+; OPT: @F8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
+; OPT: @F1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
+; OPT: @H8 = global i8* getelementptr (i8* null, i32 -1)
+; OPT: @H1 = global i1* getelementptr (i1* null, i32 -1)
+; TO: @G8 = global i8* null
+; TO: @G1 = global i1* null
+; TO: @F8 = global i8* inttoptr (i64 -1 to i8*)
+; TO: @F1 = global i1* inttoptr (i64 -1 to i1*)
+; TO: @H8 = global i8* inttoptr (i64 -1 to i8*)
+; TO: @H1 = global i1* inttoptr (i64 -1 to i1*)
+
+@G8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
+@G1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
+@F8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
+@F1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
+@H8 = global i8* getelementptr (i8* inttoptr (i32 0 to i8*), i32 -1)
+@H1 = global i1* getelementptr (i1* inttoptr (i32 0 to i1*), i32 -1)
+
+; The target-independent folder should be able to do some clever
+; simplifications on sizeof, alignof, and offsetof expressions. The
+; target-dependent folder should fold these down to constants.
+
+; PLAIN: @a = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310)
+; PLAIN: @b = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; PLAIN: @c = constant i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
+; PLAIN: @d = constant i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11)
+; PLAIN: @e = constant i64 ptrtoint (double* getelementptr (%1* null, i64 0, i32 2) to i64)
+; PLAIN: @f = constant i64 1
+; PLAIN: @g = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; PLAIN: @h = constant i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
+; PLAIN: @i = constant i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
+; OPT: @a = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310)
+; OPT: @b = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; OPT: @c = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
+; OPT: @d = constant i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11)
+; OPT: @e = constant i64 ptrtoint (double* getelementptr (%1* null, i64 0, i32 2) to i64)
+; OPT: @f = constant i64 1
+; OPT: @g = constant i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; OPT: @h = constant i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
+; OPT: @i = constant i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
+; TO: @a = constant i64 18480
+; TO: @b = constant i64 8
+; TO: @c = constant i64 16
+; TO: @d = constant i64 88
+; TO: @e = constant i64 16
+; TO: @f = constant i64 1
+; TO: @g = constant i64 8
+; TO: @h = constant i64 8
+; TO: @i = constant i64 8
+
+@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}* null, i64 11) to i64), i64 5))
+@b = constant i64 ptrtoint ([13 x double]* getelementptr ({i1, [13 x double]}* null, i64 0, i32 1) to i64)
+@c = constant i64 ptrtoint (double* getelementptr ({double, double, double, double}* null, i64 0, i32 2) to i64)
+@d = constant i64 ptrtoint (double* getelementptr ([13 x double]* null, i64 0, i32 11) to i64)
+@e = constant i64 ptrtoint (double* getelementptr ({double, float, double, double}* null, i64 0, i32 2) to i64)
+@f = constant i64 ptrtoint (<{ i16, i128 }>* getelementptr ({i1, <{ i16, i128 }>}* null, i64 0, i32 1) to i64)
+@g = constant i64 ptrtoint ({double, double}* getelementptr ({i1, {double, double}}* null, i64 0, i32 1) to i64)
+@h = constant i64 ptrtoint (double** getelementptr (double** null, i64 1) to i64)
+@i = constant i64 ptrtoint (double** getelementptr ({i1, double*}* null, i64 0, i32 1) to i64)
+
+; The target-dependent folder should cast GEP indices to integer-sized pointers.
+
+; PLAIN: @M = constant i64* getelementptr (i64* null, i32 1)
+; PLAIN: @N = constant i64* getelementptr (%3* null, i32 0, i32 1)
+; PLAIN: @O = constant i64* getelementptr ([2 x i64]* null, i32 0, i32 1)
+; OPT: @M = constant i64* getelementptr (i64* null, i32 1)
+; OPT: @N = constant i64* getelementptr (%3* null, i32 0, i32 1)
+; OPT: @O = constant i64* getelementptr ([2 x i64]* null, i32 0, i32 1)
+; TO: @M = constant i64* inttoptr (i64 8 to i64*)
+; TO: @N = constant i64* inttoptr (i64 8 to i64*)
+; TO: @O = constant i64* inttoptr (i64 8 to i64*)
+
+@M = constant i64* getelementptr (i64 *null, i32 1)
+@N = constant i64* getelementptr ({ i64, i64 } *null, i32 0, i32 1)
+@O = constant i64* getelementptr ([2 x i64] *null, i32 0, i32 1)
+
+; Duplicate all of the above as function return values rather than
+; global initializers.
+
+; PLAIN: define i8* @goo8() nounwind {
+; PLAIN: %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1) to i8*
+; PLAIN: ret i8* %t
+; PLAIN: }
+; PLAIN: define i1* @goo1() nounwind {
+; PLAIN: %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1) to i1*
+; PLAIN: ret i1* %t
+; PLAIN: }
+; PLAIN: define i8* @foo8() nounwind {
+; PLAIN: %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2) to i8*
+; PLAIN: ret i8* %t
+; PLAIN: }
+; PLAIN: define i1* @foo1() nounwind {
+; PLAIN: %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2) to i1*
+; PLAIN: ret i1* %t
+; PLAIN: }
+; PLAIN: define i8* @hoo8() nounwind {
+; PLAIN: %t = bitcast i8* getelementptr (i8* null, i32 -1) to i8*
+; PLAIN: ret i8* %t
+; PLAIN: }
+; PLAIN: define i1* @hoo1() nounwind {
+; PLAIN: %t = bitcast i1* getelementptr (i1* null, i32 -1) to i1*
+; PLAIN: ret i1* %t
+; PLAIN: }
+; OPT: define i8* @goo8() nounwind {
+; OPT: ret i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
+; OPT: }
+; OPT: define i1* @goo1() nounwind {
+; OPT: ret i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
+; OPT: }
+; OPT: define i8* @foo8() nounwind {
+; OPT: ret i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
+; OPT: }
+; OPT: define i1* @foo1() nounwind {
+; OPT: ret i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
+; OPT: }
+; OPT: define i8* @hoo8() nounwind {
+; OPT: ret i8* getelementptr (i8* null, i32 -1)
+; OPT: }
+; OPT: define i1* @hoo1() nounwind {
+; OPT: ret i1* getelementptr (i1* null, i32 -1)
+; OPT: }
+; TO: define i8* @goo8() nounwind {
+; TO: ret i8* null
+; TO: }
+; TO: define i1* @goo1() nounwind {
+; TO: ret i1* null
+; TO: }
+; TO: define i8* @foo8() nounwind {
+; TO: ret i8* inttoptr (i64 -1 to i8*)
+; TO: }
+; TO: define i1* @foo1() nounwind {
+; TO: ret i1* inttoptr (i64 -1 to i1*)
+; TO: }
+; TO: define i8* @hoo8() nounwind {
+; TO: ret i8* inttoptr (i64 -1 to i8*)
+; TO: }
+; TO: define i1* @hoo1() nounwind {
+; TO: ret i1* inttoptr (i64 -1 to i1*)
+; TO: }
+; SCEV: Classifying expressions for: @goo8
+; SCEV: %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1) to i8*
+; SCEV: --> ((-1 * sizeof(i8)) + inttoptr (i32 1 to i8*))
+; SCEV: Classifying expressions for: @goo1
+; SCEV: %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1) to i1*
+; SCEV: --> ((-1 * sizeof(i1)) + inttoptr (i32 1 to i1*))
+; SCEV: Classifying expressions for: @foo8
+; SCEV: %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2) to i8*
+; SCEV: --> ((-2 * sizeof(i8)) + inttoptr (i32 1 to i8*))
+; SCEV: Classifying expressions for: @foo1
+; SCEV: %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2) to i1*
+; SCEV: --> ((-2 * sizeof(i1)) + inttoptr (i32 1 to i1*))
+; SCEV: Classifying expressions for: @hoo8
+; SCEV: --> (-1 * sizeof(i8))
+; SCEV: Classifying expressions for: @hoo1
+; SCEV: --> (-1 * sizeof(i1))
+
+define i8* @goo8() nounwind {
+ %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1) to i8*
+ ret i8* %t
+}
+define i1* @goo1() nounwind {
+ %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1) to i1*
+ ret i1* %t
+}
+define i8* @foo8() nounwind {
+ %t = bitcast i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2) to i8*
+ ret i8* %t
+}
+define i1* @foo1() nounwind {
+ %t = bitcast i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2) to i1*
+ ret i1* %t
+}
+define i8* @hoo8() nounwind {
+ %t = bitcast i8* getelementptr (i8* inttoptr (i32 0 to i8*), i32 -1) to i8*
+ ret i8* %t
+}
+define i1* @hoo1() nounwind {
+ %t = bitcast i1* getelementptr (i1* inttoptr (i32 0 to i1*), i32 -1) to i1*
+ ret i1* %t
+}
+
+; PLAIN: define i64 @fa() nounwind {
+; PLAIN: %t = bitcast i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310) to i64
+; PLAIN: ret i64 %t
+; PLAIN: }
+; PLAIN: define i64 @fb() nounwind {
+; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
+; PLAIN: ret i64 %t
+; PLAIN: }
+; PLAIN: define i64 @fc() nounwind {
+; PLAIN: %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2) to i64
+; PLAIN: ret i64 %t
+; PLAIN: }
+; PLAIN: define i64 @fd() nounwind {
+; PLAIN: %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11) to i64
+; PLAIN: ret i64 %t
+; PLAIN: }
+; PLAIN: define i64 @fe() nounwind {
+; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr (%1* null, i64 0, i32 2) to i64) to i64
+; PLAIN: ret i64 %t
+; PLAIN: }
+; PLAIN: define i64 @ff() nounwind {
+; PLAIN: %t = bitcast i64 1 to i64
+; PLAIN: ret i64 %t
+; PLAIN: }
+; PLAIN: define i64 @fg() nounwind {
+; PLAIN: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; PLAIN: ret i64 %t
+; PLAIN: }
+; PLAIN: define i64 @fh() nounwind {
+; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
+; PLAIN: ret i64 %t
+; PLAIN: }
+; PLAIN: define i64 @fi() nounwind {
+; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
+; PLAIN: ret i64 %t
+; PLAIN: }
+; OPT: define i64 @fa() nounwind {
+; OPT: ret i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310)
+; OPT: }
+; OPT: define i64 @fb() nounwind {
+; OPT: ret i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; OPT: }
+; OPT: define i64 @fc() nounwind {
+; OPT: ret i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2)
+; OPT: }
+; OPT: define i64 @fd() nounwind {
+; OPT: ret i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11)
+; OPT: }
+; OPT: define i64 @fe() nounwind {
+; OPT: ret i64 ptrtoint (double* getelementptr (%1* null, i64 0, i32 2) to i64)
+; OPT: }
+; OPT: define i64 @ff() nounwind {
+; OPT: ret i64 1
+; OPT: }
+; OPT: define i64 @fg() nounwind {
+; OPT: ret i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; OPT: }
+; OPT: define i64 @fh() nounwind {
+; OPT: ret i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
+; OPT: }
+; OPT: define i64 @fi() nounwind {
+; OPT: ret i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
+; OPT: }
+; TO: define i64 @fa() nounwind {
+; TO: ret i64 18480
+; TO: }
+; TO: define i64 @fb() nounwind {
+; TO: ret i64 8
+; TO: }
+; TO: define i64 @fc() nounwind {
+; TO: ret i64 16
+; TO: }
+; TO: define i64 @fd() nounwind {
+; TO: ret i64 88
+; TO: }
+; TO: define i64 @fe() nounwind {
+; TO: ret i64 16
+; TO: }
+; TO: define i64 @ff() nounwind {
+; TO: ret i64 1
+; TO: }
+; TO: define i64 @fg() nounwind {
+; TO: ret i64 8
+; TO: }
+; TO: define i64 @fh() nounwind {
+; TO: ret i64 8
+; TO: }
+; TO: define i64 @fi() nounwind {
+; TO: ret i64 8
+; TO: }
+; SCEV: Classifying expressions for: @fa
+; SCEV: %t = bitcast i64 mul (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2310) to i64
+; SCEV: --> (2310 * sizeof(double))
+; SCEV: Classifying expressions for: @fb
+; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64) to i64
+; SCEV: --> alignof(double)
+; SCEV: Classifying expressions for: @fc
+; SCEV: %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 2) to i64
+; SCEV: --> (2 * sizeof(double))
+; SCEV: Classifying expressions for: @fd
+; SCEV: %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double* null, i32 1) to i64), i64 11) to i64
+; SCEV: --> (11 * sizeof(double))
+; SCEV: Classifying expressions for: @fe
+; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr (%1* null, i64 0, i32 2) to i64) to i64
+; SCEV: --> offsetof({ double, float, double, double }, 2)
+; SCEV: Classifying expressions for: @ff
+; SCEV: %t = bitcast i64 1 to i64
+; SCEV: --> 1
+; SCEV: Classifying expressions for: @fg
+; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr (%0* null, i64 0, i32 1) to i64)
+; SCEV: --> alignof(double)
+; SCEV: Classifying expressions for: @fh
+; SCEV: %t = bitcast i64 ptrtoint (i1** getelementptr (i1** null, i32 1) to i64)
+; SCEV: --> sizeof(i1*)
+; SCEV: Classifying expressions for: @fi
+; SCEV: %t = bitcast i64 ptrtoint (i1** getelementptr (%2* null, i64 0, i32 1) to i64)
+; SCEV: --> alignof(i1*)
+
+define i64 @fa() nounwind {
+ %t = bitcast i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}* null, i64 11) to i64), i64 5)) to i64
+ ret i64 %t
+}
+define i64 @fb() nounwind {
+ %t = bitcast i64 ptrtoint ([13 x double]* getelementptr ({i1, [13 x double]}* null, i64 0, i32 1) to i64) to i64
+ ret i64 %t
+}
+define i64 @fc() nounwind {
+ %t = bitcast i64 ptrtoint (double* getelementptr ({double, double, double, double}* null, i64 0, i32 2) to i64) to i64
+ ret i64 %t
+}
+define i64 @fd() nounwind {
+ %t = bitcast i64 ptrtoint (double* getelementptr ([13 x double]* null, i64 0, i32 11) to i64) to i64
+ ret i64 %t
+}
+define i64 @fe() nounwind {
+ %t = bitcast i64 ptrtoint (double* getelementptr ({double, float, double, double}* null, i64 0, i32 2) to i64) to i64
+ ret i64 %t
+}
+define i64 @ff() nounwind {
+ %t = bitcast i64 ptrtoint (<{ i16, i128 }>* getelementptr ({i1, <{ i16, i128 }>}* null, i64 0, i32 1) to i64) to i64
+ ret i64 %t
+}
+define i64 @fg() nounwind {
+ %t = bitcast i64 ptrtoint ({double, double}* getelementptr ({i1, {double, double}}* null, i64 0, i32 1) to i64) to i64
+ ret i64 %t
+}
+define i64 @fh() nounwind {
+ %t = bitcast i64 ptrtoint (double** getelementptr (double** null, i32 1) to i64) to i64
+ ret i64 %t
+}
+define i64 @fi() nounwind {
+ %t = bitcast i64 ptrtoint (double** getelementptr ({i1, double*}* null, i64 0, i32 1) to i64) to i64
+ ret i64 %t
+}
+
+; PLAIN: define i64* @fM() nounwind {
+; PLAIN: %t = bitcast i64* getelementptr (i64* null, i32 1) to i64*
+; PLAIN: ret i64* %t
+; PLAIN: }
+; PLAIN: define i64* @fN() nounwind {
+; PLAIN: %t = bitcast i64* getelementptr (%3* null, i32 0, i32 1) to i64*
+; PLAIN: ret i64* %t
+; PLAIN: }
+; PLAIN: define i64* @fO() nounwind {
+; PLAIN: %t = bitcast i64* getelementptr ([2 x i64]* null, i32 0, i32 1) to i64*
+; PLAIN: ret i64* %t
+; PLAIN: }
+; OPT: define i64* @fM() nounwind {
+; OPT: ret i64* getelementptr (i64* null, i32 1)
+; OPT: }
+; OPT: define i64* @fN() nounwind {
+; OPT: ret i64* getelementptr (%3* null, i32 0, i32 1)
+; OPT: }
+; OPT: define i64* @fO() nounwind {
+; OPT: ret i64* getelementptr ([2 x i64]* null, i32 0, i32 1)
+; OPT: }
+; TO: define i64* @fM() nounwind {
+; TO: ret i64* inttoptr (i64 8 to i64*)
+; TO: }
+; TO: define i64* @fN() nounwind {
+; TO: ret i64* inttoptr (i64 8 to i64*)
+; TO: }
+; TO: define i64* @fO() nounwind {
+; TO: ret i64* inttoptr (i64 8 to i64*)
+; TO: }
+; SCEV: Classifying expressions for: @fM
+; SCEV: %t = bitcast i64* getelementptr (i64* null, i32 1) to i64*
+; SCEV: --> sizeof(i64)
+; SCEV: Classifying expressions for: @fN
+; SCEV: %t = bitcast i64* getelementptr (%3* null, i32 0, i32 1) to i64*
+; SCEV: --> sizeof(i64)
+; SCEV: Classifying expressions for: @fO
+; SCEV: %t = bitcast i64* getelementptr ([2 x i64]* null, i32 0, i32 1) to i64*
+; SCEV: --> sizeof(i64)
+
+define i64* @fM() nounwind {
+ %t = bitcast i64* getelementptr (i64 *null, i32 1) to i64*
+ ret i64* %t
+}
+define i64* @fN() nounwind {
+ %t = bitcast i64* getelementptr ({ i64, i64 } *null, i32 0, i32 1) to i64*
+ ret i64* %t
+}
+define i64* @fO() nounwind {
+ %t = bitcast i64* getelementptr ([2 x i64] *null, i32 0, i32 1) to i64*
+ ret i64* %t
+}
diff --git a/test/Transforms/ConstProp/basictest.ll b/test/Transforms/ConstProp/basictest.ll
index 2edc55d..14580c1 100644
--- a/test/Transforms/ConstProp/basictest.ll
+++ b/test/Transforms/ConstProp/basictest.ll
@@ -19,3 +19,15 @@ BB3:
ret i32 %Ret
}
+
+; PR6197
+define i1 @test2(i8* %f) nounwind {
+entry:
+ %V = icmp ne i8* blockaddress(@test2, %bb), null
+ br label %bb
+bb:
+ ret i1 %V
+
+; CHECK: @test2
+; CHECK: ret i1 true
+}
diff --git a/test/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll b/test/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll
deleted file mode 100644
index cea18a0..0000000
--- a/test/Transforms/ConstantMerge/2006-03-07-DontMergeDiffSections.ll
+++ /dev/null
@@ -1,16 +0,0 @@
-; RUN: opt < %s -constmerge -S | grep foo
-; RUN: opt < %s -constmerge -S | grep bar
-
-; Don't merge constants in different sections.
-
-@G1 = internal constant i32 1, section "foo" ; <i32*> [#uses=1]
-@G2 = internal constant i32 1, section "bar" ; <i32*> [#uses=1]
-@G3 = internal constant i32 1, section "bar" ; <i32*> [#uses=1]
-
-define void @test(i32** %P1, i32** %P2, i32** %P3) {
- store i32* @G1, i32** %P1
- store i32* @G2, i32** %P2
- store i32* @G3, i32** %P3
- ret void
-}
-
diff --git a/test/Transforms/ConstantMerge/dont-merge.ll b/test/Transforms/ConstantMerge/dont-merge.ll
new file mode 100644
index 0000000..877cf8d
--- /dev/null
+++ b/test/Transforms/ConstantMerge/dont-merge.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -constmerge -S | FileCheck %s
+
+; Don't merge constants with specified sections.
+
+@T1G1 = internal constant i32 1, section "foo"
+@T1G2 = internal constant i32 1, section "bar"
+@T1G3 = internal constant i32 1, section "bar"
+
+; CHECK: @T1G1
+; CHECK: @T1G2
+; CHECK: @T1G3
+
+define void @test1(i32** %P1, i32** %P2, i32** %P3) {
+ store i32* @T1G1, i32** %P1
+ store i32* @T1G2, i32** %P2
+ store i32* @T1G3, i32** %P3
+ ret void
+}
+
+@T2a = internal constant i32 224
+@T2b = internal addrspace(30) constant i32 224
+
+; CHECK: @T2a
+; CHECK: @T2b
+
+define void @test2(i32** %P1, i32 addrspace(30)** %P2) {
+ store i32* @T2a, i32** %P1
+ store i32 addrspace(30)* @T2b, i32 addrspace(30)** %P2
+ ret void
+}
diff --git a/test/Transforms/DeadStoreElimination/crash.ll b/test/Transforms/DeadStoreElimination/crash.ll
index f89f8f5..6d8ba71 100644
--- a/test/Transforms/DeadStoreElimination/crash.ll
+++ b/test/Transforms/DeadStoreElimination/crash.ll
@@ -41,3 +41,17 @@ bb14: ; preds = %bb4
}
declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
+
+
+; rdar://7635088
+define i32 @test3() {
+entry:
+ ret i32 0
+
+dead:
+ %P2 = getelementptr i32 *%P2, i32 52
+ %Q2 = getelementptr i32 *%Q2, i32 52
+ store i32 4, i32* %P2
+ store i32 4, i32* %Q2
+ br label %dead
+} \ No newline at end of file
diff --git a/test/Transforms/GVN/crash.ll b/test/Transforms/GVN/crash.ll
index 9167b6e..4a3aa1c 100644
--- a/test/Transforms/GVN/crash.ll
+++ b/test/Transforms/GVN/crash.ll
@@ -5,7 +5,7 @@
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin10.0"
-define i32* @peel_to_type(i8* %name, i32 %namelen, i32* %o, i32 %expected_type) nounwind ssp {
+define i32* @test1(i8* %name, i32 %namelen, i32* %o, i32 %expected_type) nounwind ssp {
entry:
br i1 undef, label %if.end13, label %while.body.preheader
@@ -69,7 +69,7 @@ declare i32* @parse_object(i8*)
@attribute_tables = external global [4 x %struct.attribute_spec*] ; <[4 x %struct.attribute_spec*]*> [#uses=2]
-define void @decl_attributes() nounwind {
+define void @test2() nounwind {
entry:
br label %bb69.i
@@ -99,7 +99,7 @@ bb66.i: ; Unreachable
@g = external global i64, align 8
-define i32* @foo() {
+define i32* @test3() {
do.end17.i:
%tmp18.i = load i7** undef
%tmp1 = bitcast i7* %tmp18.i to i8*
@@ -135,3 +135,19 @@ do.body57.i:
declare i32 @foo2()
+
+
+define i32 @test4() {
+entry:
+ ret i32 0
+
+dead:
+ %P2 = getelementptr i32 *%P2, i32 52
+ %Q2 = getelementptr i32 *%Q2, i32 52
+ store i32 4, i32* %P2
+ %A = load i32* %Q2
+ br i1 true, label %dead, label %dead2
+
+dead2:
+ ret i32 %A
+}
diff --git a/test/Transforms/GVN/load-pre-align.ll b/test/Transforms/GVN/load-pre-align.ll
new file mode 100644
index 0000000..3a66c0b
--- /dev/null
+++ b/test/Transforms/GVN/load-pre-align.ll
@@ -0,0 +1,44 @@
+; RUN: opt < %s -gvn -S | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
+
+@p = external global i32
+
+define arm_apcscc i32 @test(i32 %n) nounwind {
+; CHECK: @test
+entry:
+ br label %for.cond
+
+; loads aligned greater than the memory should not be moved past conditionals
+; CHECK-NOT: load
+; CHECK: br i1
+
+for.cond:
+ %i.0 = phi i32 [ 0, %entry ], [ %indvar.next, %for.inc ]
+ %cmp = icmp slt i32 %i.0, %n
+ br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
+
+for.cond.for.end_crit_edge:
+; ...but PRE can still move the load out of for.end to here.
+; CHECK: for.cond.for.end_crit_edge:
+; CHECK-NEXT: load
+ br label %for.end
+
+for.body:
+ %tmp3 = load i32* @p, align 8
+ %dec = add i32 %tmp3, -1
+ store i32 %dec, i32* @p
+ %cmp6 = icmp slt i32 %dec, 0
+ br i1 %cmp6, label %for.body.for.end_crit_edge, label %for.inc
+
+for.body.for.end_crit_edge:
+ br label %for.end
+
+for.inc:
+ %indvar.next = add i32 %i.0, 1
+ br label %for.cond
+
+for.end:
+ %tmp9 = load i32* @p, align 8
+ ret i32 %tmp9
+}
diff --git a/test/Transforms/GVN/rle-nonlocal.ll b/test/Transforms/GVN/rle-nonlocal.ll
index 51b8986..5c73dad 100644
--- a/test/Transforms/GVN/rle-nonlocal.ll
+++ b/test/Transforms/GVN/rle-nonlocal.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -gvn -S | grep {%DEAD = phi i32. }
+; RUN: opt < %s -gvn -S | FileCheck %s
define i32 @main(i32** %p) {
block1:
@@ -13,7 +13,12 @@ block3:
br label %block4
block4:
+; CHECK-NOT: %existingPHI = phi
+; CHECK: %DEAD = phi
+ %existingPHI = phi i32* [ %a, %block2 ], [ %b, %block3 ]
%DEAD = load i32** %p
%c = load i32* %DEAD
- ret i32 %c
+ %d = load i32* %existingPHI
+ %e = add i32 %c, %d
+ ret i32 %e
}
diff --git a/test/Transforms/IndVarSimplify/addrec-gep.ll b/test/Transforms/IndVarSimplify/addrec-gep.ll
index 9e42734..345f666 100644
--- a/test/Transforms/IndVarSimplify/addrec-gep.ll
+++ b/test/Transforms/IndVarSimplify/addrec-gep.ll
@@ -25,7 +25,7 @@ bb1: ; preds = %bb2, %bb.nph
%j.01 = phi i64 [ %tmp9, %bb2 ], [ 0, %bb.nph ] ; <i64> [#uses=3]
%tmp3 = add i64 %j.01, %tmp1 ; <i64> [#uses=1]
%tmp4 = add i64 %j.01, %tmp2 ; <i64> [#uses=1]
- %z0 = add i64 %tmp4, 5203
+ %z0 = add i64 %tmp3, 5203
%tmp5 = getelementptr double* %p, i64 %z0 ; <double*> [#uses=1]
%tmp6 = load double* %tmp5, align 8 ; <double> [#uses=1]
%tmp7 = fdiv double %tmp6, 2.100000e+00 ; <double> [#uses=1]
diff --git a/test/Transforms/IndVarSimplify/shrunk-constant.ll b/test/Transforms/IndVarSimplify/shrunk-constant.ll
index 8003fd3..271f8ed 100644
--- a/test/Transforms/IndVarSimplify/shrunk-constant.ll
+++ b/test/Transforms/IndVarSimplify/shrunk-constant.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -scalar-evolution -analyze -disable-output \
+; RUN: opt < %s -scalar-evolution -analyze \
; RUN: | grep {\\--> (zext i4 {-7,+,-8}<%loop> to i32)}
define fastcc void @foo() nounwind {
diff --git a/test/Transforms/InstCombine/2007-03-27-PR1280.ll b/test/Transforms/InstCombine/2007-03-27-PR1280.ll
deleted file mode 100644
index 7700c7d..0000000
--- a/test/Transforms/InstCombine/2007-03-27-PR1280.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; PR1280 - we should be able to reduce this function to a trunc/sext but it
-; would involve using a bit width (24) that doesn't match a size that
-; the back end can handle. This test makes sure that such a transform
-; is not done. It should be removed when code gen supports "funny"
-; bit widths.
-
-; RUN: opt < %s -instcombine -S | grep {add i49.*-8388608}
-
-define i49 @test5(i49 %x) {
- ;; If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext.
- %X = and i49 %x, 16777215 ; 0x0000000ffffff
- %tmp.2 = xor i49 %X, 8388608 ; 0x0000000800000
- %tmp.4 = add i49 %tmp.2, -8388608 ; 0x1FFFFFF800000
- ret i49 %tmp.4
-}
diff --git a/test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll b/test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll
new file mode 100644
index 0000000..4ab9bf0
--- /dev/null
+++ b/test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; PR6165
+
+define i32 @f() {
+entry:
+ br label %BB1
+
+BB1: ; preds = %BB1, %entry
+; CHECK: BB1:
+ %x = phi i32 [ -29, %entry ], [ 0, %BB1 ] ; <i32> [#uses=2]
+ %rem = srem i32 %x, 2 ; <i32> [#uses=1]
+ %t = icmp eq i32 %rem, -1 ; <i1> [#uses=1]
+ br i1 %t, label %BB2, label %BB1
+; CHECK-NOT: br i1 false
+
+BB2: ; preds = %BB1
+; CHECK: BB2:
+ ret i32 %x
+}
diff --git a/test/Transforms/InstCombine/and2.ll b/test/Transforms/InstCombine/and2.ll
index 0af9bfa..a5a6574 100644
--- a/test/Transforms/InstCombine/and2.ll
+++ b/test/Transforms/InstCombine/and2.ll
@@ -1,5 +1,4 @@
-; RUN: opt < %s -instcombine -S | not grep and
-
+; RUN: opt < %s -instcombine -S | FileCheck %s
; PR1738
define i1 @test1(double %X, double %Y) {
@@ -7,6 +6,5 @@ define i1 @test1(double %X, double %Y) {
%tmp13 = fcmp ord double %Y, 0.000000e+00
%bothcond = and i1 %tmp13, %tmp9
ret i1 %bothcond
+; CHECK: fcmp ord double %Y, %X
}
-
-
diff --git a/test/Transforms/InstCombine/call.ll b/test/Transforms/InstCombine/call.ll
index 05c063d..dd65b96 100644
--- a/test/Transforms/InstCombine/call.ll
+++ b/test/Transforms/InstCombine/call.ll
@@ -75,7 +75,7 @@ define i32 @test5() {
declare i32 @test6a(i32)
define i32 @test6() {
- %X = call i32 bitcast (i32 (i32)* @test6a to i32 ()*)( ) ; <i32> [#uses=1]
+ %X = call i32 bitcast (i32 (i32)* @test6a to i32 ()*)( )
ret i32 %X
; CHECK: %X1 = call i32 @test6a(i32 0)
; CHECK: ret i32 %X1
@@ -96,3 +96,23 @@ define void @test7() {
}
+; rdar://7590304
+declare void @test8a()
+
+define i8* @test8() {
+ invoke arm_apcscc void @test8a()
+ to label %invoke.cont unwind label %try.handler
+
+invoke.cont: ; preds = %entry
+ unreachable
+
+try.handler: ; preds = %entry
+ ret i8* null
+}
+
+; Don't turn this into "unreachable": the callee and caller don't agree in
+; calling conv, but the implementation of test8a may actually end up using the
+; right calling conv.
+; CHECK: @test8() {
+; CHECK-NEXT: invoke arm_apcscc void @test8a()
+
diff --git a/test/Transforms/InstCombine/crash.ll b/test/Transforms/InstCombine/crash.ll
index 732a882..2faa539 100644
--- a/test/Transforms/InstCombine/crash.ll
+++ b/test/Transforms/InstCombine/crash.ll
@@ -204,3 +204,36 @@ declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
declare void @_ZSt9terminatev()
declare void @_Unwind_Resume_or_Rethrow(i8*)
+
+
+
+; rdar://7590304
+define i8* @test10(i8* %self, i8* %tmp3) {
+entry:
+ store i1 true, i1* undef
+ store i1 true, i1* undef
+ invoke arm_apcscc void @test10a()
+ to label %invoke.cont unwind label %try.handler ; <i8*> [#uses=0]
+
+invoke.cont: ; preds = %entry
+ unreachable
+
+try.handler: ; preds = %entry
+ ret i8* %self
+}
+
+define void @test10a() {
+ ret void
+}
+
+
+; PR6193
+define i32 @test11(i32 %aMaskWidth, i8 %aStride) nounwind {
+entry:
+ %conv41 = sext i8 %aStride to i32
+ %neg = xor i32 %conv41, -1
+ %and42 = and i32 %aMaskWidth, %neg
+ %and47 = and i32 130, %conv41
+ %or = or i32 %and42, %and47
+ ret i32 %or
+}
diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll
index de325f6..f0bee4e 100644
--- a/test/Transforms/InstCombine/getelementptr.ll
+++ b/test/Transforms/InstCombine/getelementptr.ll
@@ -246,7 +246,7 @@ bc0:
store i32 0, i32* %tmp53
ret void
; CHECK: @test24
-; CHECK: store i32 0, i32* getelementptr (%"java/lang/StringBuffer"* null, i32 0, i32 1)
+; CHECK: store i32 0, i32* getelementptr (%"java/lang/StringBuffer"* null, i64 0, i32 1)
}
define void @test25() {
diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll
index 79fa220..c2234a1 100644
--- a/test/Transforms/InstCombine/icmp.ll
+++ b/test/Transforms/InstCombine/icmp.ll
@@ -112,3 +112,12 @@ define i1 @test11(i32 %x) {
; CHECK: ret i1 true
}
+; PR6195
+define i1 @test12(i1 %A) {
+ %S = select i1 %A, i64 -4294967295, i64 8589934591
+ %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S
+ ret i1 %B
+; CHECK: @test12
+; CHECK-NEXT: %B = select i1
+; CHECK-NEXT: ret i1 %B
+}
diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll
index c63475c..08dcfa7 100644
--- a/test/Transforms/InstCombine/intrinsics.ll
+++ b/test/Transforms/InstCombine/intrinsics.ll
@@ -144,3 +144,18 @@ entry:
; CHECK-NEXT: %pop.cmp = icmp eq i32 %b, 0
; CHECK-NEXT: volatile store i1 %pop.cmp, i1* %c
}
+
+
+define i32 @cttz_simplify1(i32 %x) nounwind readnone ssp {
+ %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %x) ; <i32> [#uses=1]
+ %shr3 = lshr i32 %tmp1, 5 ; <i32> [#uses=1]
+ ret i32 %shr3
+
+; CHECK: @cttz_simplify1
+; CHECK: icmp eq i32 %x, 0
+; CHECK-NEXT: zext i1
+; CHECK-NEXT: ret i32
+}
+
+declare i32 @llvm.ctlz.i32(i32) nounwind readnone
+
diff --git a/test/Transforms/InstCombine/load-select.ll b/test/Transforms/InstCombine/load-select.ll
new file mode 100644
index 0000000..f3d83dc
--- /dev/null
+++ b/test/Transforms/InstCombine/load-select.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
+
+@a = constant [2 x i32] [i32 3, i32 6] ; <[2 x i32]*> [#uses=2]
+
+define i32 @b(i32 %y) nounwind readonly {
+; CHECK: @b
+; CHECK-NOT: load
+; CHECK: ret i32
+entry:
+ %0 = icmp eq i32 %y, 0 ; <i1> [#uses=1]
+ %storemerge = select i1 %0, i32* getelementptr inbounds ([2 x i32]* @a, i32 0, i32 1), i32* getelementptr inbounds ([2 x i32]* @a, i32 0, i32 0) ; <i32*> [#uses=1]
+ %1 = load i32* %storemerge, align 4 ; <i32> [#uses=1]
+ ret i32 %1
+}
diff --git a/test/Transforms/InstCombine/logical-select.ll b/test/Transforms/InstCombine/logical-select.ll
index ece8bc3..bb59817 100644
--- a/test/Transforms/InstCombine/logical-select.ll
+++ b/test/Transforms/InstCombine/logical-select.ll
@@ -1,7 +1,5 @@
-; RUN: opt < %s -instcombine -S > %t
-; RUN: grep select %t | count 5
-; RUN: not grep and %t
-; RUN: not grep or %t
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
%e = icmp slt i32 %a, %b
@@ -11,6 +9,9 @@ define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
%i = and i32 %d, %h
%j = or i32 %g, %i
ret i32 %j
+; CHECK: %e = icmp slt i32 %a, %b
+; CHECK: %j = select i1 %e, i32 %c, i32 %d
+; CHECK: ret i32 %j
}
define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
%e = icmp slt i32 %a, %b
@@ -20,7 +21,11 @@ define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
%i = and i32 %d, %h
%j = or i32 %i, %g
ret i32 %j
+; CHECK: %e = icmp slt i32 %a, %b
+; CHECK: %j = select i1 %e, i32 %c, i32 %d
+; CHECK: ret i32 %j
}
+
define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
entry:
%0 = icmp slt i32 %a, %b
@@ -30,6 +35,9 @@ entry:
%2 = and i32 %not, %d
%3 = or i32 %1, %2
ret i32 %3
+; CHECK: %0 = icmp slt i32 %a, %b
+; CHECK: %1 = select i1 %0, i32 %c, i32 %d
+; CHECK: ret i32 %1
}
define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
entry:
@@ -40,6 +48,9 @@ entry:
%2 = and i32 %iftmp, %d
%3 = or i32 %1, %2
ret i32 %3
+; CHECK: %0 = icmp slt i32 %a, %b
+; CHECK: %1 = select i1 %0, i32 %c, i32 %d
+; CHECK: ret i32 %1
}
define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
@@ -51,4 +62,7 @@ entry:
%2 = and i32 %not, %d
%3 = or i32 %1, %2
ret i32 %3
+; CHECK: %0 = icmp slt i32 %a, %b
+; CHECK: %1 = select i1 %0, i32 %c, i32 %d
+; CHECK: ret i32 %1
}
diff --git a/test/Transforms/InstCombine/objsize.ll b/test/Transforms/InstCombine/objsize.ll
new file mode 100644
index 0000000..dbc7d31
--- /dev/null
+++ b/test/Transforms/InstCombine/objsize.ll
@@ -0,0 +1,75 @@
+; Test a pile of objectsize bounds checking.
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; We need target data to get the sizes of the arrays and structures.
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+
+@a = private global [60 x i8] zeroinitializer, align 1 ; <[60 x i8]*>
+@.str = private constant [8 x i8] c"abcdefg\00" ; <[8 x i8]*>
+
+define i32 @foo() nounwind {
+; CHECK: @foo
+; CHECK-NEXT: ret i32 60
+ %1 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
+ ret i32 %1
+}
+
+define i8* @bar() nounwind {
+; CHECK: @bar
+entry:
+ %retval = alloca i8*
+ %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
+ %cmp = icmp ne i32 %0, -1
+; CHECK: br i1 true
+ br i1 %cmp, label %cond.true, label %cond.false
+
+cond.true:
+ %1 = load i8** %retval;
+ ret i8* %1;
+
+cond.false:
+ %2 = load i8** %retval;
+ ret i8* %2;
+}
+
+define i32 @f() nounwind {
+; CHECK: @f
+; CHECK-NEXT: ret i32 0
+ %1 = call i32 @llvm.objectsize.i32(i8* getelementptr ([60 x i8]* @a, i32 1, i32 0), i1 false)
+ ret i32 %1
+}
+
+@window = external global [0 x i8]
+
+define i1 @baz() nounwind {
+; CHECK: @baz
+; CHECK-NEXT: ret i1 true
+ %1 = tail call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 0), i1 false)
+ %2 = icmp eq i32 %1, -1
+ ret i1 %2
+}
+
+define void @test1(i8* %q, i32 %x) nounwind noinline {
+; CHECK: @test1
+; CHECK: objectsize.i32
+entry:
+ %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 10), i1 false) ; <i64> [#uses=1]
+ %1 = icmp eq i32 %0, -1 ; <i1> [#uses=1]
+ br i1 %1, label %"47", label %"46"
+
+"46": ; preds = %entry
+ unreachable
+
+"47": ; preds = %entry
+ unreachable
+}
+
+@.str5 = private constant [9 x i32] [i32 97, i32 98, i32 99, i32 100, i32 0, i32
+ 101, i32 102, i32 103, i32 0], align 4 ;
+define i32 @test2() nounwind {
+; CHECK: @test2
+; CHECK-NEXT: ret i32 34
+ %1 = call i32 @llvm.objectsize.i32(i8* getelementptr (i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false)
+ ret i32 %1
+}
+
+declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly \ No newline at end of file
diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll
index 2040f3d..189be10 100644
--- a/test/Transforms/InstCombine/or.ll
+++ b/test/Transforms/InstCombine/or.ll
@@ -336,3 +336,17 @@ define i64 @test31(i64 %A) nounwind readnone ssp noredzone {
; CHECK-NEXT: %F = and i64 %bitfield, 4294941946
; CHECK-NEXT: ret i64 %F
}
+
+define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) {
+ %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32> ; <<4 x i32>> [#uses=2]
+ %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135 ; <<4 x i32>> [#uses=1]
+ %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1> ; <<4 x i32>> [#uses=1]
+ %and.i = and <4 x i32> %vecinit6.i191, %neg.i ; <<4 x i32>> [#uses=1]
+ %or.i = or <4 x i32> %and.i, %and.i129 ; <<4 x i32>> [#uses=1]
+ ret <4 x i32> %or.i
+; Don't turn this into a vector select until codegen matures to handle them
+; better.
+; CHECK: @test32
+; CHECK: or <4 x i32> %and.i, %and.i129
+}
+
diff --git a/test/Transforms/InstCombine/signext.ll b/test/Transforms/InstCombine/signext.ll
index 1c52b62..49384d6 100644
--- a/test/Transforms/InstCombine/signext.ll
+++ b/test/Transforms/InstCombine/signext.ll
@@ -8,8 +8,8 @@ define i32 @test1(i32 %x) {
%tmp.3 = add i32 %tmp.2, 32768 ; <i32> [#uses=1]
ret i32 %tmp.3
; CHECK: @test1
-; CHECK: %sext1 = shl i32 %x, 16
-; CHECK: %tmp.3 = ashr i32 %sext1, 16
+; CHECK: %sext = shl i32 %x, 16
+; CHECK: %tmp.3 = ashr i32 %sext, 16
; CHECK: ret i32 %tmp.3
}
@@ -19,8 +19,8 @@ define i32 @test2(i32 %x) {
%tmp.3 = add i32 %tmp.2, -32768 ; <i32> [#uses=1]
ret i32 %tmp.3
; CHECK: @test2
-; CHECK: %sext1 = shl i32 %x, 16
-; CHECK: %tmp.3 = ashr i32 %sext1, 16
+; CHECK: %sext = shl i32 %x, 16
+; CHECK: %tmp.3 = ashr i32 %sext, 16
; CHECK: ret i32 %tmp.3
}
@@ -50,8 +50,8 @@ define i32 @test5(i32 %x) {
%tmp.3 = add i32 %tmp.2, -128 ; <i32> [#uses=1]
ret i32 %tmp.3
; CHECK: @test5
-; CHECK: %sext1 = shl i32 %x, 24
-; CHECK: %tmp.3 = ashr i32 %sext1, 24
+; CHECK: %sext = shl i32 %x, 24
+; CHECK: %tmp.3 = ashr i32 %sext, 24
; CHECK: ret i32 %tmp.3
}
@@ -74,3 +74,14 @@ define i32 @test7(i16 %P) {
; CHECK: %tmp.5 = sext i16 %P to i32
; CHECK: ret i32 %tmp.5
}
+
+define i32 @test8(i32 %x) nounwind readnone {
+entry:
+ %shr = lshr i32 %x, 5 ; <i32> [#uses=1]
+ %xor = xor i32 %shr, 67108864 ; <i32> [#uses=1]
+ %sub = add i32 %xor, -67108864 ; <i32> [#uses=1]
+ ret i32 %sub
+; CHECK: @test8
+; CHECK: %sub = ashr i32 %x, 5
+; CHECK: ret i32 %sub
+}
diff --git a/test/Transforms/InstCombine/sub.ll b/test/Transforms/InstCombine/sub.ll
index fa0322a..29bd7be 100644
--- a/test/Transforms/InstCombine/sub.ll
+++ b/test/Transforms/InstCombine/sub.ll
@@ -272,4 +272,12 @@ define i64 @test25(i8* %P, i64 %A){
; CHECK-NEXT: ret i64
}
+define i32 @test26(i32 %x) {
+ %shl = shl i32 3, %x
+ %neg = sub i32 0, %shl
+ ret i32 %neg
+; CHECK: @test26
+; CHECK-NEXT: shl i32 -3
+; CHECK-NEXT: ret i32
+}
diff --git a/test/Transforms/InstCombine/vector-casts.ll b/test/Transforms/InstCombine/vector-casts.ll
index 470d485..24bd04d 100644
--- a/test/Transforms/InstCombine/vector-casts.ll
+++ b/test/Transforms/InstCombine/vector-casts.ll
@@ -51,6 +51,22 @@ entry:
}
+; rdar://7434900
+define <2 x i64> @test5(<4 x float> %a, <4 x float> %b) nounwind readnone {
+entry:
+ %cmp = fcmp ult <4 x float> %a, zeroinitializer
+ %sext = sext <4 x i1> %cmp to <4 x i32>
+ %cmp4 = fcmp ult <4 x float> %b, zeroinitializer
+ %sext5 = sext <4 x i1> %cmp4 to <4 x i32>
+ %and = and <4 x i32> %sext, %sext5
+ %conv = bitcast <4 x i32> %and to <2 x i64>
+ ret <2 x i64> %conv
+
+; CHECK: @test5
+; CHECK: sext <4 x i1> %cmp to <4 x i32>
+; CHECK: sext <4 x i1> %cmp4 to <4 x i32>
+}
+
define void @convert(<2 x i32>* %dst.addr, <2 x i64> %src) nounwind {
entry:
diff --git a/test/Transforms/JumpThreading/crash.ll b/test/Transforms/JumpThreading/crash.ll
index 361ec6c..c65fd10 100644
--- a/test/Transforms/JumpThreading/crash.ll
+++ b/test/Transforms/JumpThreading/crash.ll
@@ -234,3 +234,93 @@ bb2:
return:
ret void
}
+
+; PR6119
+define i32 @test8(i32 %action) nounwind {
+entry:
+ switch i32 %action, label %lor.rhs [
+ i32 1, label %if.then
+ i32 0, label %lor.end
+ ]
+
+if.then: ; preds = %for.cond, %lor.end, %entry
+ ret i32 undef
+
+lor.rhs: ; preds = %entry
+ br label %lor.end
+
+lor.end: ; preds = %lor.rhs, %entry
+ %cmp103 = xor i1 undef, undef ; <i1> [#uses=1]
+ br i1 %cmp103, label %for.cond, label %if.then
+
+for.cond: ; preds = %for.body, %lor.end
+ br i1 undef, label %if.then, label %for.body
+
+for.body: ; preds = %for.cond
+ br label %for.cond
+}
+
+; PR6119
+define i32 @test9(i32 %action) nounwind {
+entry:
+ switch i32 %action, label %lor.rhs [
+ i32 1, label %if.then
+ i32 0, label %lor.end
+ ]
+
+if.then: ; preds = %for.cond, %lor.end, %entry
+ ret i32 undef
+
+lor.rhs: ; preds = %entry
+ br label %lor.end
+
+lor.end: ; preds = %lor.rhs, %entry
+ %0 = phi i1 [ undef, %lor.rhs ], [ true, %entry ] ; <i1> [#uses=1]
+ %cmp103 = xor i1 undef, %0 ; <i1> [#uses=1]
+ br i1 %cmp103, label %for.cond, label %if.then
+
+for.cond: ; preds = %for.body, %lor.end
+ br i1 undef, label %if.then, label %for.body
+
+for.body: ; preds = %for.cond
+ br label %for.cond
+}
+
+; PR6119
+define i32 @test10(i32 %action, i32 %type) nounwind {
+entry:
+ %cmp2 = icmp eq i32 %type, 0 ; <i1> [#uses=1]
+ switch i32 %action, label %lor.rhs [
+ i32 1, label %if.then
+ i32 0, label %lor.end
+ ]
+
+if.then: ; preds = %for.cond, %lor.end, %entry
+ ret i32 undef
+
+lor.rhs: ; preds = %entry
+ %cmp101 = icmp eq i32 %action, 2 ; <i1> [#uses=1]
+ br label %lor.end
+
+lor.end: ; preds = %lor.rhs, %entry
+ %0 = phi i1 [ %cmp101, %lor.rhs ], [ true, %entry ] ; <i1> [#uses=1]
+ %cmp103 = xor i1 %cmp2, %0 ; <i1> [#uses=1]
+ br i1 %cmp103, label %for.cond, label %if.then
+
+for.cond: ; preds = %for.body, %lor.end
+ br i1 undef, label %if.then, label %for.body
+
+for.body: ; preds = %for.cond
+ br label %for.cond
+}
+
+
+; PR6305
+define void @test11() nounwind {
+entry:
+ br label %A
+
+A: ; preds = %entry
+ call void undef(i64 ptrtoint (i8* blockaddress(@test11, %A) to i64)) nounwind
+ unreachable
+}
diff --git a/test/Transforms/JumpThreading/or-undef.ll b/test/Transforms/JumpThreading/or-undef.ll
new file mode 100644
index 0000000..6e35992
--- /dev/null
+++ b/test/Transforms/JumpThreading/or-undef.ll
@@ -0,0 +1,69 @@
+; RUN: opt -jump-threading -S %s | FileCheck %s
+; rdar://7620633
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin11.0"
+
+define void @test1(i8* %args, i32 %from_tty) nounwind optsize ssp {
+entry:
+ %tmp = call i8* @f3(void (i8*)* null, i8* null) nounwind ; <i8*> [#uses=1]
+ %tmp1 = icmp eq i8* %args, null ; <i1> [#uses=1]
+ br i1 %tmp1, label %bb2, label %bb
+
+; CHECK: entry:
+; CHECK-NEXT: %tmp = call i8* @f3
+; CHECK-NEXT: %tmp1 = icmp eq i8* %args, null
+; CHECK-NEXT: br i1 %tmp1, label %bb7, label %bb
+
+bb: ; preds = %entry
+ %tmp2 = call noalias i8** @buildargv(i8* %args) nounwind ; <i8**> [#uses=4]
+ %tmp3 = icmp eq i8** %tmp2, null ; <i1> [#uses=1]
+ br i1 %tmp3, label %bb2, label %bb1
+
+bb1: ; preds = %bb
+ call void @f2(i8** %tmp2) nounwind
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb, %entry
+ %argv.0 = phi i8** [ %tmp2, %bb1 ], [ %tmp2, %bb ], [ undef, %entry ] ; <i8**> [#uses=4]
+ %tmp5 = icmp eq i8* %args, null ; <i1> [#uses=1]
+ %tmp6 = icmp eq i8** %argv.0, null ; <i1> [#uses=1]
+ %tmp7 = or i1 %tmp5, %tmp6 ; <i1> [#uses=1]
+ br i1 %tmp7, label %bb7, label %bb5
+
+bb5: ; preds = %bb2
+ %tmp8 = load i8** %argv.0, align 8 ; <i8*> [#uses=1]
+ %tmp9 = icmp eq i8* %tmp8, null ; <i1> [#uses=1]
+ br i1 %tmp9, label %bb7, label %bb6
+
+bb6: ; preds = %bb5
+ %tmp10 = load i8** %argv.0, align 8 ; <i8*> [#uses=1]
+ %tmp11 = load i8* %tmp10, align 1 ; <i8> [#uses=1]
+ %tmp12 = icmp eq i8 %tmp11, 0 ; <i1> [#uses=1]
+ br i1 %tmp12, label %bb7, label %bb8
+
+bb7: ; preds = %bb6, %bb5, %bb2
+ call void @f1() nounwind optsize ssp
+ br label %bb9
+
+bb8: ; preds = %bb6
+ %tmp13 = load i8** %argv.0, align 8 ; <i8*> [#uses=1]
+ %tmp14 = call i64 @f5(i8* %tmp13) nounwind ; <i64> [#uses=0]
+ br label %bb9
+
+bb9: ; preds = %bb8, %bb7
+ call void @f4(i8* %tmp) nounwind
+ ret void
+}
+
+declare noalias i8** @buildargv(i8*)
+
+declare void @f2(i8**)
+
+declare void @f4(i8*)
+
+declare i8* @f3(void (i8*)*, i8*)
+
+declare void @f1()
+
+declare i64 @f5(i8*)
diff --git a/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll b/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll
index 7c7a21c..99cb856 100644
--- a/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll
+++ b/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll
@@ -1,5 +1,4 @@
-; RUN: opt < %s -loop-reduce -S | grep ugt
-; PR2535
+; RUN: llc -march=x86-64 < %s -o - | grep {cmpl \\$\[1\], %}
@.str = internal constant [4 x i8] c"%d\0A\00"
@@ -16,7 +15,7 @@ forbody:
%add166 = or i32 %mul15, 1 ; <i32> [#uses=1] *
call i32 (i8*, ...)* @printf( i8* noalias getelementptr ([4 x i8]* @.str, i32 0, i32 0), i32 %add166 ) nounwind
%inc = add i32 %i.0, 1 ; <i32> [#uses=3]
- %cmp = icmp ult i32 %inc, 1027 ; <i1> [#uses=1]
+ %cmp = icmp ne i32 %inc, 1027 ; <i1> [#uses=1]
br i1 %cmp, label %forbody, label %afterfor
afterfor: ; preds = %forcond
diff --git a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll
index 36941ad..1f7f6ec 100644
--- a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll
+++ b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll
@@ -1,10 +1,15 @@
-; RUN: llc %s -o - --x86-asm-syntax=att | grep {cmpl \$4}
+; RUN: llc < %s -o - | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-apple-darwin9"
-; This is like change-compare-stride-trickiness-1.ll except the comparison
-; happens before the relevant use, so the comparison stride can't be
-; easily changed.
+; The comparison happens before the relevant use, but it can still be rewritten
+; to compare with zero.
+
+; CHECK: foo:
+; CHECK: align
+; CHECK: incl %eax
+; CHECK-NEXT: decl %ecx
+; CHECK-NEXT: jne
define void @foo() nounwind {
entry:
diff --git a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
index ea8a259..cb63809 100644
--- a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
+++ b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
@@ -1,10 +1,12 @@
-; RUN: llc %s -o - --x86-asm-syntax=att | grep {cmp. \$8}
+; RUN: llc %s -o - --x86-asm-syntax=att | grep {cmp. \$10}
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-apple-darwin9"
; The comparison happens after the relevant use, so the stride can easily
; be changed. The comparison can be done in a narrower mode than the
; induction variable.
+; TODO: By making the first store post-increment as well, the loop setup
+; could be made simpler.
define void @foo() nounwind {
entry:
diff --git a/test/Transforms/LoopStrengthReduce/count-to-zero.ll b/test/Transforms/LoopStrengthReduce/count-to-zero.ll
index 8cc3b5c..feb79f8 100644
--- a/test/Transforms/LoopStrengthReduce/count-to-zero.ll
+++ b/test/Transforms/LoopStrengthReduce/count-to-zero.ll
@@ -19,7 +19,7 @@ bb3: ; preds = %bb1
%tmp4 = add i32 %c_addr.1, -1 ; <i32> [#uses=1]
%c_addr.1.be = select i1 %tmp2, i32 %tmp3, i32 %tmp4 ; <i32> [#uses=1]
%indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
-; CHECK: sub i32 %lsr.iv, 1
+; CHECK: add i32 %lsr.iv, -1
br label %bb6
bb6: ; preds = %bb3, %entry
diff --git a/test/Transforms/LoopStrengthReduce/invariant_value_first.ll b/test/Transforms/LoopStrengthReduce/invariant_value_first.ll
index f86638b..4094e9c 100644
--- a/test/Transforms/LoopStrengthReduce/invariant_value_first.ll
+++ b/test/Transforms/LoopStrengthReduce/invariant_value_first.ll
@@ -1,5 +1,5 @@
; Check that the index of 'P[outer]' is pulled out of the loop.
-; RUN: opt < %s -loop-reduce -S | \
+; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | \
; RUN: not grep {getelementptr.*%outer.*%INDVAR}
declare i1 @pred()
diff --git a/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll b/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll
index 37acf0f..e2aed78 100644
--- a/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll
+++ b/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll
@@ -1,5 +1,5 @@
; Check that the index of 'P[outer]' is pulled out of the loop.
-; RUN: opt < %s -loop-reduce -S | \
+; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | \
; RUN: not grep {getelementptr.*%outer.*%INDVAR}
declare i1 @pred()
diff --git a/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll b/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll
index a032cc9..410d88f 100644
--- a/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll
+++ b/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll
@@ -1,7 +1,7 @@
; Check that this test makes INDVAR and related stuff dead, because P[indvar]
; gets reduced, making INDVAR dead.
-; RUN: opt < %s -loop-reduce -S | not grep INDVAR
+; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | not grep INDVAR
declare i1 @pred()
diff --git a/test/Transforms/LoopStrengthReduce/pr3086.ll b/test/Transforms/LoopStrengthReduce/pr3086.ll
index 9a5911f..599633a 100644
--- a/test/Transforms/LoopStrengthReduce/pr3086.ll
+++ b/test/Transforms/LoopStrengthReduce/pr3086.ll
@@ -1,5 +1,5 @@
-; RUN: opt < %s -loop-reduce -disable-output
-; RUN: opt < %s -analyze -scalar-evolution -disable-output
+; RUN: opt < %s -loop-reduce
+; RUN: opt < %s -analyze -scalar-evolution
; PR 3086
%struct.Cls = type { i32, i8, [2 x %struct.Cls*], [2 x %struct.Lit*] }
diff --git a/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll b/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll
index b829b47..8959c17 100644
--- a/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll
+++ b/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -analyze -iv-users -disable-output | grep {Stride i64 {3,+,2}<%loop>:}
+; RUN: opt < %s -analyze -iv-users | grep {\{1,+,3,+,2\}<%loop> (post-inc)}
; The value of %r is dependent on a polynomial iteration expression.
diff --git a/test/Transforms/LoopStrengthReduce/remove_indvar.ll b/test/Transforms/LoopStrengthReduce/remove_indvar.ll
index 53f4b9d..bb39532 100644
--- a/test/Transforms/LoopStrengthReduce/remove_indvar.ll
+++ b/test/Transforms/LoopStrengthReduce/remove_indvar.ll
@@ -7,10 +7,12 @@ define void @test(i32* %P) {
; <label>:0
br label %Loop
Loop: ; preds = %Loop, %0
+ %i = phi i32 [ 0, %0 ], [ %i.next, %Loop ]
%INDVAR = phi i32 [ 0, %0 ], [ %INDVAR2, %Loop ] ; <i32> [#uses=2]
%STRRED = getelementptr i32* %P, i32 %INDVAR ; <i32*> [#uses=1]
store i32 0, i32* %STRRED
%INDVAR2 = add i32 %INDVAR, 1 ; <i32> [#uses=1]
+ %i.next = add i32 %i, 1
%cond = call i1 @pred( ) ; <i1> [#uses=1]
br i1 %cond, label %Loop, label %Out
Out: ; preds = %Loop
diff --git a/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll b/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll
index a99a823..5ed37dd 100644
--- a/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll
+++ b/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -loop-reduce -S | \
-; RUN: grep {add i32 %lsr.iv.next, 1}
+; RUN: grep {add i32 %indvar630.ui, 1}
;
; Make sure that the use of the IV outside of the loop (the store) uses the
; post incremented value of the IV, not the preincremented value. This
diff --git a/test/Transforms/LoopUnswitch/2006-02-14-LoopSimplifyCrash.ll b/test/Transforms/LoopUnswitch/2006-02-14-LoopSimplifyCrash.ll
deleted file mode 100644
index b4cf406..0000000
--- a/test/Transforms/LoopUnswitch/2006-02-14-LoopSimplifyCrash.ll
+++ /dev/null
@@ -1,1697 +0,0 @@
-; RUN: opt < %s -loop-unswitch -disable-output
-; END.
-
-target datalayout = "E-p:32:32"
-target triple = "powerpc-apple-darwin8.2.0"
-deplibs = [ "c", "crtend" ]
- %struct.__sFILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
- %struct.__sFILEX = type opaque
- %struct.__sbuf = type { i8*, i32 }
- %struct.fd_set = type { [32 x i32] }
- %struct.timeval = type { i32, i32 }
- %struct.tm = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8* }
- %typedef.CHESS_PATH = type { [65 x i32], i8, i8, i8 }
- %typedef.CHESS_POSITION = type { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i32, i32, i8, i8, [64 x i8], i8, i8, i8, i8, i8 }
- %typedef.HASH_ENTRY = type { i64, i64 }
- %typedef.NEXT_MOVE = type { i32, i32, i32* }
- %typedef.PAWN_HASH_ENTRY = type { i32, i16, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 }
- %typedef.SEARCH_POSITION = type { i8, i8, i8, i8 }
- %union.doub0. = type { i64 }
-@search = external global %typedef.CHESS_POSITION ; <%typedef.CHESS_POSITION*> [#uses=1]
-@w_pawn_attacks = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@b_pawn_attacks = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@knight_attacks = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@bishop_attacks_rl45 = external global [64 x [256 x i64]] ; <[64 x [256 x i64]]*> [#uses=0]
-@bishop_shift_rl45 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@bishop_attacks_rr45 = external global [64 x [256 x i64]] ; <[64 x [256 x i64]]*> [#uses=0]
-@bishop_shift_rr45 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@rook_attacks_r0 = external global [64 x [256 x i64]] ; <[64 x [256 x i64]]*> [#uses=0]
-@rook_attacks_rl90 = external global [64 x [256 x i64]] ; <[64 x [256 x i64]]*> [#uses=0]
-@king_attacks = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@set_mask = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@first_ones = external global [65536 x i8] ; <[65536 x i8]*> [#uses=0]
-@last_ones = external global [65536 x i8] ; <[65536 x i8]*> [#uses=0]
-@draw_score_is_zero = external global i32 ; <i32*> [#uses=0]
-@default_draw_score = external global i32 ; <i32*> [#uses=0]
-@opening = external global i32 ; <i32*> [#uses=0]
-@middle_game = external global i32 ; <i32*> [#uses=0]
-@tc_increment = external global i32 ; <i32*> [#uses=0]
-@tc_time_remaining_opponent = external global i32 ; <i32*> [#uses=0]
-@.ctor_1 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@input_stream = external global %struct.__sFILE* ; <%struct.__sFILE**> [#uses=0]
-@__sF = external global [0 x %struct.__sFILE] ; <[0 x %struct.__sFILE]*> [#uses=1]
-@xboard = external global i32 ; <i32*> [#uses=0]
-@.str_1 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@.str_2 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@buffer = external global [512 x i8] ; <[512 x i8]*> [#uses=0]
-@nargs = external global i32 ; <i32*> [#uses=0]
-@args = external global [32 x i8*] ; <[32 x i8*]*> [#uses=0]
-@.str_3 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_4 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_5 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_6 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_7 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_8 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_9 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_10 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_11 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_12 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@.str_14 = external global [23 x i8] ; <[23 x i8]*> [#uses=0]
-@position = external global [67 x %typedef.SEARCH_POSITION] ; <[67 x %typedef.SEARCH_POSITION]*> [#uses=0]
-@log_file = external global %struct.__sFILE* ; <%struct.__sFILE**> [#uses=0]
-@move_number = external global i32 ; <i32*> [#uses=0]
-@rephead_b = external global i64* ; <i64**> [#uses=0]
-@replist_b = external global [82 x i64] ; <[82 x i64]*> [#uses=0]
-@rephead_w = external global i64* ; <i64**> [#uses=0]
-@replist_w = external global [82 x i64] ; <[82 x i64]*> [#uses=0]
-@moves_out_of_book = external global i32 ; <i32*> [#uses=0]
-@largest_positional_score = external global i32 ; <i32*> [#uses=0]
-@end_game = external global i32 ; <i32*> [#uses=0]
-@p_values = external global [15 x i32] ; <[15 x i32]*> [#uses=0]
-@clear_mask = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@directions = external global [64 x [64 x i8]] ; <[64 x [64 x i8]]*> [#uses=0]
-@root_wtm = external global i32 ; <i32*> [#uses=0]
-@all_pawns = external global i64 ; <i64*> [#uses=0]
-@pawn_score = external global %typedef.PAWN_HASH_ENTRY ; <%typedef.PAWN_HASH_ENTRY*> [#uses=0]
-@pawn_probes = external global i32 ; <i32*> [#uses=0]
-@pawn_hits = external global i32 ; <i32*> [#uses=0]
-@outside_passed = external global [128 x i32] ; <[128 x i32]*> [#uses=0]
-@root_total_black_pieces = external global i32 ; <i32*> [#uses=0]
-@root_total_white_pawns = external global i32 ; <i32*> [#uses=0]
-@root_total_white_pieces = external global i32 ; <i32*> [#uses=0]
-@root_total_black_pawns = external global i32 ; <i32*> [#uses=0]
-@mask_A7H7 = external global i64 ; <i64*> [#uses=0]
-@mask_B6B7 = external global i64 ; <i64*> [#uses=0]
-@mask_G6G7 = external global i64 ; <i64*> [#uses=0]
-@mask_A2H2 = external global i64 ; <i64*> [#uses=0]
-@mask_B2B3 = external global i64 ; <i64*> [#uses=0]
-@mask_G2G3 = external global i64 ; <i64*> [#uses=0]
-@king_defects_w = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@good_bishop_kw = external global i64 ; <i64*> [#uses=0]
-@mask_F3H3 = external global i64 ; <i64*> [#uses=0]
-@file_mask = external global [8 x i64] ; <[8 x i64]*> [#uses=0]
-@good_bishop_qw = external global i64 ; <i64*> [#uses=0]
-@mask_A3C3 = external global i64 ; <i64*> [#uses=0]
-@king_defects_b = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@good_bishop_kb = external global i64 ; <i64*> [#uses=0]
-@mask_F6H6 = external global i64 ; <i64*> [#uses=0]
-@good_bishop_qb = external global i64 ; <i64*> [#uses=0]
-@mask_A6C6 = external global i64 ; <i64*> [#uses=0]
-@square_color = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@evaluations = external global i32 ; <i32*> [#uses=0]
-@king_value_w = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@rank_mask = external global [8 x i64] ; <[8 x i64]*> [#uses=0]
-@mask_kr_trapped_w = external global [3 x i64] ; <[3 x i64]*> [#uses=0]
-@mask_qr_trapped_w = external global [3 x i64] ; <[3 x i64]*> [#uses=0]
-@king_value_b = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@mask_kr_trapped_b = external global [3 x i64] ; <[3 x i64]*> [#uses=0]
-@mask_qr_trapped_b = external global [3 x i64] ; <[3 x i64]*> [#uses=0]
-@white_outpost = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@mask_no_pawn_attacks_b = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@knight_value_w = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@black_outpost = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@mask_no_pawn_attacks_w = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@knight_value_b = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@bishop_value_w = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@bishop_mobility_rl45 = external global [64 x [256 x i32]] ; <[64 x [256 x i32]]*> [#uses=0]
-@bishop_mobility_rr45 = external global [64 x [256 x i32]] ; <[64 x [256 x i32]]*> [#uses=0]
-@bishop_value_b = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@rook_value_w = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@plus8dir = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@mask_abs7_w = external global i64 ; <i64*> [#uses=0]
-@rook_value_b = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@minus8dir = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@mask_abs7_b = external global i64 ; <i64*> [#uses=0]
-@queen_value_w = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@queen_value_b = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@white_minor_pieces = external global i64 ; <i64*> [#uses=0]
-@black_minor_pieces = external global i64 ; <i64*> [#uses=0]
-@not_rook_pawns = external global i64 ; <i64*> [#uses=0]
-@dark_squares = external global i64 ; <i64*> [#uses=0]
-@b_n_mate_dark_squares = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@b_n_mate_light_squares = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@mate = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@first_ones_8bit = external global [256 x i8] ; <[256 x i8]*> [#uses=0]
-@reduced_material_passer = external global [20 x i32] ; <[20 x i32]*> [#uses=0]
-@supported_passer = external global [8 x i32] ; <[8 x i32]*> [#uses=0]
-@passed_pawn_value = external global [8 x i32] ; <[8 x i32]*> [#uses=0]
-@connected_passed = external global [256 x i8] ; <[256 x i8]*> [#uses=0]
-@black_pawn_race_btm = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@white_pawn_race_wtm = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@black_pawn_race_wtm = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@white_pawn_race_btm = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@obstructed = external global [64 x [64 x i64]] ; <[64 x [64 x i64]]*> [#uses=0]
-@pawn_hash_table = external global %typedef.PAWN_HASH_ENTRY* ; <%typedef.PAWN_HASH_ENTRY**> [#uses=0]
-@pawn_hash_mask = external global i32 ; <i32*> [#uses=0]
-@pawn_value_w = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@mask_pawn_isolated = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@mask_pawn_passed_w = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@mask_pawn_protected_w = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@pawn_value_b = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@mask_pawn_passed_b = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@mask_pawn_protected_b = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@unblocked_pawns = external global [9 x i32] ; <[9 x i32]*> [#uses=0]
-@mask_wk_4th = external global i64 ; <i64*> [#uses=0]
-@mask_wk_5th = external global i64 ; <i64*> [#uses=0]
-@mask_wq_4th = external global i64 ; <i64*> [#uses=0]
-@mask_wq_5th = external global i64 ; <i64*> [#uses=0]
-@stonewall_white = external global i64 ; <i64*> [#uses=0]
-@mask_bk_4th = external global i64 ; <i64*> [#uses=0]
-@mask_bk_5th = external global i64 ; <i64*> [#uses=0]
-@mask_bq_5th = external global i64 ; <i64*> [#uses=0]
-@mask_bq_4th = external global i64 ; <i64*> [#uses=0]
-@stonewall_black = external global i64 ; <i64*> [#uses=0]
-@last_ones_8bit = external global [256 x i8] ; <[256 x i8]*> [#uses=0]
-@right_side_mask = external global [8 x i64] ; <[8 x i64]*> [#uses=0]
-@left_side_empty_mask = external global [8 x i64] ; <[8 x i64]*> [#uses=0]
-@left_side_mask = external global [8 x i64] ; <[8 x i64]*> [#uses=0]
-@right_side_empty_mask = external global [8 x i64] ; <[8 x i64]*> [#uses=0]
-@pv = external global [65 x %typedef.CHESS_PATH] ; <[65 x %typedef.CHESS_PATH]*> [#uses=0]
-@history_w = external global [4096 x i32] ; <[4096 x i32]*> [#uses=0]
-@history_b = external global [4096 x i32] ; <[4096 x i32]*> [#uses=0]
-@killer_move1 = external global [65 x i32] ; <[65 x i32]*> [#uses=0]
-@killer_count1 = external global [65 x i32] ; <[65 x i32]*> [#uses=0]
-@killer_move2 = external global [65 x i32] ; <[65 x i32]*> [#uses=0]
-@killer_count2 = external global [65 x i32] ; <[65 x i32]*> [#uses=0]
-@current_move = external global [65 x i32] ; <[65 x i32]*> [#uses=0]
-@init_r90 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@init_l90 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@init_l45 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@init_ul45 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@init_r45 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@init_ur45 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@diagonal_length = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@last = external global [65 x i32*] ; <[65 x i32*]*> [#uses=0]
-@move_list = external global [5120 x i32] ; <[5120 x i32]*> [#uses=0]
-@history_file = external global %struct.__sFILE* ; <%struct.__sFILE**> [#uses=0]
-@.str_1.upgrd.1 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_2.upgrd.2 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_3.upgrd.3 = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@.str_5.upgrd.4 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_6.upgrd.5 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@trans_ref_wa = external global %typedef.HASH_ENTRY* ; <%typedef.HASH_ENTRY**> [#uses=0]
-@hash_table_size = external global i32 ; <i32*> [#uses=0]
-@trans_ref_wb = external global %typedef.HASH_ENTRY* ; <%typedef.HASH_ENTRY**> [#uses=0]
-@trans_ref_ba = external global %typedef.HASH_ENTRY* ; <%typedef.HASH_ENTRY**> [#uses=0]
-@trans_ref_bb = external global %typedef.HASH_ENTRY* ; <%typedef.HASH_ENTRY**> [#uses=0]
-@pawn_hash_table_size = external global i32 ; <i32*> [#uses=0]
-@.str_9.upgrd.6 = external global [37 x i8] ; <[37 x i8]*> [#uses=0]
-@log_hash = external global i32 ; <i32*> [#uses=0]
-@log_pawn_hash = external global i32 ; <i32*> [#uses=0]
-@hash_maska = external global i32 ; <i32*> [#uses=0]
-@hash_maskb = external global i32 ; <i32*> [#uses=0]
-@mask_1 = external global i64 ; <i64*> [#uses=0]
-@bishop_attacks = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@queen_attacks = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@plus7dir = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@plus9dir = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@minus7dir = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@minus9dir = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@plus1dir = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@minus1dir = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@rook_attacks = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@king_attacks_1 = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@king_attacks_2 = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@.ctor_1.upgrd.7 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@.ctor_2 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@rook_mobility_r0 = external global [64 x [256 x i32]] ; <[64 x [256 x i32]]*> [#uses=0]
-@rook_mobility_rl90 = external global [64 x [256 x i32]] ; <[64 x [256 x i32]]*> [#uses=0]
-@initial_position = external global [80 x i8] ; <[80 x i8]*> [#uses=5]
-@"\01a1.0__" = external global [80 x i8] ; <[80 x i8]*> [#uses=0]
-@"\01a2.1__" = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@"\01a3.2__" = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@"\01a4.3__" = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@"\01a5.4__" = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@"\01args.5__" = external global [16 x i8*] ; <[16 x i8*]*> [#uses=0]
-@.str_10.upgrd.8 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@w_pawn_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@w_pawn_random32 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@b_pawn_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@b_pawn_random32 = external global [64 x i32] ; <[64 x i32]*> [#uses=0]
-@w_knight_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@b_knight_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@w_bishop_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@b_bishop_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@w_rook_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@b_rook_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@w_queen_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@b_queen_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@w_king_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@b_king_random = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@enpassant_random = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@castle_random_w = external global [2 x i64] ; <[2 x i64]*> [#uses=0]
-@castle_random_b = external global [2 x i64] ; <[2 x i64]*> [#uses=0]
-@set_mask_rl90 = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@set_mask_rl45 = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@set_mask_rr45 = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@transposition_id = external global i8 ; <i8*> [#uses=0]
-@mask_2 = external global i64 ; <i64*> [#uses=0]
-@mask_3 = external global i64 ; <i64*> [#uses=0]
-@mask_4 = external global i64 ; <i64*> [#uses=0]
-@mask_8 = external global i64 ; <i64*> [#uses=0]
-@mask_16 = external global i64 ; <i64*> [#uses=0]
-@mask_32 = external global i64 ; <i64*> [#uses=0]
-@mask_72 = external global i64 ; <i64*> [#uses=0]
-@mask_80 = external global i64 ; <i64*> [#uses=0]
-@mask_85 = external global i64 ; <i64*> [#uses=0]
-@mask_96 = external global i64 ; <i64*> [#uses=0]
-@mask_107 = external global i64 ; <i64*> [#uses=0]
-@mask_108 = external global i64 ; <i64*> [#uses=0]
-@mask_112 = external global i64 ; <i64*> [#uses=0]
-@mask_118 = external global i64 ; <i64*> [#uses=0]
-@mask_120 = external global i64 ; <i64*> [#uses=0]
-@mask_121 = external global i64 ; <i64*> [#uses=0]
-@mask_127 = external global i64 ; <i64*> [#uses=0]
-@mask_clear_entry = external global i64 ; <i64*> [#uses=0]
-@clear_mask_rl45 = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@clear_mask_rr45 = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@clear_mask_rl90 = external global [65 x i64] ; <[65 x i64]*> [#uses=0]
-@right_half_mask = external global i64 ; <i64*> [#uses=0]
-@left_half_mask = external global i64 ; <i64*> [#uses=0]
-@mask_not_rank8 = external global i64 ; <i64*> [#uses=0]
-@mask_not_rank1 = external global i64 ; <i64*> [#uses=0]
-@center = external global i64 ; <i64*> [#uses=0]
-@mask_pawn_connected = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@mask_eptest = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@mask_kingside_attack_w1 = external global i64 ; <i64*> [#uses=0]
-@mask_kingside_attack_w2 = external global i64 ; <i64*> [#uses=0]
-@mask_queenside_attack_w1 = external global i64 ; <i64*> [#uses=0]
-@mask_queenside_attack_w2 = external global i64 ; <i64*> [#uses=0]
-@mask_kingside_attack_b1 = external global i64 ; <i64*> [#uses=0]
-@mask_kingside_attack_b2 = external global i64 ; <i64*> [#uses=0]
-@mask_queenside_attack_b1 = external global i64 ; <i64*> [#uses=0]
-@mask_queenside_attack_b2 = external global i64 ; <i64*> [#uses=0]
-@pawns_cramp_black = external global i64 ; <i64*> [#uses=0]
-@pawns_cramp_white = external global i64 ; <i64*> [#uses=0]
-@light_squares = external global i64 ; <i64*> [#uses=0]
-@mask_left_edge = external global i64 ; <i64*> [#uses=0]
-@mask_right_edge = external global i64 ; <i64*> [#uses=0]
-@mask_advance_2_w = external global i64 ; <i64*> [#uses=0]
-@mask_advance_2_b = external global i64 ; <i64*> [#uses=0]
-@mask_corner_squares = external global i64 ; <i64*> [#uses=0]
-@mask_promotion_threat_w = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@mask_promotion_threat_b = external global [64 x i64] ; <[64 x i64]*> [#uses=0]
-@promote_mask_w = external global i64 ; <i64*> [#uses=0]
-@promote_mask_b = external global i64 ; <i64*> [#uses=0]
-@mask_a1_corner = external global i64 ; <i64*> [#uses=0]
-@mask_h1_corner = external global i64 ; <i64*> [#uses=0]
-@mask_a8_corner = external global i64 ; <i64*> [#uses=0]
-@mask_h8_corner = external global i64 ; <i64*> [#uses=0]
-@white_center_pawns = external global i64 ; <i64*> [#uses=0]
-@black_center_pawns = external global i64 ; <i64*> [#uses=0]
-@wtm_random = external global [2 x i64] ; <[2 x i64]*> [#uses=0]
-@endgame_random_w = external global i64 ; <i64*> [#uses=0]
-@endgame_random_b = external global i64 ; <i64*> [#uses=0]
-@w_rooks_random = external global i64 ; <i64*> [#uses=0]
-@b_rooks_random = external global i64 ; <i64*> [#uses=0]
-@.ctor_11 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.ctor_2.upgrd.9 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_1.upgrd.10 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_2.upgrd.11 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_32 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_4.upgrd.12 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_5.upgrd.13 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_6.upgrd.14 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_7.upgrd.15 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_8.upgrd.16 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_9.upgrd.17 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_10.upgrd.18 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_11.upgrd.19 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_12.upgrd.20 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_13 = external global [15 x i8] ; <[15 x i8]*> [#uses=0]
-@num_ponder_moves = external global i32 ; <i32*> [#uses=0]
-@ponder_moves = external global [220 x i32] ; <[220 x i32]*> [#uses=0]
-@.str_14.upgrd.21 = external global [15 x i8] ; <[15 x i8]*> [#uses=0]
-@.str_15 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_16 = external global [20 x i8] ; <[20 x i8]*> [#uses=0]
-@auto232 = external global i32 ; <i32*> [#uses=0]
-@puzzling = external global i8 ; <i8*> [#uses=0]
-@abort_search = external global i8 ; <i8*> [#uses=0]
-@.str_24 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@wtm = external global i32 ; <i32*> [#uses=0]
-@.str_3.upgrd.22 = external global [15 x i8] ; <[15 x i8]*> [#uses=0]
-@.str_4.upgrd.23 = external global [15 x i8] ; <[15 x i8]*> [#uses=0]
-@end_time = external global i32 ; <i32*> [#uses=0]
-@time_type = external global i32 ; <i32*> [#uses=0]
-@start_time = external global i32 ; <i32*> [#uses=0]
-@.str_6.upgrd.24 = external global [12 x i8] ; <[12 x i8]*> [#uses=0]
-@.str_7.upgrd.25 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@nodes_searched = external global i32 ; <i32*> [#uses=0]
-@iteration_depth = external global i32 ; <i32*> [#uses=0]
-@searched_this_root_move = external global [256 x i8] ; <[256 x i8]*> [#uses=0]
-@.str_9.upgrd.26 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_10.upgrd.27 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_11.upgrd.28 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_12.upgrd.29 = external global [12 x i8] ; <[12 x i8]*> [#uses=0]
-@.str_14.upgrd.30 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_16.upgrd.31 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@thinking = external global i8 ; <i8*> [#uses=0]
-@time_abort = external global i32 ; <i32*> [#uses=0]
-@.str_17 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@analyze_move_read = external global i32 ; <i32*> [#uses=0]
-@analyze_mode = external global i32 ; <i32*> [#uses=0]
-@pondering = external global i8 ; <i8*> [#uses=0]
-@auto232_delay = external global i32 ; <i32*> [#uses=0]
-@auto_file = external global %struct.__sFILE* ; <%struct.__sFILE**> [#uses=0]
-@.str_19 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_20 = external global [11 x i8] ; <[11 x i8]*> [#uses=0]
-@.str_21 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@ponder_move = external global i32 ; <i32*> [#uses=0]
-@predicted = external global i32 ; <i32*> [#uses=0]
-@made_predicted_move = external global i32 ; <i32*> [#uses=0]
-@opponent_end_time = external global i32 ; <i32*> [#uses=0]
-@program_start_time = external global i32 ; <i32*> [#uses=0]
-@.str_23 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_24.upgrd.32 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_25 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_26 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_28 = external global [31 x i8] ; <[31 x i8]*> [#uses=0]
-@book_move = external global i32 ; <i32*> [#uses=0]
-@elapsed_start = external global i32 ; <i32*> [#uses=0]
-@burp = external global i32 ; <i32*> [#uses=0]
-@cpu_percent = external global i32 ; <i32*> [#uses=0]
-@next_time_check = external global i32 ; <i32*> [#uses=0]
-@nodes_between_time_checks = external global i32 ; <i32*> [#uses=0]
-@transposition_hits = external global i32 ; <i32*> [#uses=0]
-@transposition_probes = external global i32 ; <i32*> [#uses=0]
-@tb_probes = external global i32 ; <i32*> [#uses=0]
-@tb_probes_successful = external global i32 ; <i32*> [#uses=0]
-@check_extensions_done = external global i32 ; <i32*> [#uses=0]
-@recapture_extensions_done = external global i32 ; <i32*> [#uses=0]
-@passed_pawn_extensions_done = external global i32 ; <i32*> [#uses=0]
-@one_reply_extensions_done = external global i32 ; <i32*> [#uses=0]
-@program_end_time = external global i32 ; <i32*> [#uses=0]
-@root_value = external global i32 ; <i32*> [#uses=0]
-@last_search_value = external global i32 ; <i32*> [#uses=0]
-@.str_1.upgrd.33 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@.str_2.upgrd.34 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@booking = external global i8 ; <i8*> [#uses=0]
-@annotate_mode = external global i32 ; <i32*> [#uses=0]
-@.str_4.upgrd.35 = external global [38 x i8] ; <[38 x i8]*> [#uses=0]
-@.str_5.upgrd.36 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@last_pv = external global %typedef.CHESS_PATH ; <%typedef.CHESS_PATH*> [#uses=0]
-@.str_8.upgrd.37 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@root_alpha = external global i32 ; <i32*> [#uses=0]
-@last_value = external global i32 ; <i32*> [#uses=0]
-@root_beta = external global i32 ; <i32*> [#uses=0]
-@root_nodes = external global [256 x i32] ; <[256 x i32]*> [#uses=0]
-@trace_level = external global i32 ; <i32*> [#uses=0]
-@.str_9.upgrd.38 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_10.upgrd.39 = external global [37 x i8] ; <[37 x i8]*> [#uses=0]
-@search_failed_high = external global i32 ; <i32*> [#uses=0]
-@search_failed_low = external global i32 ; <i32*> [#uses=0]
-@nodes_per_second = external global i32 ; <i32*> [#uses=0]
-@time_limit = external global i32 ; <i32*> [#uses=0]
-@easy_move = external global i32 ; <i32*> [#uses=0]
-@noise_level = external global i32 ; <i32*> [#uses=0]
-@.str_12.upgrd.40 = external global [34 x i8] ; <[34 x i8]*> [#uses=0]
-@.str_136 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@solution_type = external global i32 ; <i32*> [#uses=0]
-@number_of_solutions = external global i32 ; <i32*> [#uses=0]
-@solutions = external global [10 x i32] ; <[10 x i32]*> [#uses=0]
-@early_exit = external global i32 ; <i32*> [#uses=0]
-@.str_14.upgrd.41 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_15.upgrd.42 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_16.upgrd.43 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@whisper_value = external global i32 ; <i32*> [#uses=0]
-@.str_17.upgrd.44 = external global [29 x i8] ; <[29 x i8]*> [#uses=0]
-@.str_19.upgrd.45 = external global [37 x i8] ; <[37 x i8]*> [#uses=0]
-@last_mate_score = external global i32 ; <i32*> [#uses=0]
-@search_depth = external global i32 ; <i32*> [#uses=0]
-@elapsed_end = external global i32 ; <i32*> [#uses=0]
-@.str_20.upgrd.46 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_21.upgrd.47 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_22 = external global [13 x i8] ; <[13 x i8]*> [#uses=0]
-@.str_23.upgrd.48 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_24.upgrd.49 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@.str_25.upgrd.50 = external global [67 x i8] ; <[67 x i8]*> [#uses=0]
-@.str_26.upgrd.51 = external global [69 x i8] ; <[69 x i8]*> [#uses=0]
-@hash_move = external global [65 x i32] ; <[65 x i32]*> [#uses=0]
-@version = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@mode = external global i32 ; <i32*> [#uses=0]
-@batch_mode = external global i32 ; <i32*> [#uses=0]
-@crafty_rating = external global i32 ; <i32*> [#uses=0]
-@opponent_rating = external global i32 ; <i32*> [#uses=0]
-@pgn_event = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@pgn_site = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@pgn_date = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@pgn_round = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@pgn_white = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@pgn_white_elo = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@pgn_black = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@pgn_black_elo = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@pgn_result = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@number_auto_kibitzers = external global i32 ; <i32*> [#uses=0]
-@auto_kibitz_list = external global [100 x [20 x i8]] ; <[100 x [20 x i8]]*> [#uses=0]
-@number_of_computers = external global i32 ; <i32*> [#uses=0]
-@computer_list = external global [100 x [20 x i8]] ; <[100 x [20 x i8]]*> [#uses=0]
-@number_of_GMs = external global i32 ; <i32*> [#uses=0]
-@GM_list = external global [100 x [20 x i8]] ; <[100 x [20 x i8]]*> [#uses=0]
-@number_of_IMs = external global i32 ; <i32*> [#uses=0]
-@IM_list = external global [100 x [20 x i8]] ; <[100 x [20 x i8]]*> [#uses=0]
-@ics = external global i32 ; <i32*> [#uses=0]
-@output_format = external global i32 ; <i32*> [#uses=0]
-@EGTBlimit = external global i32 ; <i32*> [#uses=0]
-@whisper = external global i32 ; <i32*> [#uses=0]
-@channel = external global i32 ; <i32*> [#uses=0]
-@new_game = external global i32 ; <i32*> [#uses=0]
-@channel_title = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@initialized = external global i32 ; <i32*> [#uses=0]
-@kibitz = external global i32 ; <i32*> [#uses=0]
-@post = external global i32 ; <i32*> [#uses=0]
-@log_id = external global i32 ; <i32*> [#uses=0]
-@crafty_is_white = external global i32 ; <i32*> [#uses=0]
-@last_opponent_move = external global i32 ; <i32*> [#uses=0]
-@search_move = external global i32 ; <i32*> [#uses=0]
-@time_used = external global i32 ; <i32*> [#uses=0]
-@time_used_opponent = external global i32 ; <i32*> [#uses=0]
-@auto_kibitzing = external global i32 ; <i32*> [#uses=0]
-@test_mode = external global i32 ; <i32*> [#uses=0]
-@resign = external global i8 ; <i8*> [#uses=0]
-@resign_counter = external global i8 ; <i8*> [#uses=0]
-@resign_count = external global i8 ; <i8*> [#uses=0]
-@draw_counter = external global i8 ; <i8*> [#uses=0]
-@draw_count = external global i8 ; <i8*> [#uses=0]
-@tc_moves = external global i32 ; <i32*> [#uses=0]
-@tc_time = external global i32 ; <i32*> [#uses=0]
-@tc_time_remaining = external global i32 ; <i32*> [#uses=0]
-@tc_moves_remaining = external global i32 ; <i32*> [#uses=0]
-@tc_secondary_moves = external global i32 ; <i32*> [#uses=0]
-@tc_secondary_time = external global i32 ; <i32*> [#uses=0]
-@tc_sudden_death = external global i32 ; <i32*> [#uses=0]
-@tc_operator_time = external global i32 ; <i32*> [#uses=0]
-@tc_safety_margin = external global i32 ; <i32*> [#uses=0]
-@force = external global i32 ; <i32*> [#uses=0]
-@over = external global i32 ; <i32*> [#uses=0]
-@usage_level = external global i32 ; <i32*> [#uses=0]
-@audible_alarm = external global i8 ; <i8*> [#uses=0]
-@ansi = external global i32 ; <i32*> [#uses=0]
-@book_accept_mask = external global i32 ; <i32*> [#uses=0]
-@book_reject_mask = external global i32 ; <i32*> [#uses=0]
-@book_random = external global i32 ; <i32*> [#uses=0]
-@book_search_trigger = external global i32 ; <i32*> [#uses=0]
-@learning = external global i32 ; <i32*> [#uses=0]
-@show_book = external global i32 ; <i32*> [#uses=0]
-@book_selection_width = external global i32 ; <i32*> [#uses=0]
-@ponder = external global i32 ; <i32*> [#uses=0]
-@verbosity_level = external global i32 ; <i32*> [#uses=0]
-@push_extensions = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@.str_28.upgrd.52 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_3.upgrd.53 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@display = external global %typedef.CHESS_POSITION ; <%typedef.CHESS_POSITION*> [#uses=0]
-@.str_4.upgrd.54 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@opponent_start_time = external global i32 ; <i32*> [#uses=0]
-@.str_8.upgrd.55 = external global [12 x i8] ; <[12 x i8]*> [#uses=0]
-@.str_9.upgrd.56 = external global [12 x i8] ; <[12 x i8]*> [#uses=0]
-@.str_18 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_19.upgrd.57 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_2013 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_21.upgrd.58 = external global [41 x i8] ; <[41 x i8]*> [#uses=0]
-@.str_22.upgrd.59 = external global [29 x i8] ; <[29 x i8]*> [#uses=0]
-@.str_23.upgrd.60 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@whisper_text = external global [500 x i8] ; <[500 x i8]*> [#uses=0]
-@.str_24.upgrd.61 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_25.upgrd.62 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_26.upgrd.63 = external global [11 x i8] ; <[11 x i8]*> [#uses=0]
-@.str_28.upgrd.64 = external global [13 x i8] ; <[13 x i8]*> [#uses=0]
-@.str_29 = external global [13 x i8] ; <[13 x i8]*> [#uses=0]
-@.str_30 = external global [33 x i8] ; <[33 x i8]*> [#uses=0]
-@.str_31 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_32.upgrd.65 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_36 = external global [3 x i8] ; <[3 x i8]*> [#uses=1]
-@.str_37 = external global [15 x i8] ; <[15 x i8]*> [#uses=0]
-@.str_44 = external global [12 x i8] ; <[12 x i8]*> [#uses=0]
-@.str_45 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_49 = external global [15 x i8] ; <[15 x i8]*> [#uses=0]
-@.str_52 = external global [12 x i8] ; <[12 x i8]*> [#uses=0]
-@previous_search_value = external global i32 ; <i32*> [#uses=0]
-@.str_64 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@whisper_depth = external global i32 ; <i32*> [#uses=0]
-@.str_65 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_66 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@total_moves = external global i32 ; <i32*> [#uses=0]
-@book_file = external global %struct.__sFILE* ; <%struct.__sFILE**> [#uses=0]
-@books_file = external global %struct.__sFILE* ; <%struct.__sFILE**> [#uses=0]
-@book_lrn_file = external global %struct.__sFILE* ; <%struct.__sFILE**> [#uses=0]
-@position_file = external global %struct.__sFILE* ; <%struct.__sFILE**> [#uses=0]
-@position_lrn_file = external global %struct.__sFILE* ; <%struct.__sFILE**> [#uses=0]
-@log_filename = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@history_filename = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@book_path = external global [128 x i8] ; <[128 x i8]*> [#uses=0]
-@log_path = external global [128 x i8] ; <[128 x i8]*> [#uses=0]
-@tb_path = external global [128 x i8] ; <[128 x i8]*> [#uses=0]
-@cmd_buffer = external global [512 x i8] ; <[512 x i8]*> [#uses=0]
-@root_move = external global i32 ; <i32*> [#uses=0]
-@hint = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@absolute_time_limit = external global i32 ; <i32*> [#uses=0]
-@search_time_limit = external global i32 ; <i32*> [#uses=0]
-@in_check = external global [65 x i8] ; <[65 x i8]*> [#uses=0]
-@extended_reason = external global [65 x i8] ; <[65 x i8]*> [#uses=0]
-@current_phase = external global [65 x i8] ; <[65 x i8]*> [#uses=0]
-@sort_value = external global [256 x i32] ; <[256 x i32]*> [#uses=0]
-@next_status = external global [65 x %typedef.NEXT_MOVE] ; <[65 x %typedef.NEXT_MOVE]*> [#uses=0]
-@save_hash_key = external global [67 x i64] ; <[67 x i64]*> [#uses=0]
-@save_pawn_hash_key = external global [67 x i32] ; <[67 x i32]*> [#uses=0]
-@pawn_advance = external global [8 x i32] ; <[8 x i32]*> [#uses=0]
-@bit_move = external global i64 ; <i64*> [#uses=0]
-@.str_1.upgrd.66 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_2.upgrd.67 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_3.upgrd.68 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_1.upgrd.69 = external global [34 x i8] ; <[34 x i8]*> [#uses=0]
-@.str_2.upgrd.70 = external global [46 x i8] ; <[46 x i8]*> [#uses=0]
-@.str_2.upgrd.71 = external global [47 x i8] ; <[47 x i8]*> [#uses=0]
-@.str_1.upgrd.72 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_2.upgrd.73 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_3.upgrd.74 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_4.upgrd.75 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_5.upgrd.76 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_615 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_7.upgrd.77 = external global [21 x i8] ; <[21 x i8]*> [#uses=0]
-@.str_10.upgrd.78 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_11.upgrd.79 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_12.upgrd.80 = external global [18 x i8] ; <[18 x i8]*> [#uses=0]
-@.str_1318 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_1419 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_15.upgrd.81 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_16.upgrd.82 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_19.upgrd.83 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_20.upgrd.84 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_2222 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_2323 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_25.upgrd.85 = external global [29 x i8] ; <[29 x i8]*> [#uses=0]
-@.str_27 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@.str_28.upgrd.86 = external global [42 x i8] ; <[42 x i8]*> [#uses=0]
-@.str_29.upgrd.87 = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@.str_30.upgrd.88 = external global [27 x i8] ; <[27 x i8]*> [#uses=0]
-@.str_31.upgrd.89 = external global [18 x i8] ; <[18 x i8]*> [#uses=0]
-@.str_32.upgrd.90 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_33 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_34 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_35 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_36.upgrd.91 = external global [46 x i8] ; <[46 x i8]*> [#uses=0]
-@.str_37.upgrd.92 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_38 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_41 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_42 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_43 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_44.upgrd.93 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_4525 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_46 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_47 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_48 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_49.upgrd.94 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_50 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_51 = external global [25 x i8] ; <[25 x i8]*> [#uses=0]
-@.str_52.upgrd.95 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_53 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_54 = external global [23 x i8] ; <[23 x i8]*> [#uses=0]
-@.str_55 = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@.str_56 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_57 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_58 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_59 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_60 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_61 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_62 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_63 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_64.upgrd.96 = external global [37 x i8] ; <[37 x i8]*> [#uses=0]
-@.str_66.upgrd.97 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_67 = external global [21 x i8] ; <[21 x i8]*> [#uses=0]
-@.str_68 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_69 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_71 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_72 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_73 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_74 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_75 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_81 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_83 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_84 = external global [23 x i8] ; <[23 x i8]*> [#uses=0]
-@.str_86 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_87 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_89 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_90 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_91 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_92 = external global [47 x i8] ; <[47 x i8]*> [#uses=0]
-@.str_94 = external global [37 x i8] ; <[37 x i8]*> [#uses=0]
-@.str_95 = external global [33 x i8] ; <[33 x i8]*> [#uses=0]
-@.str_96 = external global [34 x i8] ; <[34 x i8]*> [#uses=0]
-@.str_97 = external global [33 x i8] ; <[33 x i8]*> [#uses=0]
-@.str_98 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_100 = external global [42 x i8] ; <[42 x i8]*> [#uses=0]
-@.str_101 = external global [38 x i8] ; <[38 x i8]*> [#uses=0]
-@.str_102 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_103 = external global [38 x i8] ; <[38 x i8]*> [#uses=0]
-@.str_104 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_105 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_106 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_107 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_108 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_109 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_110 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_111 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_112 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_113 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_114 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_115 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@.str_116 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_117 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_118 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_119 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_120 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_121 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_122 = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@.str_123 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_124 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_125 = external global [65 x i8] ; <[65 x i8]*> [#uses=0]
-@.str_126 = external global [65 x i8] ; <[65 x i8]*> [#uses=0]
-@.str_127 = external global [69 x i8] ; <[69 x i8]*> [#uses=0]
-@.str_128 = external global [66 x i8] ; <[66 x i8]*> [#uses=0]
-@.str_129 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_130 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_131 = external global [67 x i8] ; <[67 x i8]*> [#uses=0]
-@.str_132 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_133 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_134 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_135 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_136.upgrd.98 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_137 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_138 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_139 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_140 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_141 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_142 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_143 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_144 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_145 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_146 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_147 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_148 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_149 = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@.str_150 = external global [65 x i8] ; <[65 x i8]*> [#uses=0]
-@.str_151 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_152 = external global [46 x i8] ; <[46 x i8]*> [#uses=0]
-@.str_153 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_154 = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@.str_156 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_157 = external global [31 x i8] ; <[31 x i8]*> [#uses=0]
-@.str_158 = external global [71 x i8] ; <[71 x i8]*> [#uses=0]
-@.str_159 = external global [72 x i8] ; <[72 x i8]*> [#uses=0]
-@.str_160 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_161 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_162 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_163 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_164 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_165 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_166 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_167 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_168 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_169 = external global [65 x i8] ; <[65 x i8]*> [#uses=0]
-@.str_170 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_171 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_172 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_173 = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@.str_174 = external global [51 x i8] ; <[51 x i8]*> [#uses=0]
-@.str_175 = external global [70 x i8] ; <[70 x i8]*> [#uses=0]
-@.str_176 = external global [67 x i8] ; <[67 x i8]*> [#uses=0]
-@.str_177 = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@.str_178 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@.str_180 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_181 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_182 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_183 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_184 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_185 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_186 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_187 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_188 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_189 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_190 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_191 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_192 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_193 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@.str_194 = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@.str_195 = external global [33 x i8] ; <[33 x i8]*> [#uses=0]
-@.str_196 = external global [46 x i8] ; <[46 x i8]*> [#uses=0]
-@.str_197 = external global [11 x i8] ; <[11 x i8]*> [#uses=0]
-@.str_198 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_201 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_202 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_203 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_204 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_206 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@.str_207 = external global [46 x i8] ; <[46 x i8]*> [#uses=0]
-@.str_208 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_209 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_210 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_211 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_213 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_214 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_215 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_216 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@.str_218 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_219 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_220 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_221 = external global [37 x i8] ; <[37 x i8]*> [#uses=0]
-@.str_222 = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@.str_223 = external global [66 x i8] ; <[66 x i8]*> [#uses=0]
-@.str_224 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_225 = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@.str_226 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_227 = external global [46 x i8] ; <[46 x i8]*> [#uses=0]
-@.str_228 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_229 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_230 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_231 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_232 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_233 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_234 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_235 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_236 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_237 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_238 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_239 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_240 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_241 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_242 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_243 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_245 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_246 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_247 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_248 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_249 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_250 = external global [45 x i8] ; <[45 x i8]*> [#uses=0]
-@.str_253 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_254 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_256 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_258 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_259 = external global [27 x i8] ; <[27 x i8]*> [#uses=0]
-@.str_261 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_262 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_263 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_266 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_267 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_268 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_270 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_271 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_272 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_273 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_274 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_275 = external global [44 x i8] ; <[44 x i8]*> [#uses=0]
-@.str_276 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_277 = external global [21 x i8] ; <[21 x i8]*> [#uses=0]
-@.str_278 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@.str_279 = external global [51 x i8] ; <[51 x i8]*> [#uses=0]
-@.str_280 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_281 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_282 = external global [50 x i8] ; <[50 x i8]*> [#uses=0]
-@.str_283 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_284 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_285 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@.str_286 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_287 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_288 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_289 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_290 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_291 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_292 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_293 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_294 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_295 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_296 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_297 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_298 = external global [51 x i8] ; <[51 x i8]*> [#uses=0]
-@.str_299 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_300 = external global [49 x i8] ; <[49 x i8]*> [#uses=0]
-@.str_301 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_302 = external global [18 x i8] ; <[18 x i8]*> [#uses=0]
-@.str_304 = external global [50 x i8] ; <[50 x i8]*> [#uses=0]
-@.str_305 = external global [50 x i8] ; <[50 x i8]*> [#uses=0]
-@.str_306 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_308 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_310 = external global [50 x i8] ; <[50 x i8]*> [#uses=0]
-@.str_311 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_312 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_313 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_314 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_315 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_316 = external global [51 x i8] ; <[51 x i8]*> [#uses=0]
-@.str_317 = external global [26 x i8] ; <[26 x i8]*> [#uses=0]
-@.str_319 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_320 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_321 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_322 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@.str_323 = external global [20 x i8] ; <[20 x i8]*> [#uses=0]
-@.str_325 = external global [26 x i8] ; <[26 x i8]*> [#uses=0]
-@.str_327 = external global [51 x i8] ; <[51 x i8]*> [#uses=0]
-@.str_328 = external global [51 x i8] ; <[51 x i8]*> [#uses=0]
-@.str_329 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_330 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_331 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_332 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_333 = external global [50 x i8] ; <[50 x i8]*> [#uses=0]
-@.str_334 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_335 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@.str_336 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_337 = external global [50 x i8] ; <[50 x i8]*> [#uses=0]
-@.str_338 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_339 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_340 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@.str_341 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_342 = external global [49 x i8] ; <[49 x i8]*> [#uses=0]
-@.str_343 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_344 = external global [49 x i8] ; <[49 x i8]*> [#uses=0]
-@.str_345 = external global [47 x i8] ; <[47 x i8]*> [#uses=0]
-@.str_346 = external global [49 x i8] ; <[49 x i8]*> [#uses=0]
-@.str_347 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_348 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_349 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_350 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@.str_351 = external global [47 x i8] ; <[47 x i8]*> [#uses=0]
-@.str_352 = external global [49 x i8] ; <[49 x i8]*> [#uses=0]
-@.str_353 = external global [49 x i8] ; <[49 x i8]*> [#uses=0]
-@.str_354 = external global [42 x i8] ; <[42 x i8]*> [#uses=0]
-@.str_355 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_356 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_357 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_358 = external global [47 x i8] ; <[47 x i8]*> [#uses=0]
-@.str_359 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_360 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_362 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_363 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_364 = external global [56 x i8] ; <[56 x i8]*> [#uses=0]
-@.str_365 = external global [51 x i8] ; <[51 x i8]*> [#uses=0]
-@.str_366 = external global [64 x i8] ; <[64 x i8]*> [#uses=0]
-@.str_367 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_368 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@.str_369 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_370 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_371 = external global [49 x i8] ; <[49 x i8]*> [#uses=0]
-@.str_372 = external global [58 x i8] ; <[58 x i8]*> [#uses=0]
-@.str_373 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_374 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_375 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_376 = external global [63 x i8] ; <[63 x i8]*> [#uses=0]
-@.str_377 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_378 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_379 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_380 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_381 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_382 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_383 = external global [49 x i8] ; <[49 x i8]*> [#uses=0]
-@.str_384 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_385 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_387 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_388 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_389 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_390 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@.str_391 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@.str_392 = external global [71 x i8] ; <[71 x i8]*> [#uses=0]
-@.str_393 = external global [46 x i8] ; <[46 x i8]*> [#uses=0]
-@.str_394 = external global [51 x i8] ; <[51 x i8]*> [#uses=0]
-@.str_395 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_396 = external global [60 x i8] ; <[60 x i8]*> [#uses=0]
-@.str_397 = external global [49 x i8] ; <[49 x i8]*> [#uses=0]
-@.str_398 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_399 = external global [67 x i8] ; <[67 x i8]*> [#uses=0]
-@.str_400 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@.str_401 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_402 = external global [62 x i8] ; <[62 x i8]*> [#uses=0]
-@.str_403 = external global [47 x i8] ; <[47 x i8]*> [#uses=0]
-@.str_404 = external global [59 x i8] ; <[59 x i8]*> [#uses=0]
-@.str_405 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_406 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_407 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_408 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_409 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_410 = external global [26 x i8] ; <[26 x i8]*> [#uses=0]
-@.str_411 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_412 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_413 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_414 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_421 = external global [53 x i8] ; <[53 x i8]*> [#uses=0]
-@.str_422 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@.str_423 = external global [23 x i8] ; <[23 x i8]*> [#uses=0]
-@.str_424 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_426 = external global [42 x i8] ; <[42 x i8]*> [#uses=0]
-@.str_427 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_429 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_430 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@.str_431 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_432 = external global [23 x i8] ; <[23 x i8]*> [#uses=0]
-@.str_433 = external global [23 x i8] ; <[23 x i8]*> [#uses=0]
-@.str_434 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@.str_435 = external global [27 x i8] ; <[27 x i8]*> [#uses=0]
-@.str_436 = external global [28 x i8] ; <[28 x i8]*> [#uses=0]
-@.str_437 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_438 = external global [38 x i8] ; <[38 x i8]*> [#uses=0]
-@.str_440 = external global [44 x i8] ; <[44 x i8]*> [#uses=0]
-@.str_445 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_446 = external global [26 x i8] ; <[26 x i8]*> [#uses=0]
-@.str_447 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_448 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_449 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_450 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_451 = external global [44 x i8] ; <[44 x i8]*> [#uses=0]
-@.str_452 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_453 = external global [26 x i8] ; <[26 x i8]*> [#uses=0]
-@.str_454 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_455 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_456 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_459 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_460 = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@.str_461 = external global [42 x i8] ; <[42 x i8]*> [#uses=0]
-@.str_462 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_463 = external global [28 x i8] ; <[28 x i8]*> [#uses=0]
-@.str_466 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_467 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_468 = external global [45 x i8] ; <[45 x i8]*> [#uses=0]
-@.str_469 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_470 = external global [31 x i8] ; <[31 x i8]*> [#uses=0]
-@.str_474 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_477 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_480 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_483 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_485 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_487 = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@.str_490 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_494 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_495 = external global [33 x i8] ; <[33 x i8]*> [#uses=0]
-@.str_497 = external global [12 x i8] ; <[12 x i8]*> [#uses=0]
-@.str_498 = external global [13 x i8] ; <[13 x i8]*> [#uses=0]
-@.str_507 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_508 = external global [11 x i8] ; <[11 x i8]*> [#uses=0]
-@.str_509 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_510 = external global [37 x i8] ; <[37 x i8]*> [#uses=0]
-@.str_511 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_512 = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@.str_513 = external global [18 x i8] ; <[18 x i8]*> [#uses=0]
-@.str_514 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@.str_515 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_516 = external global [21 x i8] ; <[21 x i8]*> [#uses=0]
-@.str_517 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_519 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_520 = external global [21 x i8] ; <[21 x i8]*> [#uses=0]
-@.str_521 = external global [15 x i8] ; <[15 x i8]*> [#uses=0]
-@.str_522 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_523 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_524 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_525 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_526 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_527 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@.str_528 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_529 = external global [28 x i8] ; <[28 x i8]*> [#uses=0]
-@.str_530 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_531 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_532 = external global [38 x i8] ; <[38 x i8]*> [#uses=0]
-@.str_533 = external global [32 x i8] ; <[32 x i8]*> [#uses=0]
-@.str_534 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_535 = external global [27 x i8] ; <[27 x i8]*> [#uses=0]
-@.str_536 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_537 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_539 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_540 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_541 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_542 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_543 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_544 = external global [49 x i8] ; <[49 x i8]*> [#uses=0]
-@.str_546 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_550 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_551 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_552 = external global [31 x i8] ; <[31 x i8]*> [#uses=0]
-@.str_553 = external global [52 x i8] ; <[52 x i8]*> [#uses=0]
-@.str_554 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_555 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_556 = external global [26 x i8] ; <[26 x i8]*> [#uses=0]
-@.str_557 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_559 = external global [27 x i8] ; <[27 x i8]*> [#uses=0]
-@.str_560 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_562 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_564 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_565 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_567 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_568 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_570 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_571 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_572 = external global [30 x i8] ; <[30 x i8]*> [#uses=0]
-@.str_574 = external global [20 x i8] ; <[20 x i8]*> [#uses=0]
-@.str_576 = external global [21 x i8] ; <[21 x i8]*> [#uses=0]
-@.str_577 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_578 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_579 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_580 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_581 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_582 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_583 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@.str_584 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_586 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_587 = external global [28 x i8] ; <[28 x i8]*> [#uses=0]
-@.str_589 = external global [28 x i8] ; <[28 x i8]*> [#uses=0]
-@.str_590 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_591 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_592 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_596 = external global [25 x i8] ; <[25 x i8]*> [#uses=0]
-@.str_597 = external global [27 x i8] ; <[27 x i8]*> [#uses=0]
-@.str_598 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_599 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_605 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_610 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_613 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_616 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_621 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_622 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@.str_623 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_624 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@.str_625 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_626 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_628 = external global [30 x i8] ; <[30 x i8]*> [#uses=0]
-@.str_629 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@.str_630 = external global [13 x i8] ; <[13 x i8]*> [#uses=0]
-@.str_631 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@.str_632 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@.str_633 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@.str_634 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_635 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@.str_636 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.str_637 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_639 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_643 = external global [20 x i8] ; <[20 x i8]*> [#uses=0]
-@.str_644 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_645 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_646 = external global [1 x i8] ; <[1 x i8]*> [#uses=0]
-@.str_649 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_654 = external global [2 x i8] ; <[2 x i8]*> [#uses=1]
-@.str_656 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_658 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_660 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_662 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_664 = external global [2 x i8] ; <[2 x i8]*> [#uses=0]
-@.str_666 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_667 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_669 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_670 = external global [20 x i8] ; <[20 x i8]*> [#uses=0]
-@.str_671 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_672 = external global [23 x i8] ; <[23 x i8]*> [#uses=0]
-@.str_674 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_675 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_676 = external global [30 x i8] ; <[30 x i8]*> [#uses=0]
-@.str_680 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_682 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_683 = external global [37 x i8] ; <[37 x i8]*> [#uses=0]
-@.str_684 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_685 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_686 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_687 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_688 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_689 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_690 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_691 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_692 = external global [20 x i8] ; <[20 x i8]*> [#uses=0]
-@.str_694 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_695 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_697 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_698 = external global [28 x i8] ; <[28 x i8]*> [#uses=0]
-@.str_700 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_701 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_702 = external global [26 x i8] ; <[26 x i8]*> [#uses=0]
-@.str_703 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_704 = external global [25 x i8] ; <[25 x i8]*> [#uses=0]
-@.str_707 = external global [4 x i8] ; <[4 x i8]*> [#uses=0]
-@.str_708 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_709 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_710 = external global [20 x i8] ; <[20 x i8]*> [#uses=0]
-@.str_711 = external global [37 x i8] ; <[37 x i8]*> [#uses=0]
-@.str_722 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_723 = external global [34 x i8] ; <[34 x i8]*> [#uses=0]
-@.str_726 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_727 = external global [23 x i8] ; <[23 x i8]*> [#uses=0]
-@.str_728 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_729 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_730 = external global [12 x i8] ; <[12 x i8]*> [#uses=0]
-@.str_732 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_734 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_735 = external global [28 x i8] ; <[28 x i8]*> [#uses=0]
-@.str_736 = external global [61 x i8] ; <[61 x i8]*> [#uses=0]
-@.str_738 = external global [25 x i8] ; <[25 x i8]*> [#uses=0]
-@.str_739 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_740 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_741 = external global [25 x i8] ; <[25 x i8]*> [#uses=0]
-@.str_742 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_743 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_744 = external global [31 x i8] ; <[31 x i8]*> [#uses=0]
-@.str_745 = external global [42 x i8] ; <[42 x i8]*> [#uses=0]
-@.str_747 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_748 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_750 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@"\01text_move.0__" = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@"\01new_text.1__" = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_1.upgrd.99 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@"\01text_move.2__" = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_1.upgrd.100 = external global [15 x i8] ; <[15 x i8]*> [#uses=0]
-@.str_2.upgrd.101 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_3.upgrd.102 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_130.upgrd.103 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_231.upgrd.104 = external global [47 x i8] ; <[47 x i8]*> [#uses=0]
-@.str_3.upgrd.105 = external global [27 x i8] ; <[27 x i8]*> [#uses=0]
-@.str_4.upgrd.106 = external global [27 x i8] ; <[27 x i8]*> [#uses=0]
-@.str_7.upgrd.107 = external global [30 x i8] ; <[30 x i8]*> [#uses=0]
-@"\01hashing_pawns.0__" = external global i32 ; <i32*> [#uses=0]
-@"\01hashing_opening.1__" = external global i32 ; <i32*> [#uses=0]
-@"\01hashing_middle_game.2__" = external global i32 ; <i32*> [#uses=0]
-@"\01hashing_end_game.3__" = external global i32 ; <i32*> [#uses=0]
-@"\01last_wtm.4__" = external global i32 ; <i32*> [#uses=0]
-@.str_1.upgrd.108 = external global [37 x i8] ; <[37 x i8]*> [#uses=0]
-@.str_1.upgrd.109 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_1.upgrd.110 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_2.upgrd.111 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_3.upgrd.112 = external global [30 x i8] ; <[30 x i8]*> [#uses=0]
-@.str_4.upgrd.113 = external global [30 x i8] ; <[30 x i8]*> [#uses=0]
-@.str_5.upgrd.114 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_6.upgrd.115 = external global [25 x i8] ; <[25 x i8]*> [#uses=0]
-@.str_7.upgrd.116 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@.str_934 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_1.upgrd.117 = external global [28 x i8] ; <[28 x i8]*> [#uses=0]
-@.str_3.upgrd.118 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_1.upgrd.119 = external global [38 x i8] ; <[38 x i8]*> [#uses=0]
-@.str_2.upgrd.120 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_4.upgrd.121 = external global [28 x i8] ; <[28 x i8]*> [#uses=0]
-@.str_5.upgrd.122 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_1.upgrd.123 = external global [11 x i8] ; <[11 x i8]*> [#uses=0]
-@.str_2.upgrd.124 = external global [27 x i8] ; <[27 x i8]*> [#uses=0]
-@.str_7.upgrd.125 = external global [29 x i8] ; <[29 x i8]*> [#uses=0]
-@.str_10.upgrd.126 = external global [34 x i8] ; <[34 x i8]*> [#uses=0]
-@.str_1141 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_12.upgrd.127 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_14.upgrd.128 = external global [20 x i8] ; <[20 x i8]*> [#uses=0]
-@.str_1542 = external global [17 x i8] ; <[17 x i8]*> [#uses=0]
-@.ctor_1.upgrd.129 = external global [25 x i8] ; <[25 x i8]*> [#uses=0]
-@.str_1.upgrd.130 = external global [33 x i8] ; <[33 x i8]*> [#uses=0]
-@.str_3.upgrd.131 = external global [21 x i8] ; <[21 x i8]*> [#uses=0]
-@.str_4.upgrd.132 = external global [25 x i8] ; <[25 x i8]*> [#uses=0]
-@.str_5.upgrd.133 = external global [26 x i8] ; <[26 x i8]*> [#uses=0]
-@.str_6.upgrd.134 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@.str_143.upgrd.135 = external global [33 x i8] ; <[33 x i8]*> [#uses=0]
-@.str_2.upgrd.136 = external global [15 x i8] ; <[15 x i8]*> [#uses=0]
-@.str_1.upgrd.137 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_2.upgrd.138 = external global [51 x i8] ; <[51 x i8]*> [#uses=0]
-@bit_move44 = external global i64 ; <i64*> [#uses=0]
-@.str_1.upgrd.139 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_248.upgrd.140 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_349.upgrd.141 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.ctor_1.upgrd.142 = external global [46 x i8] ; <[46 x i8]*> [#uses=0]
-@.str_5.upgrd.143 = external global [43 x i8] ; <[43 x i8]*> [#uses=0]
-@.str_6.upgrd.144 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_751 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_852 = external global [3 x i8] ; <[3 x i8]*> [#uses=0]
-@.str_9.upgrd.145 = external global [42 x i8] ; <[42 x i8]*> [#uses=0]
-@.str_10.upgrd.146 = external global [41 x i8] ; <[41 x i8]*> [#uses=0]
-@"\01out.0__" = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_1153 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_12.upgrd.147 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_13.upgrd.148 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_14.upgrd.149 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_15.upgrd.150 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_16.upgrd.151 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_17.upgrd.152 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@"\01out.1__" = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_18.upgrd.153 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_19.upgrd.154 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_20.upgrd.155 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_21.upgrd.156 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_2254 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_2355 = external global [8 x i8] ; <[8 x i8]*> [#uses=0]
-@.str_24.upgrd.157 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-@.str_25.upgrd.158 = external global [45 x i8] ; <[45 x i8]*> [#uses=0]
-@.str_26.upgrd.159 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@"\01out.2__" = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_31.upgrd.160 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@"\01out.3__" = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@"\01out.4__" = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_3457 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_35.upgrd.161 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_36.upgrd.162 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_37.upgrd.163 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_41.upgrd.164 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_45.upgrd.165 = external global [55 x i8] ; <[55 x i8]*> [#uses=0]
-@"\01save_book_selection_width.5__" = external global i32 ; <i32*> [#uses=0]
-@"\01save_book_random.6__" = external global i32 ; <i32*> [#uses=0]
-@"\01save_whisper.7__" = external global i32 ; <i32*> [#uses=0]
-@"\01save_kibitz.8__" = external global i32 ; <i32*> [#uses=0]
-@"\01save_channel.9__" = external global i32 ; <i32*> [#uses=0]
-@"\01save_resign.10" = external global i32 ; <i32*> [#uses=0]
-@"\01save_resign_count.11" = external global i32 ; <i32*> [#uses=0]
-@"\01save_draw_count.12" = external global i32 ; <i32*> [#uses=0]
-@"\01save_learning.13" = external global i32 ; <i32*> [#uses=0]
-@.str_49.upgrd.166 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_51.upgrd.167 = external global [44 x i8] ; <[44 x i8]*> [#uses=0]
-@"\01x.14" = external global [55 x i32] ; <[55 x i32]*> [#uses=0]
-@"\01init.15.b" = external global i1 ; <i1*> [#uses=0]
-@"\01y.16" = external global [55 x i32] ; <[55 x i32]*> [#uses=0]
-@"\01j.17" = external global i32 ; <i32*> [#uses=0]
-@"\01k.18" = external global i32 ; <i32*> [#uses=0]
-@.str_52.upgrd.168 = external global [50 x i8] ; <[50 x i8]*> [#uses=0]
-@"\01text.19" = external global [128 x i8] ; <[128 x i8]*> [#uses=0]
-@.str_5659 = external global [12 x i8] ; <[12 x i8]*> [#uses=0]
-@.str_62.upgrd.169 = external global [14 x i8] ; <[14 x i8]*> [#uses=0]
-@.str_6662 = external global [5 x i8] ; <[5 x i8]*> [#uses=0]
-@.str_68.upgrd.170 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_69.upgrd.171 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_70 = external global [16 x i8] ; <[16 x i8]*> [#uses=0]
-@.str_72.upgrd.172 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_74.upgrd.173 = external global [23 x i8] ; <[23 x i8]*> [#uses=0]
-@.str_76 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@.str_78 = external global [57 x i8] ; <[57 x i8]*> [#uses=0]
-@.str_80 = external global [45 x i8] ; <[45 x i8]*> [#uses=0]
-@.str_82 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_84.upgrd.174 = external global [10 x i8] ; <[10 x i8]*> [#uses=0]
-@.str_86.upgrd.175 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_88 = external global [7 x i8] ; <[7 x i8]*> [#uses=0]
-@.str_90.upgrd.176 = external global [31 x i8] ; <[31 x i8]*> [#uses=0]
-@.str_92.upgrd.177 = external global [19 x i8] ; <[19 x i8]*> [#uses=0]
-@.str_94.upgrd.178 = external global [30 x i8] ; <[30 x i8]*> [#uses=0]
-@.str_95.upgrd.179 = external global [48 x i8] ; <[48 x i8]*> [#uses=0]
-@.str_97.upgrd.180 = external global [18 x i8] ; <[18 x i8]*> [#uses=0]
-@.str_98.upgrd.181 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_100.upgrd.182 = external global [22 x i8] ; <[22 x i8]*> [#uses=0]
-@.str_163.upgrd.183 = external global [38 x i8] ; <[38 x i8]*> [#uses=0]
-@.str_2.upgrd.184 = external global [38 x i8] ; <[38 x i8]*> [#uses=0]
-@.str_3.upgrd.185 = external global [50 x i8] ; <[50 x i8]*> [#uses=0]
-@.str_4.upgrd.186 = external global [50 x i8] ; <[50 x i8]*> [#uses=0]
-@.str_5.upgrd.187 = external global [51 x i8] ; <[51 x i8]*> [#uses=0]
-@.str_6.upgrd.188 = external global [30 x i8] ; <[30 x i8]*> [#uses=0]
-@.str_7.upgrd.189 = external global [28 x i8] ; <[28 x i8]*> [#uses=0]
-@.str_8.upgrd.190 = external global [33 x i8] ; <[33 x i8]*> [#uses=0]
-@.str_9.upgrd.191 = external global [54 x i8] ; <[54 x i8]*> [#uses=0]
-@.str_10.upgrd.192 = external global [47 x i8] ; <[47 x i8]*> [#uses=0]
-@.str_11.upgrd.193 = external global [46 x i8] ; <[46 x i8]*> [#uses=0]
-@.str_12.upgrd.194 = external global [47 x i8] ; <[47 x i8]*> [#uses=0]
-@.str_13.upgrd.195 = external global [46 x i8] ; <[46 x i8]*> [#uses=0]
-@.str_14.upgrd.196 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_15.upgrd.197 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_16.upgrd.198 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_17.upgrd.199 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_18.upgrd.200 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_19.upgrd.201 = external global [41 x i8] ; <[41 x i8]*> [#uses=0]
-@.str_20.upgrd.202 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_22.upgrd.203 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_23.upgrd.204 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_24.upgrd.205 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_26.upgrd.206 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_27.upgrd.207 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_28.upgrd.208 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_30.upgrd.209 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_31.upgrd.210 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_32.upgrd.211 = external global [36 x i8] ; <[36 x i8]*> [#uses=0]
-@.str_33.upgrd.212 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_34.upgrd.213 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_3565 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_36.upgrd.214 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_37.upgrd.215 = external global [41 x i8] ; <[41 x i8]*> [#uses=0]
-@.str_38.upgrd.216 = external global [41 x i8] ; <[41 x i8]*> [#uses=0]
-@.str_39 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_40 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_41.upgrd.217 = external global [40 x i8] ; <[40 x i8]*> [#uses=0]
-@.str_42.upgrd.218 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_43.upgrd.219 = external global [41 x i8] ; <[41 x i8]*> [#uses=0]
-@.str_44.upgrd.220 = external global [41 x i8] ; <[41 x i8]*> [#uses=0]
-@.str_45.upgrd.221 = external global [39 x i8] ; <[39 x i8]*> [#uses=0]
-@.str_46.upgrd.222 = external global [35 x i8] ; <[35 x i8]*> [#uses=0]
-@.str_47.upgrd.223 = external global [50 x i8] ; <[50 x i8]*> [#uses=0]
-@.str_48.upgrd.224 = external global [26 x i8] ; <[26 x i8]*> [#uses=0]
-@.str_49.upgrd.225 = external global [31 x i8] ; <[31 x i8]*> [#uses=0]
-@.str_50.upgrd.226 = external global [15 x i8] ; <[15 x i8]*> [#uses=0]
-@.str_51.upgrd.227 = external global [6 x i8] ; <[6 x i8]*> [#uses=0]
-@.str_52.upgrd.228 = external global [24 x i8] ; <[24 x i8]*> [#uses=0]
-@.str_53.upgrd.229 = external global [9 x i8] ; <[9 x i8]*> [#uses=0]
-
-declare i64 @AttacksFrom(i32, i32)
-
-declare i64 @AttacksTo(i32)
-
-declare i32 @Attacked(i32, i32)
-
-declare i64 @Mask(i32)
-
-declare i32 @PopCnt(i64)
-
-declare i32 @FirstOne(i64)
-
-declare i32 @LastOne(i64)
-
-declare i32 @DrawScore()
-
-declare i32 @Drawn(i32)
-
-declare i8* @strchr(i8*, i32)
-
-declare i32 @strcmp(i8*, i8*)
-
-declare i32 @strlen(i8*)
-
-declare i32 @printf(i8*, ...)
-
-declare void @Edit()
-
-declare void @llvm.memcpy(i8*, i8*, i32, i32)
-
-declare i32 @fflush(%struct.__sFILE*)
-
-declare i32 @Read(i32, i8*)
-
-declare i32 @ReadParse(i8*, i8**, i8*)
-
-declare void @DisplayChessBoard(%struct.__sFILE*, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i32, i32, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8)
-
-declare void @SetChessBitBoards(%typedef.SEARCH_POSITION*)
-
-declare i32 @EnPrise(i32, i32)
-
-declare i64 @SwapXray(i64, i32, i32)
-
-declare i32 @Evaluate(i32, i32, i32, i32)
-
-declare i32 @EvaluateMate()
-
-declare i32 @EvaluatePawns()
-
-declare i32 @EvaluatePassedPawns()
-
-declare i32 @EvaluatePassedPawnRaces(i32)
-
-declare i32 @Swap(i32, i32, i32)
-
-declare i32 @EvaluateDevelopment(i32)
-
-declare i32 @EvaluateDraws()
-
-declare i32 @HasOpposition(i32, i32, i32)
-
-declare void @HistoryBest(i32, i32, i32)
-
-declare void @HistoryRefutation(i32, i32, i32)
-
-declare i32 @sprintf(i8*, i8*, ...)
-
-declare void @Initialize(i32)
-
-declare void @InitializeZeroMasks()
-
-declare void @InitializeMasks()
-
-declare void @InitializeRandomHash()
-
-declare void @InitializeAttackBoards()
-
-declare void @InitializePawnMasks()
-
-declare void @InitializePieceMasks()
-
-declare void @InitializeChessBoard(%typedef.SEARCH_POSITION*)
-
-declare %struct.__sFILE* @fopen(i8*, i8*)
-
-define i32 @Option() {
-no_exit.53.outer:
- %tmp.4747 = shl i32 7, 3 ; <i32> [#uses=1]
- %tmp.4779 = icmp eq %struct.__sFILE* getelementptr ([0 x %struct.__sFILE]* @__sF, i32 0, i32 1), null ; <i1> [#uses=2]
- br label %no_exit.53
-no_exit.53: ; preds = %else.166, %else.168, %then.360, %no_exit.53.outer
- %file.2.3.3.ph = phi i32 [ 0, %no_exit.53.outer ], [ %inc.551688, %then.360 ], [ %inc.551701, %else.168 ], [ %file.2.3.3.ph, %else.166 ] ; <i32> [#uses=2]
- %nempty.5.3.ph = phi i32 [ 0, %no_exit.53.outer ], [ %nempty.5.3, %then.360 ], [ %nempty.5.3, %else.168 ], [ %nempty.5.3.ph, %else.166 ] ; <i32> [#uses=2]
- %indvar2053.ui = phi i32 [ 0, %no_exit.53.outer ], [ 0, %then.360 ], [ 0, %else.168 ], [ %indvar.next2054, %else.166 ] ; <i32> [#uses=2]
- %indvar2053 = bitcast i32 %indvar2053.ui to i32 ; <i32> [#uses=2]
- %file.2.3.3 = add i32 %indvar2053, %file.2.3.3.ph ; <i32> [#uses=4]
- %nempty.5.3 = add i32 %indvar2053, %nempty.5.3.ph ; <i32> [#uses=3]
- %tmp.4749 = add i32 %file.2.3.3, %tmp.4747 ; <i32> [#uses=1]
- %tmp.4750 = getelementptr %typedef.CHESS_POSITION* @search, i32 0, i32 22, i32 %tmp.4749 ; <i8*> [#uses=3]
- %tmp.4751 = load i8* %tmp.4750 ; <i8> [#uses=1]
- %tmp.4752 = icmp eq i8 %tmp.4751, 0 ; <i1> [#uses=1]
- br i1 %tmp.4752, label %else.166, label %then.357
-then.357: ; preds = %no_exit.53
- %tmp.4755 = icmp eq i32 %nempty.5.3, 0 ; <i1> [#uses=1]
- br i1 %tmp.4755, label %endif.358, label %then.358
-then.358: ; preds = %then.357
- ret i32 0
-endif.358: ; preds = %then.357
- br i1 %tmp.4779, label %else.168, label %then.360
-then.360: ; preds = %endif.358
- %tmp.4791 = load i8* %tmp.4750 ; <i8> [#uses=1]
- %tmp.4792 = sext i8 %tmp.4791 to i32 ; <i32> [#uses=1]
- %tmp.4793 = add i32 %tmp.4792, 7 ; <i32> [#uses=1]
- %tmp.4794 = getelementptr [15 x i8]* null, i32 0, i32 %tmp.4793 ; <i8*> [#uses=1]
- %tmp.4795 = load i8* %tmp.4794 ; <i8> [#uses=1]
- %tmp.4796 = sext i8 %tmp.4795 to i32 ; <i32> [#uses=1]
- %tmp.4781 = call i32 (%struct.__sFILE*, i8*, ...)* @fprintf( %struct.__sFILE* getelementptr ([0 x %struct.__sFILE]* @__sF, i32 0, i32 1), i8* getelementptr ([3 x i8]* @.str_36, i32 0, i32 0), i32 %tmp.4796 ) ; <i32> [#uses=0]
- %inc.551688 = add i32 %file.2.3.3, 1 ; <i32> [#uses=2]
- %tmp.47421699 = icmp slt i32 %inc.551688, 8 ; <i1> [#uses=1]
- br i1 %tmp.47421699, label %no_exit.53, label %loopexit.56
-else.168: ; preds = %endif.358
- %tmp.4799 = call i32 @strlen( i8* getelementptr ([80 x i8]* @initial_position, i32 0, i32 0) ) ; <i32> [#uses=2]
- %gep.upgrd.230 = zext i32 %tmp.4799 to i64 ; <i64> [#uses=1]
- %tmp.4802 = getelementptr [80 x i8]* @initial_position, i32 0, i64 %gep.upgrd.230 ; <i8*> [#uses=1]
- %tmp.4811 = load i8* %tmp.4750 ; <i8> [#uses=1]
- %tmp.4812 = sext i8 %tmp.4811 to i32 ; <i32> [#uses=1]
- %tmp.4813 = add i32 %tmp.4812, 7 ; <i32> [#uses=1]
- %tmp.4814 = getelementptr [15 x i8]* null, i32 0, i32 %tmp.4813 ; <i8*> [#uses=1]
- %tmp.4815 = load i8* %tmp.4814 ; <i8> [#uses=1]
- store i8 %tmp.4815, i8* %tmp.4802
- %tmp.4802.sum = add i32 %tmp.4799, 1 ; <i32> [#uses=1]
- %gep.upgrd.231 = zext i32 %tmp.4802.sum to i64 ; <i64> [#uses=1]
- %tmp.4802.end = getelementptr [80 x i8]* @initial_position, i32 0, i64 %gep.upgrd.231 ; <i8*> [#uses=1]
- store i8 0, i8* %tmp.4802.end
- %inc.551701 = add i32 %file.2.3.3, 1 ; <i32> [#uses=2]
- %tmp.47421703 = icmp slt i32 %inc.551701, 8 ; <i1> [#uses=1]
- br i1 %tmp.47421703, label %no_exit.53, label %loopexit.56
-else.166: ; preds = %no_exit.53
- %inc.55 = add i32 %file.2.3.3, 1 ; <i32> [#uses=1]
- %tmp.47421705 = icmp slt i32 %inc.55, 8 ; <i1> [#uses=1]
- %indvar.next2054 = add i32 %indvar2053.ui, 1 ; <i32> [#uses=1]
- br i1 %tmp.47421705, label %no_exit.53, label %loopexit.56
-loopexit.56: ; preds = %else.166, %else.168, %then.360
- br i1 %tmp.4779, label %else.169, label %then.361
-then.361: ; preds = %loopexit.56
- %tmp.4822 = call i32 @fwrite( i8* getelementptr ([2 x i8]* @.str_654, i32 0, i32 0), i32 1, i32 1, %struct.__sFILE* getelementptr ([0 x %struct.__sFILE]* @__sF, i32 0, i32 1) ) ; <i32> [#uses=0]
- %dec.101707 = add i32 7, -1 ; <i32> [#uses=1]
- %tmp.47391709 = icmp sgt i32 %dec.101707, -1 ; <i1> [#uses=0]
- ret i32 0
-else.169: ; preds = %loopexit.56
- %tmp.4827 = call i32 @strlen( i8* getelementptr ([80 x i8]* @initial_position, i32 0, i32 0) ) ; <i32> [#uses=2]
- %gep.upgrd.232 = zext i32 %tmp.4827 to i64 ; <i64> [#uses=1]
- %tmp.4830 = getelementptr [80 x i8]* @initial_position, i32 0, i64 %gep.upgrd.232 ; <i8*> [#uses=1]
- store i8 47, i8* %tmp.4830
- %tmp.4830.sum = add i32 %tmp.4827, 1 ; <i32> [#uses=1]
- %gep.upgrd.233 = zext i32 %tmp.4830.sum to i64 ; <i64> [#uses=1]
- %tmp.4830.end = getelementptr [80 x i8]* @initial_position, i32 0, i64 %gep.upgrd.233 ; <i8*> [#uses=1]
- store i8 0, i8* %tmp.4830.end
- %dec.10 = add i32 7, -1 ; <i32> [#uses=1]
- %tmp.47391711 = icmp sgt i32 %dec.10, -1 ; <i1> [#uses=0]
- ret i32 0
-}
-
-declare void @InitializeHashTables()
-
-declare i32 @InitializeFindAttacks(i32, i32, i32)
-
-declare void @SetBoard(i32, i8**, i32)
-
-declare i32 @KingPawnSquare(i32, i32, i32, i32)
-
-declare i64 @Random64()
-
-declare i32 @Random32()
-
-declare i8* @strcpy(i8*, i8*)
-
-declare i32 @InputMove(i8*, i32, i32, i32, i32)
-
-declare i32 @InputMoveICS(i8*, i32, i32, i32, i32)
-
-declare i32* @GenerateCaptures(i32, i32, i32*)
-
-declare i32* @GenerateNonCaptures(i32, i32, i32*)
-
-declare void @MakeMove(i32, i32, i32)
-
-declare void @UnMakeMove(i32, i32, i32)
-
-declare void @Interrupt(i32)
-
-declare i32 @GetTime(i32)
-
-declare i8* @DisplayTime(i32)
-
-declare i8* @OutputMoveICS(i32*)
-
-declare void @Delay(i32)
-
-declare i32 @fprintf(%struct.__sFILE*, i8*, ...)
-
-declare void @SignalInterrupt(i32)
-
-declare void (i32)* @signal(i32, void (i32)*)
-
-declare i32 @Iterate(i32, i32, i32)
-
-declare void @PreEvaluate(i32)
-
-declare void @RootMoveList(i32)
-
-declare i8* @OutputMove(i32*, i32, i32)
-
-declare void @TimeSet(i32)
-
-declare void @StorePV(i32, i32)
-
-declare i32 @SearchRoot(i32, i32, i32, i32)
-
-declare void @Whisper(i32, i32, i32, i32, i32, i32, i8*)
-
-declare i8* @DisplayEvaluation(i32)
-
-declare i32 @LookUp(i32, i32, i32, i32*, i32*)
-
-declare i8* @strstr(i8*, i8*)
-
-declare i32 @main(i32, i8**)
-
-declare void @__main()
-
-declare i32 @atoi(i8*)
-
-declare void @NewGame(i32)
-
-declare i32 @Ponder(i32)
-
-declare i32 @fseek(%struct.__sFILE*, i32, i32)
-
-declare void @MakeMoveRoot(i32, i32)
-
-declare i32 @RepetitionDraw(i32)
-
-declare i8* @Reverse()
-
-declare i8* @Normal()
-
-declare void @TimeAdjust(i32, i32)
-
-declare void @ValidatePosition(i32, i32, i8*)
-
-declare i32 @ValidMove(i32, i32, i32)
-
-declare i32* @GenerateCheckEvasions(i32, i32, i32*)
-
-declare i64 @InterposeSquares(i32, i32, i32)
-
-declare i32 @PinnedOnKing(i32, i32)
-
-declare i32 @NextMove(i32, i32)
-
-declare i32 @NextEvasion(i32, i32)
-
-declare i32 @NextRootMove(i32)
-
-declare i32 @TimeCheck(i32)
-
-declare i32 @strncmp(i8*, i8*, i32)
-
-declare void @exit(i32)
-
-declare i32 @OptionMatch(i8*, i8*)
-
-declare i32 @fclose(%struct.__sFILE*)
-
-declare i32 @ParseTime(i8*)
-
-declare i8* @DisplayHHMM(i32)
-
-declare void @DisplayPieceBoards(i32*, i32*)
-
-declare i32 @fscanf(%struct.__sFILE*, i8*, ...)
-
-declare i32 @feof(%struct.__sFILE*)
-
-declare i8* @fgets(i8*, i32, %struct.__sFILE*)
-
-declare i32 @remove(i8*)
-
-declare i32 @__tolower(i32)
-
-declare i32 @clock()
-
-declare void @OptionPerft(i32, i32, i32)
-
-declare void @Phase()
-
-declare i32 @ReadNextMove(i8*, i32, i32)
-
-declare i32 @time(i32*)
-
-declare %struct.tm* @localtime(i32*)
-
-declare i8* @gets(i8*)
-
-declare i32 @OutputGood(i8*, i32, i32)
-
-declare i32 @CheckInput()
-
-declare void @ClearHashTables()
-
-declare i32 @Quiesce(i32, i32, i32, i32)
-
-declare void @SearchTrace(i32, i32, i32, i32, i32, i8*, i32)
-
-declare i32 @RepetitionCheck(i32, i32)
-
-declare void @ResignOrDraw(i32, i32)
-
-declare i32 @Search(i32, i32, i32, i32, i32, i32)
-
-declare void @StoreRefutation(i32, i32, i32, i32)
-
-declare void @StoreBest(i32, i32, i32, i32, i32)
-
-declare void @SearchOutput(i32, i32)
-
-declare i32 @strspn(i8*, i8*)
-
-declare i32 @isatty(i32)
-
-declare i32 @fileno(%struct.__sFILE*)
-
-declare void @llvm.memset(i8*, i8, i32, i32)
-
-declare i32 @select(i32, %struct.fd_set*, %struct.fd_set*, %struct.fd_set*, %struct.timeval*)
-
-declare void @DisplayBitBoard(i64)
-
-declare i8* @DisplayEvaluationWhisper(i32)
-
-declare i8* @DisplayTimeWhisper(i32)
-
-declare void @Display64bitWord(i64)
-
-declare void @Display2BitBoards(i64, i64)
-
-declare void @DisplayChessMove(i8*, i32)
-
-declare void @llvm.memmove(i8*, i8*, i32, i32)
-
-declare void @ReadClear()
-
-declare i8* @strtok(i8*, i8*)
-
-declare i32 @SpecReadRaw()
-
-declare i32 @read(i32, i8*, i32)
-
-declare i32* @__error()
-
-declare i32 @ReadChessMove(%struct.__sFILE*, i32, i32)
-
-declare i64 @ValidateComputeBishopAttacks(i32)
-
-declare i64 @ValidateComputeRookAttacks(i32)
-
-declare i8* @memchr(i8*, i32, i32)
-
-declare i32 @fwrite(i8*, i32, i32, %struct.__sFILE*)
diff --git a/test/Transforms/LoopUnswitch/2006-02-22-UnswitchCrash.ll b/test/Transforms/LoopUnswitch/crash.ll
index a50bd54..fac55a6 100644
--- a/test/Transforms/LoopUnswitch/2006-02-22-UnswitchCrash.ll
+++ b/test/Transforms/LoopUnswitch/crash.ll
@@ -1,6 +1,6 @@
; RUN: opt < %s -loop-unswitch -disable-output
-define void @sort_Eq(i32* %S2) {
+define void @test1(i32* %S2) {
entry:
br i1 false, label %list_Length.exit, label %cond_true.i
cond_true.i: ; preds = %entry
@@ -30,3 +30,18 @@ return: ; preds = %return.loopexit, %list_Length.exit9
ret void
}
+define void @test2(i32 %x1, i32 %y1, i32 %z1, i32 %r1) nounwind {
+entry:
+ br label %bb.nph
+
+bb.nph: ; preds = %entry
+ %and.i13521 = and <4 x i1> undef, undef ; <<4 x i1>> [#uses=1]
+ br label %for.body
+
+for.body: ; preds = %for.body, %bb.nph
+ %or.i = select <4 x i1> %and.i13521, <4 x i32> undef, <4 x i32> undef ; <<4 x i32>> [#uses=0]
+ br i1 false, label %for.body, label %for.end
+
+for.end: ; preds = %for.body, %entry
+ ret void
+}
diff --git a/test/Transforms/Mem2Reg/ConvertDebugInfo.ll b/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
index 8e309c0..a013a1d 100644
--- a/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
+++ b/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
@@ -9,8 +9,8 @@ define double @testfunc(i32 %i, double %j) {
call void @llvm.dbg.declare(metadata !{double* %J}, metadata !1)
; CHECK: call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !0)
store i32 %i, i32* %I
-; CHECK: call void @llvm.dbg.value(metadata !{double %j}, i64 0, metadata !1)
- store double %j, double* %J
+; CHECK: call void @llvm.dbg.value(metadata !{double %j}, i64 0, metadata !1), !dbg !3
+ store double %j, double* %J, !dbg !3
%t1 = load i32* %I ; <i32> [#uses=1]
%t2 = add i32 %t1, 1 ; <i32> [#uses=1]
store i32 %t2, i32* %I
@@ -29,3 +29,4 @@ declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
!0 = metadata !{i32 459008, metadata !1, metadata !"foo", metadata !2, i32 5, metadata !"foo"} ; [ DW_TAG_auto_variable ]
!1 = metadata !{i32 459008, metadata !1, metadata !"foo", metadata !0, i32 5, metadata !1} ; [ DW_TAG_auto_variable ]
!2 = metadata !{i32 458804, i32 0, metadata !2, metadata !"foo", metadata !"bar", metadata !"bar", metadata !2, i32 3, metadata !0, i1 false, i1 true} ; [ DW_TAG_variable ]
+!3 = metadata !{i32 4, i32 0, metadata !0, null}
diff --git a/test/Transforms/Reassociate/basictest.ll b/test/Transforms/Reassociate/basictest.ll
index e77d83d..0864740 100644
--- a/test/Transforms/Reassociate/basictest.ll
+++ b/test/Transforms/Reassociate/basictest.ll
@@ -203,4 +203,14 @@ define i32 @test14(i32 %X1, i32 %X2) {
; CHECK-NEXT: ret i32
}
+; Do not reassociate expressions of type i1
+define i32 @test15(i32 %X1, i32 %X2, i32 %X3) {
+ %A = icmp ne i32 %X1, 0
+ %B = icmp slt i32 %X2, %X3
+ %C = and i1 %A, %B
+ %D = select i1 %C, i32 %X1, i32 0
+ ret i32 %D
+; CHECK: @test15
+; CHECK: and i1 %A, %B
+}
diff --git a/test/Transforms/SimplifyCFG/MagicPointer.ll b/test/Transforms/SimplifyCFG/MagicPointer.ll
new file mode 100644
index 0000000..54e5b14
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/MagicPointer.ll
@@ -0,0 +1,76 @@
+; Test that simplifycfg can create switch instructions from constant pointers.
+;
+; RUN: opt < %s -simplifycfg -S | FileCheck %s
+
+; CHECK: switch i64 %magicptr
+; CHECK: i64 0, label
+; CHECK: i64 1, label
+; CHECK: i64 2, label
+; CHECK: i64 3, label
+; CHECK: i64 4, label
+; CHECK-NOT: br
+; CHECK: }
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin10.0.0"
+
+@.str = private constant [5 x i8] c"null\00" ; <[5 x i8]*> [#uses=2]
+@.str1 = private constant [4 x i8] c"one\00" ; <[4 x i8]*> [#uses=2]
+@.str2 = private constant [4 x i8] c"two\00" ; <[4 x i8]*> [#uses=2]
+@.str3 = private constant [5 x i8] c"four\00" ; <[5 x i8]*> [#uses=2]
+
+define void @f(i8* %x) nounwind ssp {
+entry:
+ %tobool = icmp eq i8* %x, null ; <i1> [#uses=1]
+ br i1 %tobool, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.str, i64 0, i64 0)) nounwind ; <i32> [#uses=0]
+ br label %if.end21
+
+if.else: ; preds = %entry
+ %cmp = icmp eq i8* %x, inttoptr (i64 1 to i8*) ; <i1> [#uses=1]
+ br i1 %cmp, label %if.then2, label %if.else4
+
+if.then2: ; preds = %if.else
+ %call3 = call i32 @puts(i8* getelementptr inbounds ([4 x i8]* @.str1, i64 0, i64 0)) nounwind ; <i32> [#uses=0]
+ br label %if.end20
+
+if.else4: ; preds = %if.else
+ %cmp6 = icmp eq i8* %x, inttoptr (i64 2 to i8*) ; <i1> [#uses=1]
+ br i1 %cmp6, label %if.then9, label %lor.lhs.false
+
+lor.lhs.false: ; preds = %if.else4
+ %cmp8 = icmp eq i8* %x, inttoptr (i64 3 to i8*) ; <i1> [#uses=1]
+ br i1 %cmp8, label %if.then9, label %if.else11
+
+if.then9: ; preds = %lor.lhs.false, %if.else4
+ %call10 = call i32 @puts(i8* getelementptr inbounds ([4 x i8]* @.str2, i64 0, i64 0)) nounwind ; <i32> [#uses=0]
+ br label %if.end19
+
+if.else11: ; preds = %lor.lhs.false
+ %cmp13 = icmp eq i8* %x, inttoptr (i64 4 to i8*) ; <i1> [#uses=1]
+ br i1 %cmp13, label %if.then14, label %if.else16
+
+if.then14: ; preds = %if.else11
+ %call15 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.str3, i64 0, i64 0)) nounwind ; <i32> [#uses=0]
+ br label %if.end
+
+if.else16: ; preds = %if.else11
+ %call18 = call i32 @puts(i8* %x) nounwind ; <i32> [#uses=0]
+ br label %if.end
+
+if.end: ; preds = %if.else16, %if.then14
+ br label %if.end19
+
+if.end19: ; preds = %if.end, %if.then9
+ br label %if.end20
+
+if.end20: ; preds = %if.end19, %if.then2
+ br label %if.end21
+
+if.end21: ; preds = %if.end20, %if.then
+ ret void
+}
+
+declare i32 @puts(i8*)
diff --git a/test/Transforms/SimplifyLibCalls/strcpy_chk.ll b/test/Transforms/SimplifyLibCalls/strcpy_chk.ll
new file mode 100644
index 0000000..422cbd9
--- /dev/null
+++ b/test/Transforms/SimplifyLibCalls/strcpy_chk.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
+@a = common global [60 x i8] zeroinitializer, align 1 ; <[60 x i8]*> [#uses=1]
+@.str = private constant [8 x i8] c"abcdefg\00" ; <[8 x i8]*> [#uses=1]
+
+define i8* @foo() nounwind {
+; CHECK: @foo
+; CHECK-NEXT: call i8* @strcpy
+ %call = call i8* @__strcpy_chk(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32 0), i32 60) ; <i8*> [#uses=1]
+ ret i8* %call
+}
+
+declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind
diff --git a/test/lib/llvm.exp b/test/lib/llvm.exp
index 2c1bef9..319cc11 100644
--- a/test/lib/llvm.exp
+++ b/test/lib/llvm.exp
@@ -301,6 +301,16 @@ proc llvm_supports_target { tgtName } {
return 0
}
+proc llvm_supports_darwin_and_target { tgtName } {
+ global target_triplet
+ if { [ llvm_supports_target $tgtName ] } {
+ if { [regexp darwin $target_triplet match] } {
+ return 1
+ }
+ }
+ return 0
+}
+
# This procedure provides an interface to check the BINDINGS_TO_BUILD makefile
# variable to see if a particular binding has been configured to build.
proc llvm_supports_binding { name } {
diff --git a/test/lit.cfg b/test/lit.cfg
index 8e85168..0894d9b 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -114,6 +114,11 @@ for sub in ['llvmgcc', 'llvmgxx', 'compile_cxx', 'compile_c',
if sub in ('llvmgcc', 'llvmgxx'):
config.substitutions.append(('%' + sub,
site_exp[sub] + ' -emit-llvm -w'))
+ # FIXME: This is a hack to avoid LLVMC tests failing due to a clang driver
+ # warning when passing in "-fexceptions -fno-exceptions".
+ elif sub == 'compile_cxx':
+ config.substitutions.append(('%' + sub,
+ site_exp[sub].replace('-fno-exceptions', '')))
else:
config.substitutions.append(('%' + sub, site_exp[sub]))
@@ -127,6 +132,9 @@ targets = set(site_exp["TARGETS_TO_BUILD"].split())
def llvm_supports_target(name):
return name in targets
+def llvm_supports_darwin_and_target(name):
+ return 'darwin' in config.target_triple and llvm_supports_target(name)
+
langs = set(site_exp['llvmgcc_langs'].split(','))
def llvm_gcc_supports(name):
return name in langs
diff --git a/tools/Makefile b/tools/Makefile
index 0340c7f..c9b9ff2 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -21,7 +21,8 @@ PARALLEL_DIRS := opt llvm-as llvm-dis \
llvm-ld llvm-prof llvm-link \
lli llvm-extract \
bugpoint llvm-bcanalyzer llvm-stub \
- llvm-mc llvmc
+ llvm-mc llvmc \
+ edis
# Let users override the set of tools to build from the command line.
ifdef ONLY_TOOLS
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index 918d6a6a..70011a7 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -323,8 +323,6 @@ llvm::SplitFunctionsOutOfModule(Module *M,
Module *BugDriver::ExtractMappedBlocksFromModule(const
std::vector<BasicBlock*> &BBs,
Module *M) {
- char *ExtraArg = NULL;
-
sys::Path uniqueFilename(OutputPrefix + "-extractblocks");
std::string ErrMsg;
if (uniqueFilename.createTemporaryFileOnDisk(true, &ErrMsg)) {
@@ -359,9 +357,8 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const
}
BlocksToNotExtractFile.close();
- const char *uniqueFN = uniqueFilename.c_str();
- ExtraArg = (char*)malloc(23 + strlen(uniqueFN));
- strcat(strcpy(ExtraArg, "--extract-blocks-file="), uniqueFN);
+ std::string uniqueFN = "--extract-blocks-file=" + uniqueFilename.str();
+ const char *ExtraArg = uniqueFN.c_str();
std::vector<const PassInfo*> PI;
std::vector<BasicBlock *> EmptyBBs; // This parameter is ignored.
@@ -370,7 +367,6 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const
if (uniqueFilename.exists())
uniqueFilename.eraseFromDisk(); // Free disk space
- free(ExtraArg);
if (Ret == 0) {
outs() << "*** Basic Block extraction failed, please report a bug!\n";
diff --git a/tools/edis/EDDisassembler.cpp b/tools/edis/EDDisassembler.cpp
new file mode 100644
index 0000000..99864fb
--- /dev/null
+++ b/tools/edis/EDDisassembler.cpp
@@ -0,0 +1,386 @@
+//===-EDDisassembler.cpp - LLVM Enhanced Disassembler ---------------------===//
+//
+// 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 Enhanced Disassembly library's disassembler class.
+// The disassembler is responsible for vending individual instructions according
+// to a given architecture and disassembly syntax.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCParser/AsmLexer.h"
+#include "llvm/MC/MCParser/AsmParser.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Target/TargetAsmLexer.h"
+#include "llvm/Target/TargetAsmParser.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSelect.h"
+
+#include "EDDisassembler.h"
+#include "EDInst.h"
+
+#include "../../lib/Target/X86/X86GenEDInfo.inc"
+
+using namespace llvm;
+
+bool EDDisassembler::sInitialized = false;
+EDDisassembler::DisassemblerMap_t EDDisassembler::sDisassemblers;
+
+struct InfoMap {
+ Triple::ArchType Arch;
+ const char *String;
+ const InstInfo *Info;
+};
+
+static struct InfoMap infomap[] = {
+ { Triple::x86, "i386-unknown-unknown", instInfoX86 },
+ { Triple::x86_64, "x86_64-unknown-unknown", instInfoX86 },
+ { Triple::InvalidArch, NULL, NULL }
+};
+
+/// infoFromArch - Returns the InfoMap corresponding to a given architecture,
+/// or NULL if there is an error
+///
+/// @arg arch - The Triple::ArchType for the desired architecture
+static const InfoMap *infoFromArch(Triple::ArchType arch) {
+ unsigned int infoIndex;
+
+ for (infoIndex = 0; infomap[infoIndex].String != NULL; ++infoIndex) {
+ if(arch == infomap[infoIndex].Arch)
+ return &infomap[infoIndex];
+ }
+
+ return NULL;
+}
+
+/// getLLVMSyntaxVariant - gets the constant to use to get an assembly printer
+/// for the desired assembly syntax, suitable for passing to
+/// Target::createMCInstPrinter()
+///
+/// @arg arch - The target architecture
+/// @arg syntax - The assembly syntax in sd form
+static int getLLVMSyntaxVariant(Triple::ArchType arch,
+ EDAssemblySyntax_t syntax) {
+ switch (syntax) {
+ default:
+ return -1;
+ // Mappings below from X86AsmPrinter.cpp
+ case kEDAssemblySyntaxX86ATT:
+ if (arch == Triple::x86 || arch == Triple::x86_64)
+ return 0;
+ else
+ return -1;
+ case kEDAssemblySyntaxX86Intel:
+ if (arch == Triple::x86 || arch == Triple::x86_64)
+ return 1;
+ else
+ return -1;
+ }
+}
+
+#define BRINGUP_TARGET(tgt) \
+ LLVMInitialize##tgt##TargetInfo(); \
+ LLVMInitialize##tgt##Target(); \
+ LLVMInitialize##tgt##AsmPrinter(); \
+ LLVMInitialize##tgt##AsmParser(); \
+ LLVMInitialize##tgt##Disassembler();
+
+void EDDisassembler::initialize() {
+ if (sInitialized)
+ return;
+
+ sInitialized = true;
+
+ BRINGUP_TARGET(X86)
+}
+
+#undef BRINGUP_TARGET
+
+EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
+ EDAssemblySyntax_t syntax) {
+ CPUKey key;
+ key.Arch = arch;
+ key.Syntax = syntax;
+
+ EDDisassembler::DisassemblerMap_t::iterator i = sDisassemblers.find(key);
+
+ if (i != sDisassemblers.end()) {
+ return i->second;
+ }
+ else {
+ EDDisassembler* sdd = new EDDisassembler(key);
+ if(!sdd->valid()) {
+ delete sdd;
+ return NULL;
+ }
+
+ sDisassemblers[key] = sdd;
+
+ return sdd;
+ }
+
+ return NULL;
+}
+
+EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
+ EDAssemblySyntax_t syntax) {
+ Triple triple(str);
+
+ return getDisassembler(triple.getArch(), syntax);
+}
+
+EDDisassembler::EDDisassembler(CPUKey &key) :
+ Valid(false), ErrorString(), ErrorStream(ErrorString), Key(key) {
+ const InfoMap *infoMap = infoFromArch(key.Arch);
+
+ if (!infoMap)
+ return;
+
+ const char *triple = infoMap->String;
+
+ int syntaxVariant = getLLVMSyntaxVariant(key.Arch, key.Syntax);
+
+ if (syntaxVariant < 0)
+ return;
+
+ std::string tripleString(triple);
+ std::string errorString;
+
+ Tgt = TargetRegistry::lookupTarget(tripleString,
+ errorString);
+
+ if (!Tgt)
+ return;
+
+ std::string featureString;
+
+ OwningPtr<const TargetMachine>
+ targetMachine(Tgt->createTargetMachine(tripleString,
+ featureString));
+
+ const TargetRegisterInfo *registerInfo = targetMachine->getRegisterInfo();
+
+ if (!registerInfo)
+ return;
+
+ AsmInfo.reset(Tgt->createAsmInfo(tripleString));
+
+ if (!AsmInfo)
+ return;
+
+ Disassembler.reset(Tgt->createMCDisassembler());
+
+ if (!Disassembler)
+ return;
+
+ InstString.reset(new std::string);
+ InstStream.reset(new raw_string_ostream(*InstString));
+
+ InstPrinter.reset(Tgt->createMCInstPrinter(syntaxVariant,
+ *AsmInfo,
+ *InstStream));
+
+ if (!InstPrinter)
+ return;
+
+ GenericAsmLexer.reset(new AsmLexer(*AsmInfo));
+ SpecificAsmLexer.reset(Tgt->createAsmLexer(*AsmInfo));
+ SpecificAsmLexer->InstallLexer(*GenericAsmLexer);
+
+ InstInfos = infoMap->Info;
+
+ initMaps(*targetMachine->getRegisterInfo());
+
+ Valid = true;
+}
+
+EDDisassembler::~EDDisassembler() {
+ if(!valid())
+ return;
+}
+
+namespace {
+ /// EDMemoryObject - a subclass of MemoryObject that allows use of a callback
+ /// as provided by the sd interface. See MemoryObject.
+ class EDMemoryObject : public llvm::MemoryObject {
+ private:
+ EDByteReaderCallback Callback;
+ void *Arg;
+ public:
+ EDMemoryObject(EDByteReaderCallback callback,
+ void *arg) : Callback(callback), Arg(arg) { }
+ ~EDMemoryObject() { }
+ uint64_t getBase() const { return 0x0; }
+ uint64_t getExtent() const { return (uint64_t)-1; }
+ int readByte(uint64_t address, uint8_t *ptr) const {
+ if(!Callback)
+ return -1;
+
+ if(Callback(ptr, address, Arg))
+ return -1;
+
+ return 0;
+ }
+ };
+}
+
+EDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader,
+ uint64_t address,
+ void *arg) {
+ EDMemoryObject memoryObject(byteReader, arg);
+
+ MCInst* inst = new MCInst;
+ uint64_t byteSize;
+
+ if (!Disassembler->getInstruction(*inst,
+ byteSize,
+ memoryObject,
+ address,
+ ErrorStream)) {
+ delete inst;
+ return NULL;
+ }
+ else {
+ const InstInfo *thisInstInfo = &InstInfos[inst->getOpcode()];
+
+ EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo);
+ return sdInst;
+ }
+}
+
+void EDDisassembler::initMaps(const TargetRegisterInfo &registerInfo) {
+ unsigned numRegisters = registerInfo.getNumRegs();
+ unsigned registerIndex;
+
+ for (registerIndex = 0; registerIndex < numRegisters; ++registerIndex) {
+ const char* registerName = registerInfo.get(registerIndex).Name;
+
+ RegVec.push_back(registerName);
+ RegRMap[registerName] = registerIndex;
+ }
+
+ if (Key.Arch == Triple::x86 ||
+ Key.Arch == Triple::x86_64) {
+ stackPointers.insert(registerIDWithName("SP"));
+ stackPointers.insert(registerIDWithName("ESP"));
+ stackPointers.insert(registerIDWithName("RSP"));
+
+ programCounters.insert(registerIDWithName("IP"));
+ programCounters.insert(registerIDWithName("EIP"));
+ programCounters.insert(registerIDWithName("RIP"));
+ }
+}
+
+const char *EDDisassembler::nameWithRegisterID(unsigned registerID) const {
+ if (registerID >= RegVec.size())
+ return NULL;
+ else
+ return RegVec[registerID].c_str();
+}
+
+unsigned EDDisassembler::registerIDWithName(const char *name) const {
+ regrmap_t::const_iterator iter = RegRMap.find(std::string(name));
+ if (iter == RegRMap.end())
+ return 0;
+ else
+ return (*iter).second;
+}
+
+bool EDDisassembler::registerIsStackPointer(unsigned registerID) {
+ return (stackPointers.find(registerID) != stackPointers.end());
+}
+
+bool EDDisassembler::registerIsProgramCounter(unsigned registerID) {
+ return (programCounters.find(registerID) != programCounters.end());
+}
+
+int EDDisassembler::printInst(std::string& str,
+ MCInst& inst) {
+ PrinterMutex.acquire();
+
+ InstPrinter->printInst(&inst);
+ InstStream->flush();
+ str = *InstString;
+ InstString->clear();
+
+ PrinterMutex.release();
+
+ return 0;
+}
+
+int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
+ SmallVectorImpl<AsmToken> &tokens,
+ const std::string &str) {
+ int ret = 0;
+
+ const char *cStr = str.c_str();
+ MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
+
+ StringRef instName;
+ SMLoc instLoc;
+
+ SourceMgr sourceMgr;
+ sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over
+ MCContext context;
+ OwningPtr<MCStreamer> streamer
+ (createNullStreamer(context));
+ AsmParser genericParser(sourceMgr, context, *streamer, *AsmInfo);
+ OwningPtr<TargetAsmParser> specificParser
+ (Tgt->createAsmParser(genericParser));
+
+ AsmToken OpcodeToken = genericParser.Lex();
+
+ if(OpcodeToken.is(AsmToken::Identifier)) {
+ instName = OpcodeToken.getString();
+ instLoc = OpcodeToken.getLoc();
+ if (specificParser->ParseInstruction(instName, instLoc, operands))
+ ret = -1;
+ }
+ else {
+ ret = -1;
+ }
+
+ ParserMutex.acquire();
+
+ if (!ret) {
+ GenericAsmLexer->setBuffer(buf);
+
+ while (SpecificAsmLexer->Lex(),
+ SpecificAsmLexer->isNot(AsmToken::Eof) &&
+ SpecificAsmLexer->isNot(AsmToken::EndOfStatement)) {
+ if (SpecificAsmLexer->is(AsmToken::Error)) {
+ ret = -1;
+ break;
+ }
+ tokens.push_back(SpecificAsmLexer->getTok());
+ }
+ }
+
+ ParserMutex.release();
+
+ return ret;
+}
+
+int EDDisassembler::llvmSyntaxVariant() const {
+ return LLVMSyntaxVariant;
+}
diff --git a/tools/edis/EDDisassembler.h b/tools/edis/EDDisassembler.h
new file mode 100644
index 0000000..6be9152
--- /dev/null
+++ b/tools/edis/EDDisassembler.h
@@ -0,0 +1,248 @@
+//===-EDDisassembler.h - LLVM Enhanced Disassembler -------------*- 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 interface for the Enhanced Disassembly library's
+// disassembler class. The disassembler is responsible for vending individual
+// instructions according to a given architecture and disassembly syntax.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EDDisassembler_
+#define EDDisassembler_
+
+#include "EDInfo.inc"
+
+#include "llvm-c/EnhancedDisassembly.h"
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Mutex.h"
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+namespace llvm {
+class AsmLexer;
+class AsmToken;
+class MCContext;
+class MCAsmInfo;
+class MCAsmLexer;
+class AsmParser;
+class TargetAsmLexer;
+class TargetAsmParser;
+class MCDisassembler;
+class MCInstPrinter;
+class MCInst;
+class MCParsedAsmOperand;
+class MCStreamer;
+template <typename T> class SmallVectorImpl;
+class SourceMgr;
+class Target;
+class TargetRegisterInfo;
+}
+
+/// EDDisassembler - Encapsulates a disassembler for a single architecture and
+/// disassembly syntax. Also manages the static disassembler registry.
+struct EDDisassembler {
+ ////////////////////
+ // Static members //
+ ////////////////////
+
+ /// CPUKey - Encapsulates the descriptor of an architecture/disassembly-syntax
+ /// pair
+ struct CPUKey {
+ /// The architecture type
+ llvm::Triple::ArchType Arch;
+
+ /// The assembly syntax
+ EDAssemblySyntax_t Syntax;
+
+ /// operator== - Equality operator
+ bool operator==(const CPUKey &key) const {
+ return (Arch == key.Arch &&
+ Syntax == key.Syntax);
+ }
+
+ /// operator< - Less-than operator
+ bool operator<(const CPUKey &key) const {
+ if(Arch > key.Arch)
+ return false;
+ if(Syntax >= key.Syntax)
+ return false;
+ return true;
+ }
+ };
+
+ typedef std::map<CPUKey, EDDisassembler*> DisassemblerMap_t;
+
+ /// True if the disassembler registry has been initialized; false if not
+ static bool sInitialized;
+ /// A map from disassembler specifications to disassemblers. Populated
+ /// lazily.
+ static DisassemblerMap_t sDisassemblers;
+
+ /// getDisassembler - Returns the specified disassemble, or NULL on failure
+ ///
+ /// @arg arch - The desired architecture
+ /// @arg syntax - The desired disassembly syntax
+ static EDDisassembler *getDisassembler(llvm::Triple::ArchType arch,
+ EDAssemblySyntax_t syntax);
+
+ /// getDisassembler - Returns the disassembler for a given combination of
+ /// CPU type, CPU subtype, and assembly syntax, or NULL on failure
+ ///
+ /// @arg str - The string representation of the architecture triple, e.g.,
+ /// "x86_64-apple-darwin"
+ /// @arg syntax - The disassembly syntax for the required disassembler
+ static EDDisassembler *getDisassembler(llvm::StringRef str,
+ EDAssemblySyntax_t syntax);
+
+ /// initialize - Initializes the disassembler registry and the LLVM backend
+ static void initialize();
+
+ ////////////////////////
+ // Per-object members //
+ ////////////////////////
+
+ /// True only if the object has been fully and successfully initialized
+ bool Valid;
+
+ /// The string that stores disassembler errors from the backend
+ std::string ErrorString;
+ /// The stream that wraps the ErrorString
+ llvm::raw_string_ostream ErrorStream;
+
+ /// The architecture/syntax pair for the current architecture
+ CPUKey Key;
+ /// The LLVM target corresponding to the disassembler
+ const llvm::Target *Tgt;
+ /// The assembly information for the target architecture
+ llvm::OwningPtr<const llvm::MCAsmInfo> AsmInfo;
+ /// The disassembler for the target architecture
+ llvm::OwningPtr<const llvm::MCDisassembler> Disassembler;
+ /// The output string for the instruction printer; must be guarded with
+ /// PrinterMutex
+ llvm::OwningPtr<std::string> InstString;
+ /// The output stream for the disassembler; must be guarded with
+ /// PrinterMutex
+ llvm::OwningPtr<llvm::raw_string_ostream> InstStream;
+ /// The instruction printer for the target architecture; must be guarded with
+ /// PrinterMutex when printing
+ llvm::OwningPtr<llvm::MCInstPrinter> InstPrinter;
+ /// The mutex that guards the instruction printer's printing functions, which
+ /// use a shared stream
+ llvm::sys::Mutex PrinterMutex;
+ /// The array of instruction information provided by the TableGen backend for
+ /// the target architecture
+ const InstInfo *InstInfos;
+ /// The target-specific lexer for use in tokenizing strings, in
+ /// target-independent and target-specific portions
+ llvm::OwningPtr<llvm::AsmLexer> GenericAsmLexer;
+ llvm::OwningPtr<llvm::TargetAsmLexer> SpecificAsmLexer;
+ /// The guard for the above
+ llvm::sys::Mutex ParserMutex;
+ /// The LLVM number used for the target disassembly syntax variant
+ int LLVMSyntaxVariant;
+
+ typedef std::vector<std::string> regvec_t;
+ typedef std::map<std::string, unsigned> regrmap_t;
+
+ /// A vector of registers for quick mapping from LLVM register IDs to names
+ regvec_t RegVec;
+ /// A map of registers for quick mapping from register names to LLVM IDs
+ regrmap_t RegRMap;
+
+ /// A set of register IDs for aliases of the stack pointer for the current
+ /// architecture
+ std::set<unsigned> stackPointers;
+ /// A set of register IDs for aliases of the program counter for the current
+ /// architecture
+ std::set<unsigned> programCounters;
+
+ /// Constructor - initializes a disassembler with all the necessary objects,
+ /// which come pre-allocated from the registry accessor function
+ ///
+ /// @arg key - the architecture and disassembly syntax for the
+ /// disassembler
+ EDDisassembler(CPUKey& key);
+
+ /// valid - reports whether there was a failure in the constructor.
+ bool valid() {
+ return Valid;
+ }
+
+ ~EDDisassembler();
+
+ /// createInst - creates and returns an instruction given a callback and
+ /// memory address, or NULL on failure
+ ///
+ /// @arg byteReader - A callback function that provides machine code bytes
+ /// @arg address - The address of the first byte of the instruction,
+ /// suitable for passing to byteReader
+ /// @arg arg - An opaque argument for byteReader
+ EDInst *createInst(EDByteReaderCallback byteReader,
+ uint64_t address,
+ void *arg);
+
+ /// initMaps - initializes regVec and regRMap using the provided register
+ /// info
+ ///
+ /// @arg registerInfo - the register information to use as a source
+ void initMaps(const llvm::TargetRegisterInfo &registerInfo);
+ /// nameWithRegisterID - Returns the name (owned by the EDDisassembler) of a
+ /// register for a given register ID, or NULL on failure
+ ///
+ /// @arg registerID - the ID of the register to be queried
+ const char *nameWithRegisterID(unsigned registerID) const;
+ /// registerIDWithName - Returns the ID of a register for a given register
+ /// name, or (unsigned)-1 on failure
+ ///
+ /// @arg name - The name of the register
+ unsigned registerIDWithName(const char *name) const;
+
+ /// registerIsStackPointer - reports whether a register ID is an alias for the
+ /// stack pointer register
+ ///
+ /// @arg registerID - The LLVM register ID
+ bool registerIsStackPointer(unsigned registerID);
+ /// registerIsStackPointer - reports whether a register ID is an alias for the
+ /// stack pointer register
+ ///
+ /// @arg registerID - The LLVM register ID
+ bool registerIsProgramCounter(unsigned registerID);
+
+ /// printInst - prints an MCInst to a string, returning 0 on success, or -1
+ /// otherwise
+ ///
+ /// @arg str - A reference to a string which is filled in with the string
+ /// representation of the instruction
+ /// @arg inst - A reference to the MCInst to be printed
+ int printInst(std::string& str,
+ llvm::MCInst& inst);
+
+ /// parseInst - extracts operands and tokens from a string for use in
+ /// tokenizing the string. Returns 0 on success, or -1 otherwise.
+ ///
+ /// @arg operands - A reference to a vector that will be filled in with the
+ /// parsed operands
+ /// @arg tokens - A reference to a vector that will be filled in with the
+ /// tokens
+ /// @arg str - The string representation of the instruction
+ int parseInst(llvm::SmallVectorImpl<llvm::MCParsedAsmOperand*> &operands,
+ llvm::SmallVectorImpl<llvm::AsmToken> &tokens,
+ const std::string &str);
+
+ /// llvmSyntaxVariant - returns the LLVM syntax variant for this disassembler
+ int llvmSyntaxVariant() const;
+};
+
+#endif
diff --git a/tools/edis/EDInst.cpp b/tools/edis/EDInst.cpp
new file mode 100644
index 0000000..9ed2700
--- /dev/null
+++ b/tools/edis/EDInst.cpp
@@ -0,0 +1,205 @@
+//===-EDInst.cpp - LLVM Enhanced Disassembler -----------------------------===//
+//
+// 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 Enhanced Disassembly library's instruction class.
+// The instruction is responsible for vending the string representation,
+// individual tokens, and operands for a single instruction.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EDDisassembler.h"
+#include "EDInst.h"
+#include "EDOperand.h"
+#include "EDToken.h"
+
+#include "llvm/MC/MCInst.h"
+
+using namespace llvm;
+
+EDInst::EDInst(llvm::MCInst *inst,
+ uint64_t byteSize,
+ EDDisassembler &disassembler,
+ const InstInfo *info) :
+ Disassembler(disassembler),
+ Inst(inst),
+ ThisInstInfo(info),
+ ByteSize(byteSize),
+ BranchTarget(-1),
+ MoveSource(-1),
+ MoveTarget(-1) {
+}
+
+EDInst::~EDInst() {
+ unsigned int index;
+ unsigned int numOperands = Operands.size();
+
+ for (index = 0; index < numOperands; ++index)
+ delete Operands[index];
+
+ unsigned int numTokens = Tokens.size();
+
+ for (index = 0; index < numTokens; ++index)
+ delete Tokens[index];
+
+ delete Inst;
+}
+
+uint64_t EDInst::byteSize() {
+ return ByteSize;
+}
+
+int EDInst::stringify() {
+ if (StringifyResult.valid())
+ return StringifyResult.result();
+
+ if (Disassembler.printInst(String, *Inst))
+ return StringifyResult.setResult(-1);
+
+ OperandOrder = ThisInstInfo->operandOrders[Disassembler.llvmSyntaxVariant()];
+
+ return StringifyResult.setResult(0);
+}
+
+int EDInst::getString(const char*& str) {
+ if (stringify())
+ return -1;
+
+ str = String.c_str();
+
+ return 0;
+}
+
+unsigned EDInst::instID() {
+ return Inst->getOpcode();
+}
+
+bool EDInst::isBranch() {
+ if (ThisInstInfo)
+ return ThisInstInfo->instructionFlags & kInstructionFlagBranch;
+ else
+ return false;
+}
+
+bool EDInst::isMove() {
+ if (ThisInstInfo)
+ return ThisInstInfo->instructionFlags & kInstructionFlagMove;
+ else
+ return false;
+}
+
+int EDInst::parseOperands() {
+ if (ParseResult.valid())
+ return ParseResult.result();
+
+ if (!ThisInstInfo)
+ return ParseResult.setResult(-1);
+
+ unsigned int opIndex;
+ unsigned int mcOpIndex = 0;
+
+ for (opIndex = 0; opIndex < ThisInstInfo->numOperands; ++opIndex) {
+ if (isBranch() &&
+ (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)) {
+ BranchTarget = opIndex;
+ }
+ else if (isMove()) {
+ if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagSource)
+ MoveSource = opIndex;
+ else if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)
+ MoveTarget = opIndex;
+ }
+
+ EDOperand *operand = new EDOperand(Disassembler, *this, opIndex, mcOpIndex);
+
+ Operands.push_back(operand);
+ }
+
+ return ParseResult.setResult(0);
+}
+
+int EDInst::branchTargetID() {
+ if (parseOperands())
+ return -1;
+ return BranchTarget;
+}
+
+int EDInst::moveSourceID() {
+ if (parseOperands())
+ return -1;
+ return MoveSource;
+}
+
+int EDInst::moveTargetID() {
+ if (parseOperands())
+ return -1;
+ return MoveTarget;
+}
+
+int EDInst::numOperands() {
+ if (parseOperands())
+ return -1;
+ return Operands.size();
+}
+
+int EDInst::getOperand(EDOperand *&operand, unsigned int index) {
+ if (parseOperands())
+ return -1;
+
+ if (index >= Operands.size())
+ return -1;
+
+ operand = Operands[index];
+ return 0;
+}
+
+int EDInst::tokenize() {
+ if (TokenizeResult.valid())
+ return TokenizeResult.result();
+
+ if (stringify())
+ return TokenizeResult.setResult(-1);
+
+ return TokenizeResult.setResult(EDToken::tokenize(Tokens,
+ String,
+ OperandOrder,
+ Disassembler));
+
+}
+
+int EDInst::numTokens() {
+ if (tokenize())
+ return -1;
+ return Tokens.size();
+}
+
+int EDInst::getToken(EDToken *&token, unsigned int index) {
+ if (tokenize())
+ return -1;
+ token = Tokens[index];
+ return 0;
+}
+
+#ifdef __BLOCKS__
+int EDInst::visitTokens(EDTokenVisitor_t visitor) {
+ if (tokenize())
+ return -1;
+
+ tokvec_t::iterator iter;
+
+ for (iter = Tokens.begin(); iter != Tokens.end(); ++iter) {
+ int ret = visitor(*iter);
+ if (ret == 1)
+ return 0;
+ if (ret != 0)
+ return -1;
+ }
+
+ return 0;
+}
+#endif
diff --git a/tools/edis/EDInst.h b/tools/edis/EDInst.h
new file mode 100644
index 0000000..db03a78
--- /dev/null
+++ b/tools/edis/EDInst.h
@@ -0,0 +1,171 @@
+//===-EDInst.h - LLVM Enhanced Disassembler ---------------------*- 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 interface for the Enhanced Disassembly library's
+// instruction class. The instruction is responsible for vending the string
+// representation, individual tokens and operands for a single instruction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EDInst_
+#define EDInst_
+
+#include "llvm-c/EnhancedDisassembly.h"
+
+#include "llvm/ADT/SmallVector.h"
+
+#include <string>
+#include <vector>
+
+/// CachedResult - Encapsulates the result of a function along with the validity
+/// of that result, so that slow functions don't need to run twice
+struct CachedResult {
+ /// True if the result has been obtained by executing the function
+ bool Valid;
+ /// The result last obtained from the function
+ int Result;
+
+ /// Constructor - Initializes an invalid result
+ CachedResult() : Valid(false) { }
+ /// valid - Returns true if the result has been obtained by executing the
+ /// function and false otherwise
+ bool valid() { return Valid; }
+ /// result - Returns the result of the function or an undefined value if
+ /// valid() is false
+ int result() { return Result; }
+ /// setResult - Sets the result of the function and declares it valid
+ /// returning the result (so that setResult() can be called from inside a
+ /// return statement)
+ /// @arg result - The result of the function
+ int setResult(int result) { Result = result; Valid = true; return result; }
+};
+
+/// EDInst - Encapsulates a single instruction, which can be queried for its
+/// string representation, as well as its operands and tokens
+struct EDInst {
+ /// The parent disassembler
+ EDDisassembler &Disassembler;
+ /// The containing MCInst
+ llvm::MCInst *Inst;
+ /// The instruction information provided by TableGen for this instruction
+ const InstInfo *ThisInstInfo;
+ /// The number of bytes for the machine code representation of the instruction
+ uint64_t ByteSize;
+
+ /// The result of the stringify() function
+ CachedResult StringifyResult;
+ /// The string representation of the instruction
+ std::string String;
+ /// The order in which operands from the InstInfo's operand information appear
+ /// in String
+ const char* OperandOrder;
+
+ /// The result of the parseOperands() function
+ CachedResult ParseResult;
+ typedef llvm::SmallVector<EDOperand*, 5> opvec_t;
+ /// The instruction's operands
+ opvec_t Operands;
+ /// The operand corresponding to the target, if the instruction is a branch
+ int BranchTarget;
+ /// The operand corresponding to the source, if the instruction is a move
+ int MoveSource;
+ /// The operand corresponding to the target, if the instruction is a move
+ int MoveTarget;
+
+ /// The result of the tokenize() function
+ CachedResult TokenizeResult;
+ typedef std::vector<EDToken*> tokvec_t;
+ /// The instruction's tokens
+ tokvec_t Tokens;
+
+ /// Constructor - initializes an instruction given the output of the LLVM
+ /// C++ disassembler
+ ///
+ /// @arg inst - The MCInst, which will now be owned by this object
+ /// @arg byteSize - The size of the consumed instruction, in bytes
+ /// @arg disassembler - The parent disassembler
+ /// @arg instInfo - The instruction information produced by the table
+ /// generator for this instruction
+ EDInst(llvm::MCInst *inst,
+ uint64_t byteSize,
+ EDDisassembler &disassembler,
+ const InstInfo *instInfo);
+ ~EDInst();
+
+ /// byteSize - returns the number of bytes consumed by the machine code
+ /// representation of the instruction
+ uint64_t byteSize();
+ /// instID - returns the LLVM instruction ID of the instruction
+ unsigned instID();
+
+ /// stringify - populates the String and AsmString members of the instruction,
+ /// returning 0 on success or -1 otherwise
+ int stringify();
+ /// getString - retrieves a pointer to the string representation of the
+ /// instructinon, returning 0 on success or -1 otherwise
+ ///
+ /// @arg str - A reference to a pointer that, on success, is set to point to
+ /// the string representation of the instruction; this string is still owned
+ /// by the instruction and will be deleted when it is
+ int getString(const char *&str);
+
+ /// isBranch - Returns true if the instruction is a branch
+ bool isBranch();
+ /// isMove - Returns true if the instruction is a move
+ bool isMove();
+
+ /// parseOperands - populates the Operands member of the instruction,
+ /// returning 0 on success or -1 otherwise
+ int parseOperands();
+ /// branchTargetID - returns the ID (suitable for use with getOperand()) of
+ /// the target operand if the instruction is a branch, or -1 otherwise
+ int branchTargetID();
+ /// moveSourceID - returns the ID of the source operand if the instruction
+ /// is a move, or -1 otherwise
+ int moveSourceID();
+ /// moveTargetID - returns the ID of the target operand if the instruction
+ /// is a move, or -1 otherwise
+ int moveTargetID();
+
+ /// numOperands - returns the number of operands available to retrieve, or -1
+ /// on error
+ int numOperands();
+ /// getOperand - retrieves an operand from the instruction's operand list by
+ /// index, returning 0 on success or -1 on error
+ ///
+ /// @arg operand - A reference whose target is pointed at the operand on
+ /// success, although the operand is still owned by the EDInst
+ /// @arg index - The index of the operand in the instruction
+ int getOperand(EDOperand *&operand, unsigned int index);
+
+ /// tokenize - populates the Tokens member of the instruction, returning 0 on
+ /// success or -1 otherwise
+ int tokenize();
+ /// numTokens - returns the number of tokens in the instruction, or -1 on
+ /// error
+ int numTokens();
+ /// getToken - retrieves a token from the instruction's token list by index,
+ /// returning 0 on success or -1 on error
+ ///
+ /// @arg token - A reference whose target is pointed at the token on success,
+ /// although the token is still owned by the EDInst
+ /// @arg index - The index of the token in the instrcutino
+ int getToken(EDToken *&token, unsigned int index);
+
+#ifdef __BLOCKS__
+ /// visitTokens - Visits each token in turn and applies a block to it,
+ /// returning 0 if all blocks are visited and/or the block signals
+ /// termination by returning 1; returns -1 on error
+ ///
+ /// @arg visitor - The visitor block to apply to all tokens.
+ int visitTokens(EDTokenVisitor_t visitor);
+#endif
+};
+
+#endif
diff --git a/tools/edis/EDMain.cpp b/tools/edis/EDMain.cpp
new file mode 100644
index 0000000..3585657
--- /dev/null
+++ b/tools/edis/EDMain.cpp
@@ -0,0 +1,293 @@
+//===-EDMain.cpp - LLVM Enhanced Disassembly C API ------------------------===//
+//
+// 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 enhanced disassembler's public C API.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EDDisassembler.h"
+#include "EDInst.h"
+#include "EDOperand.h"
+#include "EDToken.h"
+
+#include "llvm-c/EnhancedDisassembly.h"
+
+int EDGetDisassembler(EDDisassemblerRef *disassembler,
+ const char *triple,
+ EDAssemblySyntax_t syntax) {
+ EDDisassembler::initialize();
+
+ EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple,
+ syntax);
+
+ if (ret) {
+ *disassembler = ret;
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+int EDGetRegisterName(const char** regName,
+ EDDisassemblerRef disassembler,
+ unsigned regID) {
+ const char* name = disassembler->nameWithRegisterID(regID);
+ if(!name)
+ return -1;
+ *regName = name;
+ return 0;
+}
+
+int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
+ unsigned regID) {
+ return disassembler->registerIsStackPointer(regID) ? 1 : 0;
+}
+
+int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
+ unsigned regID) {
+ return disassembler->registerIsProgramCounter(regID) ? 1 : 0;
+}
+
+unsigned int EDCreateInsts(EDInstRef *insts,
+ unsigned int count,
+ EDDisassemblerRef disassembler,
+ EDByteReaderCallback byteReader,
+ uint64_t address,
+ void *arg) {
+ unsigned int index;
+
+ for (index = 0; index < count; index++) {
+ EDInst *inst = disassembler->createInst(byteReader, address, arg);
+
+ if(!inst)
+ return index;
+
+ insts[index] = inst;
+ address += inst->byteSize();
+ }
+
+ return count;
+}
+
+void EDReleaseInst(EDInstRef inst) {
+ delete inst;
+}
+
+int EDInstByteSize(EDInstRef inst) {
+ return inst->byteSize();
+}
+
+int EDGetInstString(const char **buf,
+ EDInstRef inst) {
+ return inst->getString(*buf);
+}
+
+int EDInstID(unsigned *instID, EDInstRef inst) {
+ *instID = inst->instID();
+ return 0;
+}
+
+int EDInstIsBranch(EDInstRef inst) {
+ return inst->isBranch();
+}
+
+int EDInstIsMove(EDInstRef inst) {
+ return inst->isMove();
+}
+
+int EDBranchTargetID(EDInstRef inst) {
+ return inst->branchTargetID();
+}
+
+int EDMoveSourceID(EDInstRef inst) {
+ return inst->moveSourceID();
+}
+
+int EDMoveTargetID(EDInstRef inst) {
+ return inst->moveTargetID();
+}
+
+int EDNumTokens(EDInstRef inst) {
+ return inst->numTokens();
+}
+
+int EDGetToken(EDTokenRef *token,
+ EDInstRef inst,
+ int index) {
+ return inst->getToken(*token, index);
+}
+
+int EDGetTokenString(const char **buf,
+ EDTokenRef token) {
+ return token->getString(*buf);
+}
+
+int EDOperandIndexForToken(EDTokenRef token) {
+ return token->operandID();
+}
+
+int EDTokenIsWhitespace(EDTokenRef token) {
+ if(token->type() == EDToken::kTokenWhitespace)
+ return 1;
+ else
+ return 0;
+}
+
+int EDTokenIsPunctuation(EDTokenRef token) {
+ if(token->type() == EDToken::kTokenPunctuation)
+ return 1;
+ else
+ return 0;
+}
+
+int EDTokenIsOpcode(EDTokenRef token) {
+ if(token->type() == EDToken::kTokenOpcode)
+ return 1;
+ else
+ return 0;
+}
+
+int EDTokenIsLiteral(EDTokenRef token) {
+ if(token->type() == EDToken::kTokenLiteral)
+ return 1;
+ else
+ return 0;
+}
+
+int EDTokenIsRegister(EDTokenRef token) {
+ if(token->type() == EDToken::kTokenRegister)
+ return 1;
+ else
+ return 0;
+}
+
+int EDTokenIsNegativeLiteral(EDTokenRef token) {
+ if(token->type() != EDToken::kTokenLiteral)
+ return -1;
+
+ return token->literalSign();
+}
+
+int EDLiteralTokenAbsoluteValue(uint64_t *value,
+ EDTokenRef token) {
+ if(token->type() != EDToken::kTokenLiteral)
+ return -1;
+
+ return token->literalAbsoluteValue(*value);
+}
+
+int EDRegisterTokenValue(unsigned *registerID,
+ EDTokenRef token) {
+ if(token->type() != EDToken::kTokenRegister)
+ return -1;
+
+ return token->registerID(*registerID);
+}
+
+int EDNumOperands(EDInstRef inst) {
+ return inst->numOperands();
+}
+
+int EDGetOperand(EDOperandRef *operand,
+ EDInstRef inst,
+ int index) {
+ return inst->getOperand(*operand, index);
+}
+
+int EDOperandIsRegister(EDOperandRef operand) {
+ return operand->isRegister();
+}
+
+int EDOperandIsImmediate(EDOperandRef operand) {
+ return operand->isImmediate();
+}
+
+int EDOperandIsMemory(EDOperandRef operand) {
+ return operand->isMemory();
+}
+
+int EDRegisterOperandValue(unsigned *value,
+ EDOperandRef operand) {
+ if(!operand->isRegister())
+ return -1;
+ *value = operand->regVal();
+ return 0;
+}
+
+int EDImmediateOperandValue(uint64_t *value,
+ EDOperandRef operand) {
+ if(!operand->isImmediate())
+ return -1;
+ *value = operand->immediateVal();
+ return 0;
+}
+
+int EDEvaluateOperand(uint64_t *result,
+ EDOperandRef operand,
+ EDRegisterReaderCallback regReader,
+ void *arg) {
+ return operand->evaluate(*result, regReader, arg);
+}
+
+#ifdef __BLOCKS__
+
+struct ByteReaderWrapper {
+ EDByteBlock_t byteBlock;
+};
+
+static int readerWrapperCallback(uint8_t *byte,
+ uint64_t address,
+ void *arg) {
+ struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
+ return wrapper->byteBlock(byte, address);
+}
+
+unsigned int EDBlockCreateInsts(EDInstRef *insts,
+ int count,
+ EDDisassemblerRef disassembler,
+ EDByteBlock_t byteBlock,
+ uint64_t address) {
+ struct ByteReaderWrapper wrapper;
+ wrapper.byteBlock = byteBlock;
+
+ return EDCreateInsts(insts,
+ count,
+ disassembler,
+ readerWrapperCallback,
+ address,
+ (void*)&wrapper);
+}
+
+int EDBlockEvaluateOperand(uint64_t *result,
+ EDOperandRef operand,
+ EDRegisterBlock_t regBlock) {
+ return operand->evaluate(*result, regBlock);
+}
+
+int EDBlockVisitTokens(EDInstRef inst,
+ EDTokenVisitor_t visitor) {
+ return inst->visitTokens(visitor);
+}
+
+#else
+
+extern "C" unsigned int EDBlockCreateInsts() {
+ return 0;
+}
+
+extern "C" int EDBlockEvaluateOperand() {
+ return -1;
+}
+
+extern "C" int EDBlockVisitTokens() {
+ return -1;
+}
+
+#endif
diff --git a/tools/edis/EDOperand.cpp b/tools/edis/EDOperand.cpp
new file mode 100644
index 0000000..da6797e
--- /dev/null
+++ b/tools/edis/EDOperand.cpp
@@ -0,0 +1,168 @@
+//===-EDOperand.cpp - LLVM Enhanced Disassembler --------------------------===//
+//
+// 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 Enhanced Disassembly library's operand class. The
+// operand is responsible for allowing evaluation given a particular register
+// context.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EDDisassembler.h"
+#include "EDInst.h"
+#include "EDOperand.h"
+
+#include "llvm/MC/MCInst.h"
+
+using namespace llvm;
+
+EDOperand::EDOperand(const EDDisassembler &disassembler,
+ const EDInst &inst,
+ unsigned int opIndex,
+ unsigned int &mcOpIndex) :
+ Disassembler(disassembler),
+ Inst(inst),
+ OpIndex(opIndex),
+ MCOpIndex(mcOpIndex) {
+ unsigned int numMCOperands = 0;
+
+ if(Disassembler.Key.Arch == Triple::x86 ||
+ Disassembler.Key.Arch == Triple::x86_64) {
+ uint8_t operandFlags = inst.ThisInstInfo->operandFlags[opIndex];
+
+ if (operandFlags & kOperandFlagImmediate) {
+ numMCOperands = 1;
+ }
+ else if (operandFlags & kOperandFlagRegister) {
+ numMCOperands = 1;
+ }
+ else if (operandFlags & kOperandFlagMemory) {
+ if (operandFlags & kOperandFlagPCRelative) {
+ numMCOperands = 1;
+ }
+ else {
+ numMCOperands = 5;
+ }
+ }
+ else if (operandFlags & kOperandFlagEffectiveAddress) {
+ numMCOperands = 4;
+ }
+ }
+
+ mcOpIndex += numMCOperands;
+}
+
+EDOperand::~EDOperand() {
+}
+
+int EDOperand::evaluate(uint64_t &result,
+ EDRegisterReaderCallback callback,
+ void *arg) {
+ if (Disassembler.Key.Arch == Triple::x86 ||
+ Disassembler.Key.Arch == Triple::x86_64) {
+ uint8_t operandFlags = Inst.ThisInstInfo->operandFlags[OpIndex];
+
+ if (operandFlags & kOperandFlagImmediate) {
+ result = Inst.Inst->getOperand(MCOpIndex).getImm();
+ return 0;
+ }
+ if (operandFlags & kOperandFlagRegister) {
+ unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
+ return callback(&result, reg, arg);
+ }
+ if (operandFlags & kOperandFlagMemory ||
+ operandFlags & kOperandFlagEffectiveAddress){
+ if(operandFlags & kOperandFlagPCRelative) {
+ int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
+
+ uint64_t ripVal;
+
+ // TODO fix how we do this
+
+ if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
+ return -1;
+
+ result = ripVal + displacement;
+ return 0;
+ }
+ else {
+ unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
+ uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
+ unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
+ int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
+ //unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
+
+ uint64_t addr = 0;
+
+ if(baseReg) {
+ uint64_t baseVal;
+ if (callback(&baseVal, baseReg, arg))
+ return -1;
+ addr += baseVal;
+ }
+
+ if(indexReg) {
+ uint64_t indexVal;
+ if (callback(&indexVal, indexReg, arg))
+ return -1;
+ addr += (scaleAmount * indexVal);
+ }
+
+ addr += displacement;
+
+ result = addr;
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ return -1;
+}
+
+int EDOperand::isRegister() {
+ return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagRegister);
+}
+
+unsigned EDOperand::regVal() {
+ return Inst.Inst->getOperand(MCOpIndex).getReg();
+}
+
+int EDOperand::isImmediate() {
+ return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagImmediate);
+}
+
+uint64_t EDOperand::immediateVal() {
+ return Inst.Inst->getOperand(MCOpIndex).getImm();
+}
+
+int EDOperand::isMemory() {
+ return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagMemory);
+}
+
+#ifdef __BLOCKS__
+struct RegisterReaderWrapper {
+ EDRegisterBlock_t regBlock;
+};
+
+int readerWrapperCallback(uint64_t *value,
+ unsigned regID,
+ void *arg) {
+ struct RegisterReaderWrapper *wrapper = (struct RegisterReaderWrapper *)arg;
+ return wrapper->regBlock(value, regID);
+}
+
+int EDOperand::evaluate(uint64_t &result,
+ EDRegisterBlock_t regBlock) {
+ struct RegisterReaderWrapper wrapper;
+ wrapper.regBlock = regBlock;
+ return evaluate(result,
+ readerWrapperCallback,
+ (void*)&wrapper);
+}
+#endif
diff --git a/tools/edis/EDOperand.h b/tools/edis/EDOperand.h
new file mode 100644
index 0000000..ad9345b
--- /dev/null
+++ b/tools/edis/EDOperand.h
@@ -0,0 +1,78 @@
+//===-EDOperand.h - LLVM Enhanced Disassembler ------------------*- 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 interface for the Enhanced Disassembly library's
+// operand class. The operand is responsible for allowing evaluation given a
+// particular register context.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EDOperand_
+#define EDOperand_
+
+#include "llvm-c/EnhancedDisassembly.h"
+
+/// EDOperand - Encapsulates a single operand, which can be evaluated by the
+/// client
+struct EDOperand {
+ /// The parent disassembler
+ const EDDisassembler &Disassembler;
+ /// The parent instruction
+ const EDInst &Inst;
+
+ /// The index of the operand in the EDInst
+ unsigned int OpIndex;
+ /// The index of the first component of the operand in the MCInst
+ unsigned int MCOpIndex;
+
+ /// Constructor - Initializes an EDOperand
+ ///
+ /// @arg disassembler - The disassembler responsible for the operand
+ /// @arg inst - The instruction containing this operand
+ /// @arg opIndex - The index of the operand in inst
+ /// @arg mcOpIndex - The index of the operand in the original MCInst
+ EDOperand(const EDDisassembler &disassembler,
+ const EDInst &inst,
+ unsigned int opIndex,
+ unsigned int &mcOpIndex);
+ ~EDOperand();
+
+ /// evaluate - Returns the numeric value of an operand to the extent possible,
+ /// returning 0 on success or -1 if there was some problem (such as a
+ /// register not being readable)
+ ///
+ /// @arg result - A reference whose target is filled in with the value of
+ /// the operand (the address if it is a memory operand)
+ /// @arg callback - A function to call to obtain register values
+ /// @arg arg - An opaque argument to pass to callback
+ int evaluate(uint64_t &result,
+ EDRegisterReaderCallback callback,
+ void *arg);
+
+ /// isRegister - Returns 1 if the operand is a register or 0 otherwise
+ int isRegister();
+ /// regVal - Returns the register value.
+ unsigned regVal();
+
+ /// isImmediate - Returns 1 if the operand is an immediate or 0 otherwise
+ int isImmediate();
+ /// immediateVal - Returns the immediate value.
+ uint64_t immediateVal();
+
+ /// isMemory - Returns 1 if the operand is a memory location or 0 otherwise
+ int isMemory();
+
+#ifdef __BLOCKS__
+ /// evaluate - Like evaluate for a callback, but uses a block instead
+ int evaluate(uint64_t &result,
+ EDRegisterBlock_t regBlock);
+#endif
+};
+
+#endif
diff --git a/tools/edis/EDToken.cpp b/tools/edis/EDToken.cpp
new file mode 100644
index 0000000..cd79152
--- /dev/null
+++ b/tools/edis/EDToken.cpp
@@ -0,0 +1,208 @@
+//===-EDToken.cpp - LLVM Enhanced Disassembler ----------------------------===//
+//
+// 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 Enhanced Disassembler library's token class. The
+// token is responsible for vending information about the token, such as its
+// type and logical value.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EDDisassembler.h"
+#include "EDToken.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
+
+using namespace llvm;
+
+EDToken::EDToken(StringRef str,
+ enum tokenType type,
+ uint64_t localType,
+ EDDisassembler &disassembler) :
+ Disassembler(disassembler),
+ Str(str),
+ Type(type),
+ LocalType(localType),
+ OperandID(-1) {
+}
+
+EDToken::~EDToken() {
+}
+
+void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) {
+ Type = kTokenLiteral;
+ LiteralSign = sign;
+ LiteralAbsoluteValue = absoluteValue;
+}
+
+void EDToken::makeRegister(unsigned registerID) {
+ Type = kTokenRegister;
+ RegisterID = registerID;
+}
+
+void EDToken::setOperandID(int operandID) {
+ OperandID = operandID;
+}
+
+enum EDToken::tokenType EDToken::type() const {
+ return Type;
+}
+
+uint64_t EDToken::localType() const {
+ return LocalType;
+}
+
+StringRef EDToken::string() const {
+ return Str;
+}
+
+int EDToken::operandID() const {
+ return OperandID;
+}
+
+int EDToken::literalSign() const {
+ if(Type != kTokenLiteral)
+ return -1;
+ return (LiteralSign ? 1 : 0);
+}
+
+int EDToken::literalAbsoluteValue(uint64_t &value) const {
+ if(Type != kTokenLiteral)
+ return -1;
+ value = LiteralAbsoluteValue;
+ return 0;
+}
+
+int EDToken::registerID(unsigned &registerID) const {
+ if(Type != kTokenRegister)
+ return -1;
+ registerID = RegisterID;
+ return 0;
+}
+
+int EDToken::tokenize(std::vector<EDToken*> &tokens,
+ std::string &str,
+ const char *operandOrder,
+ EDDisassembler &disassembler) {
+ SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
+ SmallVector<AsmToken, 10> asmTokens;
+
+ if(disassembler.parseInst(parsedOperands, asmTokens, str))
+ return -1;
+
+ SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
+ unsigned int operandIndex;
+ SmallVectorImpl<AsmToken>::iterator tokenIterator;
+
+ operandIterator = parsedOperands.begin();
+ operandIndex = 0;
+
+ bool readOpcode = false;
+
+ const char *wsPointer = asmTokens.begin()->getLoc().getPointer();
+
+ for (tokenIterator = asmTokens.begin();
+ tokenIterator != asmTokens.end();
+ ++tokenIterator) {
+ SMLoc tokenLoc = tokenIterator->getLoc();
+
+ const char *tokenPointer = tokenLoc.getPointer();
+
+ if(tokenPointer > wsPointer) {
+ unsigned long wsLength = tokenPointer - wsPointer;
+
+ EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength),
+ EDToken::kTokenWhitespace,
+ 0,
+ disassembler);
+
+ tokens.push_back(whitespaceToken);
+ }
+
+ wsPointer = tokenPointer + tokenIterator->getString().size();
+
+ while (operandIterator != parsedOperands.end() &&
+ tokenLoc.getPointer() >
+ (*operandIterator)->getEndLoc().getPointer()) {
+ ++operandIterator;
+ ++operandIndex;
+ }
+
+ EDToken *token;
+
+ switch (tokenIterator->getKind()) {
+ case AsmToken::Identifier:
+ if (!readOpcode) {
+ token = new EDToken(tokenIterator->getString(),
+ EDToken::kTokenOpcode,
+ (uint64_t)tokenIterator->getKind(),
+ disassembler);
+ readOpcode = true;
+ break;
+ }
+ // any identifier that isn't an opcode is mere punctuation; so we fall
+ // through
+ default:
+ token = new EDToken(tokenIterator->getString(),
+ EDToken::kTokenPunctuation,
+ (uint64_t)tokenIterator->getKind(),
+ disassembler);
+ break;
+ case AsmToken::Integer:
+ {
+ token = new EDToken(tokenIterator->getString(),
+ EDToken::kTokenLiteral,
+ (uint64_t)tokenIterator->getKind(),
+ disassembler);
+
+ int64_t intVal = tokenIterator->getIntVal();
+
+ if(intVal < 0)
+ token->makeLiteral(true, -intVal);
+ else
+ token->makeLiteral(false, intVal);
+ break;
+ }
+ case AsmToken::Register:
+ {
+ token = new EDToken(tokenIterator->getString(),
+ EDToken::kTokenLiteral,
+ (uint64_t)tokenIterator->getKind(),
+ disassembler);
+
+ token->makeRegister((unsigned)tokenIterator->getRegVal());
+ break;
+ }
+ }
+
+ if(operandIterator != parsedOperands.end() &&
+ tokenLoc.getPointer() >=
+ (*operandIterator)->getStartLoc().getPointer()) {
+ /// operandIndex == 0 means the operand is the instruction (which the
+ /// AsmParser treats as an operand but edis does not). We therefore skip
+ /// operandIndex == 0 and subtract 1 from all other operand indices.
+
+ if(operandIndex > 0)
+ token->setOperandID(operandOrder[operandIndex - 1]);
+ }
+
+ tokens.push_back(token);
+ }
+
+ return 0;
+}
+
+int EDToken::getString(const char*& buf) {
+ if(PermStr.length() == 0) {
+ PermStr = Str.str();
+ }
+ buf = PermStr.c_str();
+ return 0;
+}
diff --git a/tools/edis/EDToken.h b/tools/edis/EDToken.h
new file mode 100644
index 0000000..e4ae91f
--- /dev/null
+++ b/tools/edis/EDToken.h
@@ -0,0 +1,135 @@
+//===-EDToken.h - LLVM Enhanced Disassembler --------------------*- 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 interface for the Enhanced Disassembly library's token
+// class. The token is responsible for vending information about the token,
+// such as its type and logical value.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EDToken_
+#define EDToken_
+
+#include "llvm-c/EnhancedDisassembly.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <string>
+#include <vector>
+
+/// EDToken - Encapsulates a single token, which can provide a string
+/// representation of itself or interpret itself in various ways, depending
+/// on the token type.
+struct EDToken {
+ enum tokenType {
+ kTokenWhitespace,
+ kTokenOpcode,
+ kTokenLiteral,
+ kTokenRegister,
+ kTokenPunctuation
+ };
+
+ /// The parent disassembler
+ EDDisassembler &Disassembler;
+
+ /// The token's string representation
+ llvm::StringRef Str;
+ /// The token's string representation, but in a form suitable for export
+ std::string PermStr;
+ /// The type of the token, as exposed through the external API
+ enum tokenType Type;
+ /// The type of the token, as recorded by the syntax-specific tokenizer
+ uint64_t LocalType;
+ /// The operand corresponding to the token, or (unsigned int)-1 if not
+ /// part of an operand.
+ int OperandID;
+
+ /// The sign if the token is a literal (1 if negative, 0 otherwise)
+ bool LiteralSign;
+ /// The absolute value if the token is a literal
+ uint64_t LiteralAbsoluteValue;
+ /// The LLVM register ID if the token is a register name
+ unsigned RegisterID;
+
+ /// Constructor - Initializes an EDToken with the information common to all
+ /// tokens
+ ///
+ /// @arg str - The string corresponding to the token
+ /// @arg type - The token's type as exposed through the public API
+ /// @arg localType - The token's type as recorded by the tokenizer
+ /// @arg disassembler - The disassembler responsible for the token
+ EDToken(llvm::StringRef str,
+ enum tokenType type,
+ uint64_t localType,
+ EDDisassembler &disassembler);
+
+ /// makeLiteral - Adds the information specific to a literal
+ /// @arg sign - The sign of the literal (1 if negative, 0
+ /// otherwise)
+ ///
+ /// @arg absoluteValue - The absolute value of the literal
+ void makeLiteral(bool sign, uint64_t absoluteValue);
+ /// makeRegister - Adds the information specific to a register
+ ///
+ /// @arg registerID - The LLVM register ID
+ void makeRegister(unsigned registerID);
+
+ /// setOperandID - Links the token to a numbered operand
+ ///
+ /// @arg operandID - The operand ID to link to
+ void setOperandID(int operandID);
+
+ ~EDToken();
+
+ /// type - Returns the public type of the token
+ enum tokenType type() const;
+ /// localType - Returns the tokenizer-specific type of the token
+ uint64_t localType() const;
+ /// string - Returns the string representation of the token
+ llvm::StringRef string() const;
+ /// operandID - Returns the operand ID of the token
+ int operandID() const;
+
+ /// literalSign - Returns the sign of the token
+ /// (1 if negative, 0 if positive or unsigned, -1 if it is not a literal)
+ int literalSign() const;
+ /// literalAbsoluteValue - Retrieves the absolute value of the token, and
+ /// returns -1 if the token is not a literal
+ /// @arg value - A reference to a value that is filled in with the absolute
+ /// value, if it is valid
+ int literalAbsoluteValue(uint64_t &value) const;
+ /// registerID - Retrieves the register ID of the token, and returns -1 if the
+ /// token is not a register
+ ///
+ /// @arg registerID - A reference to a value that is filled in with the
+ /// register ID, if it is valid
+ int registerID(unsigned &registerID) const;
+
+ /// tokenize - Tokenizes a string using the platform- and syntax-specific
+ /// tokenizer, and returns 0 on success (-1 on failure)
+ ///
+ /// @arg tokens - A vector that will be filled in with pointers to
+ /// allocated tokens
+ /// @arg str - The string, as outputted by the AsmPrinter
+ /// @arg operandOrder - The order of the operands from the operandFlags array
+ /// as they appear in str
+ /// @arg disassembler - The disassembler for the desired target and
+ // assembly syntax
+ static int tokenize(std::vector<EDToken*> &tokens,
+ std::string &str,
+ const char *operandOrder,
+ EDDisassembler &disassembler);
+
+ /// getString - Directs a character pointer to the string, returning 0 on
+ /// success (-1 on failure)
+ /// @arg buf - A reference to a pointer that is set to point to the string.
+ /// The string is still owned by the token.
+ int getString(const char*& buf);
+};
+
+#endif
diff --git a/tools/edis/EnhancedDisassembly.exports b/tools/edis/EnhancedDisassembly.exports
new file mode 100644
index 0000000..d3f8743
--- /dev/null
+++ b/tools/edis/EnhancedDisassembly.exports
@@ -0,0 +1,36 @@
+_EDGetDisassembler
+_EDGetRegisterName
+_EDRegisterIsStackPointer
+_EDRegisterIsProgramCounter
+_EDCreateInsts
+_EDReleaseInst
+_EDInstByteSize
+_EDGetInstString
+_EDInstIsBranch
+_EDInstIsMove
+_EDBranchTargetID
+_EDMoveSourceID
+_EDMoveTargetID
+_EDNumTokens
+_EDGetToken
+_EDGetTokenString
+_EDOperandIndexForToken
+_EDTokenIsWhitespace
+_EDTokenIsPunctuation
+_EDTokenIsOpcode
+_EDTokenIsLiteral
+_EDTokenIsRegister
+_EDTokenIsNegativeLiteral
+_EDLiteralTokenAbsoluteValue
+_EDRegisterTokenValue
+_EDNumOperands
+_EDGetOperand
+_EDOperandIsRegister
+_EDOperandIsImmediate
+_EDOperandIsMemory
+_EDRegisterOperandValue
+_EDImmediateOperandValue
+_EDEvaluateOperand
+_EDBlockCreateInsts
+_EDBlockEvaluateOperand
+_EDBlockVisitTokens
diff --git a/tools/edis/Makefile b/tools/edis/Makefile
new file mode 100644
index 0000000..a3c5879
--- /dev/null
+++ b/tools/edis/Makefile
@@ -0,0 +1,55 @@
+##===- tools/ed/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 = EnhancedDisassembly
+
+BUILT_SOURCES = EDInfo.inc
+
+# Include this here so we can get the configuration of the targets
+# that have been configured for construction. We have to do this
+# early so we can set up LINK_COMPONENTS before including Makefile.rules
+include $(LEVEL)/Makefile.config
+
+LINK_LIBS_IN_SHARED = 1
+SHARED_LIBRARY = 1
+
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) x86asmprinter x86disassembler
+
+include $(LEVEL)/Makefile.common
+
+ifeq ($(HOST_OS),Darwin)
+ # set dylib internal version number to llvmCore submission number
+ ifdef LLVM_SUBMIT_VERSION
+ LLVMLibsOptions := $(LLVMLibsOptions) -Wl,-current_version \
+ -Wl,$(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION) \
+ -Wl,-compatibility_version -Wl,1
+ endif
+ # extra options to override libtool defaults
+ LLVMLibsOptions := $(LLVMLibsOptions) \
+ -avoid-version \
+ -Wl,-exported_symbols_list -Wl,$(PROJ_SRC_DIR)/EnhancedDisassembly.exports \
+ -Wl,-dead_strip \
+ -Wl,-seg1addr -Wl,0xE0000000
+
+ # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line
+ DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/')
+ ifneq ($(DARWIN_VERS),8)
+ LLVMLibsOptions := $(LLVMLibsOptions) \
+ -no-undefined -Wl,-install_name \
+ -Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)"
+ endif
+endif
+
+EDInfo.inc: $(TBLGEN)
+ $(Echo) "Building semantic information header"
+ $(Verb) $(TableGen) -o $(call SYSPATH, $@) -gen-enhanced-disassembly-header /dev/null
+
+clean::
+ -$(Verb) $(RM) -f EDInfo.inc
diff --git a/tools/gold/Makefile b/tools/gold/Makefile
index 3f77229..7bac4ec 100644
--- a/tools/gold/Makefile
+++ b/tools/gold/Makefile
@@ -19,7 +19,6 @@ LINK_LIBS_IN_SHARED=1
SHARED_LIBRARY = 1
BUILD_ARCHIVE = 0
LOADABLE_MODULE = 1
-CXXFLAGS = -fno-rtti
LINK_COMPONENTS := support system
LIBS += -llto
diff --git a/tools/llc/Makefile b/tools/llc/Makefile
index 6b5b125..7319aad 100644
--- a/tools/llc/Makefile
+++ b/tools/llc/Makefile
@@ -9,7 +9,6 @@
LEVEL = ../..
TOOLNAME = llc
-CXXFLAGS = -fno-rtti
# Include this here so we can get the configuration of the targets
# that have been configured for construction. We have to do this
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 4f93a43..fe34bd1 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -15,16 +15,13 @@
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Support/IRReader.h"
-#include "llvm/CodeGen/FileWriters.h"
#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
#include "llvm/CodeGen/LinkAllCodegenComponents.h"
-#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include "llvm/Config/config.h"
#include "llvm/LinkAllVMCore.h"
#include "llvm/Support/CommandLine.h"
@@ -87,16 +84,15 @@ MAttrs("mattr",
cl::value_desc("a1,+a2,-a3,..."));
cl::opt<TargetMachine::CodeGenFileType>
-FileType("filetype", cl::init(TargetMachine::AssemblyFile),
+FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
cl::desc("Choose a file type (not all types are supported by all targets):"),
cl::values(
- clEnumValN(TargetMachine::AssemblyFile, "asm",
+ clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
"Emit an assembly ('.s') file"),
- clEnumValN(TargetMachine::ObjectFile, "obj",
+ clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
"Emit a native object ('.o') file [experimental]"),
- clEnumValN(TargetMachine::DynamicLibrary, "dynlib",
- "Emit a native dynamic library ('.so') file"
- " [experimental]"),
+ clEnumValN(TargetMachine::CGFT_Null, "null",
+ "Emit nothing, for performance testing"),
clEnumValEnd));
cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
@@ -164,7 +160,8 @@ static formatted_raw_ostream *GetOutputStream(const char *TargetName,
bool Binary = false;
switch (FileType) {
- case TargetMachine::AssemblyFile:
+ default: assert(0 && "Unknown file type");
+ case TargetMachine::CGFT_AssemblyFile:
if (TargetName[0] == 'c') {
if (TargetName[1] == 0)
OutputFilename += ".cbe.c";
@@ -175,12 +172,12 @@ static formatted_raw_ostream *GetOutputStream(const char *TargetName,
} else
OutputFilename += ".s";
break;
- case TargetMachine::ObjectFile:
+ case TargetMachine::CGFT_ObjectFile:
OutputFilename += ".o";
Binary = true;
break;
- case TargetMachine::DynamicLibrary:
- OutputFilename += LTDL_SHLIB_EXT;
+ case TargetMachine::CGFT_Null:
+ OutputFilename += ".null";
Binary = true;
break;
}
@@ -334,8 +331,7 @@ int main(int argc, char **argv) {
PM.run(mod);
} else {
// Build up all of the passes that we want to do to the module.
- ExistingModuleProvider Provider(M.release());
- FunctionPassManager Passes(&Provider);
+ FunctionPassManager Passes(M.get());
// Add the target data from the target machine, if it exists, or the module.
if (const TargetData *TD = Target.getTargetData())
@@ -348,32 +344,10 @@ int main(int argc, char **argv) {
Passes.add(createVerifierPass());
#endif
- // Ask the target to add backend passes as necessary.
- ObjectCodeEmitter *OCE = 0;
-
// Override default to generate verbose assembly.
Target.setAsmVerbosityDefault(true);
- switch (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl)) {
- default:
- assert(0 && "Invalid file model!");
- return 1;
- case FileModel::Error:
- errs() << argv[0] << ": target does not support generation of this"
- << " file type!\n";
- if (Out != &fouts()) delete Out;
- // And the Out file is empty and useless, so remove it now.
- sys::Path(OutputFilename).eraseFromDisk();
- return 1;
- case FileModel::AsmFile:
- case FileModel::MachOFile:
- break;
- case FileModel::ElfFile:
- OCE = AddELFWriter(Passes, *Out, Target);
- break;
- }
-
- if (Target.addPassesToEmitFileFinish(Passes, OCE, OLvl)) {
+ if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl)) {
errs() << argv[0] << ": target does not support generation of this"
<< " file type!\n";
if (Out != &fouts()) delete Out;
diff --git a/tools/lli/Makefile b/tools/lli/Makefile
index 2341bed..8f6eeed 100644
--- a/tools/lli/Makefile
+++ b/tools/lli/Makefile
@@ -9,7 +9,6 @@
LEVEL := ../..
TOOLNAME := lli
-CXXFLAGS = -fno-rtti
LINK_COMPONENTS := jit interpreter nativecodegen bitreader selectiondag
# Enable JIT support
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index 218bb93..81c17cd 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -15,7 +15,6 @@
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/Type.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/CodeGen/LinkAllCodegenComponents.h"
@@ -59,6 +58,22 @@ namespace {
TargetTriple("mtriple", cl::desc("Override target triple for module"));
cl::opt<std::string>
+ MArch("march",
+ cl::desc("Architecture to generate assembly for (see --version)"));
+
+ cl::opt<std::string>
+ MCPU("mcpu",
+ cl::desc("Target a specific cpu type (-mcpu=help for details)"),
+ cl::value_desc("cpu-name"),
+ cl::init(""));
+
+ cl::list<std::string>
+ MAttrs("mattr",
+ cl::CommaSeparated,
+ cl::desc("Target specific attributes (-mattr=help for details)"),
+ cl::value_desc("a1,+a2,-a3,..."));
+
+ cl::opt<std::string>
EntryFunc("entry-function",
cl::desc("Specify the entry function (default = 'main') "
"of the executable"),
@@ -110,28 +125,31 @@ int main(int argc, char **argv, char * const *envp) {
// Load the bitcode...
std::string ErrorMsg;
- ModuleProvider *MP = NULL;
+ Module *Mod = NULL;
if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFile,&ErrorMsg)){
- MP = getBitcodeModuleProvider(Buffer, Context, &ErrorMsg);
- if (!MP) delete Buffer;
+ Mod = getLazyBitcodeModule(Buffer, Context, &ErrorMsg);
+ if (!Mod) delete Buffer;
}
- if (!MP) {
+ if (!Mod) {
errs() << argv[0] << ": error loading program '" << InputFile << "': "
<< ErrorMsg << "\n";
exit(1);
}
- // Get the module as the MP could go away once EE takes over.
- Module *Mod = NoLazyCompilation
- ? MP->materializeModule(&ErrorMsg) : MP->getModule();
- if (!Mod) {
- errs() << argv[0] << ": bitcode didn't read correctly.\n";
- errs() << "Reason: " << ErrorMsg << "\n";
- exit(1);
+ // If not jitting lazily, load the whole bitcode file eagerly too.
+ if (NoLazyCompilation) {
+ if (Mod->MaterializeAllPermanently(&ErrorMsg)) {
+ errs() << argv[0] << ": bitcode didn't read correctly.\n";
+ errs() << "Reason: " << ErrorMsg << "\n";
+ exit(1);
+ }
}
- EngineBuilder builder(MP);
+ EngineBuilder builder(Mod);
+ builder.setMArch(MArch);
+ builder.setMCPU(MCPU);
+ builder.setMAttrs(MAttrs);
builder.setErrorStr(&ErrorMsg);
builder.setEngineKind(ForceInterpreter
? EngineKind::Interpreter
diff --git a/tools/llvm-ar/Makefile b/tools/llvm-ar/Makefile
index 3db7964..e4fe4e8 100644
--- a/tools/llvm-ar/Makefile
+++ b/tools/llvm-ar/Makefile
@@ -11,7 +11,6 @@ LEVEL = ../..
TOOLNAME = llvm-ar
LINK_COMPONENTS = archive
REQUIRES_EH := 1
-#CXXFLAGS = -fno-rtti
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-as/Makefile b/tools/llvm-as/Makefile
index d6fbd71..e1e5853 100644
--- a/tools/llvm-as/Makefile
+++ b/tools/llvm-as/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../..
TOOLNAME = llvm-as
LINK_COMPONENTS := asmparser bitwriter
-CXXFLAGS = -fno-rtti
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-config/Makefile b/tools/llvm-config/Makefile
index e5bdc04..cc5cf43 100644
--- a/tools/llvm-config/Makefile
+++ b/tools/llvm-config/Makefile
@@ -53,6 +53,46 @@ llvm-config.in: $(ConfigInIn) $(ConfigStatusScript)
$(Verb) cd $(PROJ_OBJ_ROOT) ; \
$(ConfigStatusScript) tools/llvm-config/llvm-config.in
+llvm-config-perobj: llvm-config.in $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a)
+ $(Echo) "Generating llvm-config-perobj"
+ $(Verb) $(PERL) $(GenLibDeps) -perobj -flat $(LibDir) "$(NM_PATH)" >PerobjDeps.txt
+ $(Echo) "Checking for cyclic dependencies between LLVM objects."
+ $(Verb) $(PERL) $(PROJ_SRC_DIR)/find-cycles.pl < PerobjDepsIncl.txt > PerobjDepsInclFinal.txt || rm -f $@
+ $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \
+ > temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \
+ >> temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \
+ >> temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_LDFLAGS@/$(subst /,\/,$(SUB_LDFLAGS))/' \
+ >> temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \
+ >> temp.sed
+ $(Verb) $(SED) -f temp.sed < $< > $@
+ $(Verb) $(RM) temp.sed
+ $(Verb) cat PerobjDepsFinal.txt >> $@
+ $(Verb) chmod +x $@
+
+llvm-config-perobjincl: llvm-config.in $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a)
+ $(Echo) "Generating llvm-config-perobjincl"
+ $(Verb) $(PERL) $(GenLibDeps) -perobj -perobjincl -flat $(LibDir) "$(NM_PATH)" >PerobjDepsIncl.txt
+ $(Echo) "Checking for cyclic dependencies between LLVM objects."
+ $(Verb) $(PERL) $(PROJ_SRC_DIR)/find-cycles.pl < PerobjDepsIncl.txt > PerobjDepsInclFinal.txt
+ $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \
+ > temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \
+ >> temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \
+ >> temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_LDFLAGS@/$(subst /,\/,$(SUB_LDFLAGS))/' \
+ >> temp.sed
+ $(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \
+ >> temp.sed
+ $(Verb) $(SED) -f temp.sed < $< > $@
+ $(Verb) $(RM) temp.sed
+ $(Verb) cat PerobjDepsInclFinal.txt >> $@
+ $(Verb) chmod +x $@
+
# Build our final script.
$(ToolDir)/llvm-config: llvm-config.in $(FinalLibDeps)
$(Echo) "Building llvm-config script."
diff --git a/tools/llvm-config/find-cycles.pl b/tools/llvm-config/find-cycles.pl
index 8156abd..5cbf5b4 100755
--- a/tools/llvm-config/find-cycles.pl
+++ b/tools/llvm-config/find-cycles.pl
@@ -62,6 +62,11 @@ foreach my $cycle (@CYCLES) {
print STDERR "find-cycles.pl: Circular dependency between *.a files:\n";
print STDERR "find-cycles.pl: ", join(' ', @archives), "\n";
push @modules, @archives; # WORKAROUND: Duplicate *.a files. Ick.
+ } elsif (@modules > 1) {
+ $cycles_found = $cycles_found + 1;
+ print STDERR "find-cycles.pl: Circular dependency between *.o files:\n";
+ print STDERR "find-cycles.pl: ", join(' ', @modules), "\n";
+ push @modules, @modules; # WORKAROUND: Duplicate *.o files. Ick.
}
# Add to our output. (@modules is already as sorted as we need it to be.)
diff --git a/tools/llvm-dis/Makefile b/tools/llvm-dis/Makefile
index 96f3cbb..22c9ecc 100644
--- a/tools/llvm-dis/Makefile
+++ b/tools/llvm-dis/Makefile
@@ -10,7 +10,6 @@ LEVEL = ../..
TOOLNAME = llvm-dis
LINK_COMPONENTS := bitreader
-CXXFLAGS = -fno-rtti
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-extract/Makefile b/tools/llvm-extract/Makefile
index dee0572..5672aa3 100644
--- a/tools/llvm-extract/Makefile
+++ b/tools/llvm-extract/Makefile
@@ -11,7 +11,6 @@ LEVEL = ../..
TOOLNAME = llvm-extract
LINK_COMPONENTS := ipo bitreader bitwriter asmparser
-CXXFLAGS = -fno-rtti
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp
index 517244f..231634c 100644
--- a/tools/llvm-extract/llvm-extract.cpp
+++ b/tools/llvm-extract/llvm-extract.cpp
@@ -49,15 +49,15 @@ static cl::opt<bool>
Relink("relink",
cl::desc("Turn external linkage for callees of function to delete"));
-// ExtractFunc - The function to extract from the module...
-static cl::opt<std::string>
-ExtractFunc("func", cl::desc("Specify function to extract"), cl::init(""),
- cl::value_desc("function"));
+// ExtractFuncs - The functions to extract from the module...
+static cl::list<std::string>
+ExtractFuncs("func", cl::desc("Specify function to extract"),
+ cl::ZeroOrMore, cl::value_desc("function"));
-// ExtractGlobal - The global to extract from the module...
-static cl::opt<std::string>
-ExtractGlobal("glob", cl::desc("Specify global to extract"), cl::init(""),
- cl::value_desc("global"));
+// ExtractGlobals - The globals to extract from the module...
+static cl::list<std::string>
+ExtractGlobals("glob", cl::desc("Specify global to extract"),
+ cl::ZeroOrMore, cl::value_desc("global"));
static cl::opt<bool>
OutputAssembly("S",
@@ -81,28 +81,34 @@ int main(int argc, char **argv) {
return 1;
}
- // Figure out which function we should extract
- GlobalVariable *G = !ExtractGlobal.empty() ?
- M.get()->getNamedGlobal(ExtractGlobal) : 0;
-
- // Figure out which function we should extract
- if (ExtractFunc.empty() && ExtractGlobal.empty()) ExtractFunc = "main";
- Function *F = M.get()->getFunction(ExtractFunc);
+ std::vector<GlobalValue *> GVs;
+
+ // Figure out which globals we should extract.
+ for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) {
+ GlobalValue *GV = M.get()->getNamedGlobal(ExtractGlobals[i]);
+ if (!GV) {
+ errs() << argv[0] << ": program doesn't contain global named '"
+ << ExtractGlobals[i] << "'!\n";
+ return 1;
+ }
+ GVs.push_back(GV);
+ }
- if (F == 0 && G == 0) {
- errs() << argv[0] << ": program doesn't contain function named '"
- << ExtractFunc << "' or a global named '" << ExtractGlobal << "'!\n";
- return 1;
+ // Figure out which functions we should extract.
+ for (size_t i = 0, e = ExtractFuncs.size(); i != e; ++i) {
+ GlobalValue *GV = M.get()->getFunction(ExtractFuncs[i]);
+ if (!GV) {
+ errs() << argv[0] << ": program doesn't contain function named '"
+ << ExtractFuncs[i] << "'!\n";
+ return 1;
+ }
+ GVs.push_back(GV);
}
// In addition to deleting all other functions, we also want to spiff it
// up a little bit. Do this now.
PassManager Passes;
Passes.add(new TargetData(M.get())); // Use correct TargetData
- // Either isolate the function or delete it from the Module
- std::vector<GlobalValue*> GVs;
- if (F) GVs.push_back(F);
- if (G) GVs.push_back(G);
Passes.add(createGVExtractionPass(GVs, DeleteFn, Relink));
if (!DeleteFn)
diff --git a/tools/llvm-ld/Makefile b/tools/llvm-ld/Makefile
index 1da1966..1ef9bf1 100644
--- a/tools/llvm-ld/Makefile
+++ b/tools/llvm-ld/Makefile
@@ -11,6 +11,5 @@ LEVEL = ../..
TOOLNAME = llvm-ld
LINK_COMPONENTS = ipo scalaropts linker archive bitwriter
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-ld/llvm-ld.cpp b/tools/llvm-ld/llvm-ld.cpp
index e71aefc..118f6b7 100644
--- a/tools/llvm-ld/llvm-ld.cpp
+++ b/tools/llvm-ld/llvm-ld.cpp
@@ -179,8 +179,9 @@ static char ** CopyEnv(char ** const envp) {
// Make a copy of the list. Don't forget the NULL that ends the list.
entries = 0;
while (envp[entries] != NULL) {
- newenv[entries] = new char[strlen (envp[entries]) + 1];
- strcpy (newenv[entries], envp[entries]);
+ size_t len = strlen(envp[entries]) + 1;
+ newenv[entries] = new char[len];
+ memcpy(newenv[entries], envp[entries], len);
++entries;
}
newenv[entries] = NULL;
diff --git a/tools/llvm-link/Makefile b/tools/llvm-link/Makefile
index de592aa..2637018 100644
--- a/tools/llvm-link/Makefile
+++ b/tools/llvm-link/Makefile
@@ -10,7 +10,6 @@ LEVEL = ../..
TOOLNAME = llvm-link
LINK_COMPONENTS = linker bitreader bitwriter asmparser
-CXXFLAGS = -fno-rtti
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-mc/AsmCond.h b/tools/llvm-mc/AsmCond.h
deleted file mode 100644
index 92a115e..0000000
--- a/tools/llvm-mc/AsmCond.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===- AsmCond.h - Assembly file conditional assembly ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ASMCOND_H
-#define ASMCOND_H
-
-namespace llvm {
-
-/// AsmCond - Class to support conditional assembly
-///
-/// The conditional assembly feature (.if, .else, .elseif and .endif) is
-/// implemented with AsmCond that tells us what we are in the middle of
-/// processing. Ignore can be either true or false. When true we are ignoring
-/// the block of code in the middle of a conditional.
-
-class AsmCond {
-public:
- enum ConditionalAssemblyType {
- NoCond, // no conditional is being processed
- IfCond, // inside if conditional
- ElseIfCond, // inside elseif conditional
- ElseCond // inside else conditional
- };
-
- ConditionalAssemblyType TheCond;
- bool CondMet;
- bool Ignore;
-
- AsmCond() : TheCond(NoCond), CondMet(false), Ignore(false) {}
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/tools/llvm-mc/AsmLexer.cpp b/tools/llvm-mc/AsmLexer.cpp
deleted file mode 100644
index 234b8f3..0000000
--- a/tools/llvm-mc/AsmLexer.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-//===- AsmLexer.cpp - Lexer for Assembly Files ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class implements the lexer for assembly files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AsmLexer.h"
-#include "llvm/Support/SMLoc.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Config/config.h" // for strtoull.
-#include "llvm/MC/MCAsmInfo.h"
-#include <cerrno>
-#include <cstdio>
-#include <cstdlib>
-using namespace llvm;
-
-AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) {
- CurBuf = NULL;
- CurPtr = NULL;
- TokStart = 0;
-}
-
-AsmLexer::~AsmLexer() {
-}
-
-void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) {
- CurBuf = buf;
-
- if (ptr)
- CurPtr = ptr;
- else
- CurPtr = CurBuf->getBufferStart();
-
- TokStart = 0;
-}
-
-SMLoc AsmLexer::getLoc() const {
- return SMLoc::getFromPointer(TokStart);
-}
-
-/// ReturnError - Set the error to the specified string at the specified
-/// location. This is defined to always return AsmToken::Error.
-AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
- SetError(SMLoc::getFromPointer(Loc), Msg);
-
- return AsmToken(AsmToken::Error, StringRef(Loc, 0));
-}
-
-int AsmLexer::getNextChar() {
- char CurChar = *CurPtr++;
- switch (CurChar) {
- default:
- return (unsigned char)CurChar;
- case 0:
- // A nul character in the stream is either the end of the current buffer or
- // a random nul in the file. Disambiguate that here.
- if (CurPtr-1 != CurBuf->getBufferEnd())
- return 0; // Just whitespace.
-
- // Otherwise, return end of file.
- --CurPtr; // Another call to lex will return EOF again.
- return EOF;
- }
-}
-
-/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
-AsmToken AsmLexer::LexIdentifier() {
- while (isalnum(*CurPtr) || *CurPtr == '_' || *CurPtr == '$' ||
- *CurPtr == '.' || *CurPtr == '@')
- ++CurPtr;
- return AsmToken(AsmToken::Identifier, StringRef(TokStart, CurPtr - TokStart));
-}
-
-/// LexSlash: Slash: /
-/// C-Style Comment: /* ... */
-AsmToken AsmLexer::LexSlash() {
- switch (*CurPtr) {
- case '*': break; // C style comment.
- case '/': return ++CurPtr, LexLineComment();
- default: return AsmToken(AsmToken::Slash, StringRef(CurPtr, 1));
- }
-
- // C Style comment.
- ++CurPtr; // skip the star.
- while (1) {
- int CurChar = getNextChar();
- switch (CurChar) {
- case EOF:
- return ReturnError(TokStart, "unterminated comment");
- case '*':
- // End of the comment?
- if (CurPtr[0] != '/') break;
-
- ++CurPtr; // End the */.
- return LexToken();
- }
- }
-}
-
-/// LexLineComment: Comment: #[^\n]*
-/// : //[^\n]*
-AsmToken AsmLexer::LexLineComment() {
- // FIXME: This is broken if we happen to a comment at the end of a file, which
- // was .included, and which doesn't end with a newline.
- int CurChar = getNextChar();
- while (CurChar != '\n' && CurChar != '\n' && CurChar != EOF)
- CurChar = getNextChar();
-
- if (CurChar == EOF)
- return AsmToken(AsmToken::Eof, StringRef(CurPtr, 0));
- return AsmToken(AsmToken::EndOfStatement, StringRef(CurPtr, 0));
-}
-
-
-/// LexDigit: First character is [0-9].
-/// Local Label: [0-9][:]
-/// Forward/Backward Label: [0-9][fb]
-/// Binary integer: 0b[01]+
-/// Octal integer: 0[0-7]+
-/// Hex integer: 0x[0-9a-fA-F]+
-/// Decimal integer: [1-9][0-9]*
-/// TODO: FP literal.
-AsmToken AsmLexer::LexDigit() {
- if (*CurPtr == ':')
- return ReturnError(TokStart, "FIXME: local label not implemented");
- if (*CurPtr == 'f' || *CurPtr == 'b')
- return ReturnError(TokStart, "FIXME: directional label not implemented");
-
- // Decimal integer: [1-9][0-9]*
- if (CurPtr[-1] != '0') {
- while (isdigit(*CurPtr))
- ++CurPtr;
- return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
- strtoll(TokStart, 0, 10));
- }
-
- if (*CurPtr == 'b') {
- ++CurPtr;
- const char *NumStart = CurPtr;
- while (CurPtr[0] == '0' || CurPtr[0] == '1')
- ++CurPtr;
-
- // Requires at least one binary digit.
- if (CurPtr == NumStart)
- return ReturnError(CurPtr-2, "Invalid binary number");
- return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
- strtoll(NumStart, 0, 2));
- }
-
- if (*CurPtr == 'x') {
- ++CurPtr;
- const char *NumStart = CurPtr;
- while (isxdigit(CurPtr[0]))
- ++CurPtr;
-
- // Requires at least one hex digit.
- if (CurPtr == NumStart)
- return ReturnError(CurPtr-2, "Invalid hexadecimal number");
-
- errno = 0;
- if (errno == EINVAL)
- return ReturnError(CurPtr-2, "Invalid hexadecimal number");
- if (errno == ERANGE) {
- errno = 0;
- if (errno == EINVAL)
- return ReturnError(CurPtr-2, "Invalid hexadecimal number");
- if (errno == ERANGE)
- return ReturnError(CurPtr-2, "Hexadecimal number out of range");
- }
- return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
- (int64_t) strtoull(NumStart, 0, 16));
- }
-
- // Must be an octal number, it starts with 0.
- while (*CurPtr >= '0' && *CurPtr <= '7')
- ++CurPtr;
- return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
- strtoll(TokStart, 0, 8));
-}
-
-/// LexQuote: String: "..."
-AsmToken AsmLexer::LexQuote() {
- int CurChar = getNextChar();
- // TODO: does gas allow multiline string constants?
- while (CurChar != '"') {
- if (CurChar == '\\') {
- // Allow \", etc.
- CurChar = getNextChar();
- }
-
- if (CurChar == EOF)
- return ReturnError(TokStart, "unterminated string constant");
-
- CurChar = getNextChar();
- }
-
- return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
-}
-
-StringRef AsmLexer::LexUntilEndOfStatement() {
- TokStart = CurPtr;
-
- while (!isAtStartOfComment(*CurPtr) && // Start of line comment.
- *CurPtr != ';' && // End of statement marker.
- *CurPtr != '\n' &&
- *CurPtr != '\r' &&
- (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) {
- ++CurPtr;
- }
- return StringRef(TokStart, CurPtr-TokStart);
-}
-
-bool AsmLexer::isAtStartOfComment(char Char) {
- // FIXME: This won't work for multi-character comment indicators like "//".
- return Char == *MAI.getCommentString();
-}
-
-AsmToken AsmLexer::LexToken() {
- TokStart = CurPtr;
- // This always consumes at least one character.
- int CurChar = getNextChar();
-
- if (isAtStartOfComment(CurChar))
- return LexLineComment();
-
- switch (CurChar) {
- default:
- // Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
- if (isalpha(CurChar) || CurChar == '_' || CurChar == '.')
- return LexIdentifier();
-
- // Unknown character, emit an error.
- return ReturnError(TokStart, "invalid character in input");
- case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
- case 0:
- case ' ':
- case '\t':
- // Ignore whitespace.
- return LexToken();
- case '\n': // FALL THROUGH.
- case '\r': // FALL THROUGH.
- case ';': return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
- case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1));
- case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1));
- case '-': return AsmToken(AsmToken::Minus, StringRef(TokStart, 1));
- case '~': return AsmToken(AsmToken::Tilde, StringRef(TokStart, 1));
- case '(': return AsmToken(AsmToken::LParen, StringRef(TokStart, 1));
- case ')': return AsmToken(AsmToken::RParen, StringRef(TokStart, 1));
- case '[': return AsmToken(AsmToken::LBrac, StringRef(TokStart, 1));
- case ']': return AsmToken(AsmToken::RBrac, StringRef(TokStart, 1));
- case '{': return AsmToken(AsmToken::LCurly, StringRef(TokStart, 1));
- case '}': return AsmToken(AsmToken::RCurly, StringRef(TokStart, 1));
- case '*': return AsmToken(AsmToken::Star, StringRef(TokStart, 1));
- case ',': return AsmToken(AsmToken::Comma, StringRef(TokStart, 1));
- case '$': return AsmToken(AsmToken::Dollar, StringRef(TokStart, 1));
- case '=':
- if (*CurPtr == '=')
- return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
- return AsmToken(AsmToken::Equal, StringRef(TokStart, 1));
- case '|':
- if (*CurPtr == '|')
- return ++CurPtr, AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
- return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1));
- case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1));
- case '&':
- if (*CurPtr == '&')
- return ++CurPtr, AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
- return AsmToken(AsmToken::Amp, StringRef(TokStart, 1));
- case '!':
- if (*CurPtr == '=')
- return ++CurPtr, AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
- return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1));
- case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
- case '/': return LexSlash();
- case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
- case '"': return LexQuote();
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- return LexDigit();
- case '<':
- switch (*CurPtr) {
- case '<': return ++CurPtr, AsmToken(AsmToken::LessLess,
- StringRef(TokStart, 2));
- case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual,
- StringRef(TokStart, 2));
- case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater,
- StringRef(TokStart, 2));
- default: return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
- }
- case '>':
- switch (*CurPtr) {
- case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater,
- StringRef(TokStart, 2));
- case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual,
- StringRef(TokStart, 2));
- default: return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
- }
-
- // TODO: Quoted identifiers (objc methods etc)
- // local labels: [0-9][:]
- // Forward/backward labels: [0-9][fb]
- // Integers, fp constants, character constants.
- }
-}
diff --git a/tools/llvm-mc/AsmLexer.h b/tools/llvm-mc/AsmLexer.h
deleted file mode 100644
index 1d49e4b..0000000
--- a/tools/llvm-mc/AsmLexer.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===- AsmLexer.h - Lexer for Assembly Files --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class declares the lexer for assembly files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ASMLEXER_H
-#define ASMLEXER_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/MC/MCAsmLexer.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/System/DataTypes.h"
-#include <string>
-#include <cassert>
-
-namespace llvm {
-class MemoryBuffer;
-class SMLoc;
-class MCAsmInfo;
-
-/// AsmLexer - Lexer class for assembly files.
-class AsmLexer : public MCAsmLexer {
- const MCAsmInfo &MAI;
-
- const char *CurPtr;
- const MemoryBuffer *CurBuf;
-
- const char *TokStart;
-
- void operator=(const AsmLexer&); // DO NOT IMPLEMENT
- AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT
-
-protected:
- /// LexToken - Read the next token and return its code.
- virtual AsmToken LexToken();
-
-public:
- AsmLexer(const MCAsmInfo &MAI);
- ~AsmLexer();
-
- void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL);
-
- SMLoc getLoc() const;
-
- StringRef LexUntilEndOfStatement();
-
- bool isAtStartOfComment(char Char);
-
- const MCAsmInfo &getMAI() const { return MAI; }
-
-private:
- int getNextChar();
- AsmToken ReturnError(const char *Loc, const std::string &Msg);
-
- AsmToken LexIdentifier();
- AsmToken LexSlash();
- AsmToken LexLineComment();
- AsmToken LexDigit();
- AsmToken LexQuote();
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp
deleted file mode 100644
index 068e506..0000000
--- a/tools/llvm-mc/AsmParser.cpp
+++ /dev/null
@@ -1,1782 +0,0 @@
-//===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class implements the parser for assembly files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AsmParser.h"
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCParsedAsmOperand.h"
-#include "llvm/MC/MCSectionMachO.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/MCValue.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetAsmParser.h"
-using namespace llvm;
-
-
-enum { DEFAULT_ADDRSPACE = 0 };
-
-// Mach-O section uniquing.
-//
-// FIXME: Figure out where this should live, it should be shared by
-// TargetLoweringObjectFile.
-typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
-
-AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
- const MCAsmInfo &_MAI)
- : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM), TargetParser(0),
- CurBuffer(0), SectionUniquingMap(0) {
- Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
-
- // Debugging directives.
- AddDirectiveHandler(".file", &AsmParser::ParseDirectiveFile);
- AddDirectiveHandler(".line", &AsmParser::ParseDirectiveLine);
- AddDirectiveHandler(".loc", &AsmParser::ParseDirectiveLoc);
-}
-
-
-
-AsmParser::~AsmParser() {
- // If we have the MachO uniquing map, free it.
- delete (MachOUniqueMapTy*)SectionUniquingMap;
-}
-
-const MCSection *AsmParser::getMachOSection(const StringRef &Segment,
- const StringRef &Section,
- unsigned TypeAndAttributes,
- unsigned Reserved2,
- SectionKind Kind) const {
- // We unique sections by their segment/section pair. The returned section
- // may not have the same flags as the requested section, if so this should be
- // diagnosed by the client as an error.
-
- // Create the map if it doesn't already exist.
- if (SectionUniquingMap == 0)
- SectionUniquingMap = new MachOUniqueMapTy();
- MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)SectionUniquingMap;
-
- // Form the name to look up.
- SmallString<64> Name;
- Name += Segment;
- Name.push_back(',');
- Name += Section;
-
- // Do the lookup, if we have a hit, return it.
- const MCSectionMachO *&Entry = Map[Name.str()];
-
- // FIXME: This should validate the type and attributes.
- if (Entry) return Entry;
-
- // Otherwise, return a new section.
- return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes,
- Reserved2, Kind, Ctx);
-}
-
-void AsmParser::Warning(SMLoc L, const Twine &Msg) {
- PrintMessage(L, Msg.str(), "warning");
-}
-
-bool AsmParser::Error(SMLoc L, const Twine &Msg) {
- PrintMessage(L, Msg.str(), "error");
- return true;
-}
-
-bool AsmParser::TokError(const char *Msg) {
- PrintMessage(Lexer.getLoc(), Msg, "error");
- return true;
-}
-
-void AsmParser::PrintMessage(SMLoc Loc, const std::string &Msg,
- const char *Type) const {
- SrcMgr.PrintMessage(Loc, Msg, Type);
-}
-
-bool AsmParser::EnterIncludeFile(const std::string &Filename) {
- int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc());
- if (NewBuf == -1)
- return true;
-
- CurBuffer = NewBuf;
-
- Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
-
- return false;
-}
-
-const AsmToken &AsmParser::Lex() {
- const AsmToken *tok = &Lexer.Lex();
-
- if (tok->is(AsmToken::Eof)) {
- // If this is the end of an included file, pop the parent file off the
- // include stack.
- SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
- if (ParentIncludeLoc != SMLoc()) {
- CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
- Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer),
- ParentIncludeLoc.getPointer());
- tok = &Lexer.Lex();
- }
- }
-
- if (tok->is(AsmToken::Error))
- PrintMessage(Lexer.getErrLoc(), Lexer.getErr(), "error");
-
- return *tok;
-}
-
-bool AsmParser::Run() {
- // Create the initial section.
- //
- // FIXME: Support -n.
- // FIXME: Target hook & command line option for initial section.
- Out.SwitchSection(getMachOSection("__TEXT", "__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 0, SectionKind()));
-
-
- // Prime the lexer.
- Lex();
-
- bool HadError = false;
-
- AsmCond StartingCondState = TheCondState;
-
- // While we have input, parse each statement.
- while (Lexer.isNot(AsmToken::Eof)) {
- // Handle conditional assembly here before calling ParseStatement()
- if (Lexer.getKind() == AsmToken::Identifier) {
- // If we have an identifier, handle it as the key symbol.
- AsmToken ID = getTok();
- SMLoc IDLoc = ID.getLoc();
- StringRef IDVal = ID.getString();
-
- if (IDVal == ".if" ||
- IDVal == ".elseif" ||
- IDVal == ".else" ||
- IDVal == ".endif") {
- if (!ParseConditionalAssemblyDirectives(IDVal, IDLoc))
- continue;
- HadError = true;
- EatToEndOfStatement();
- continue;
- }
- }
- if (TheCondState.Ignore) {
- EatToEndOfStatement();
- continue;
- }
-
- if (!ParseStatement()) continue;
-
- // We had an error, remember it and recover by skipping to the next line.
- HadError = true;
- EatToEndOfStatement();
- }
-
- if (TheCondState.TheCond != StartingCondState.TheCond ||
- TheCondState.Ignore != StartingCondState.Ignore)
- return TokError("unmatched .ifs or .elses");
-
- if (!HadError)
- Out.Finish();
-
- return HadError;
-}
-
-/// ParseConditionalAssemblyDirectives - parse the conditional assembly
-/// directives
-bool AsmParser::ParseConditionalAssemblyDirectives(StringRef Directive,
- SMLoc DirectiveLoc) {
- if (Directive == ".if")
- return ParseDirectiveIf(DirectiveLoc);
- if (Directive == ".elseif")
- return ParseDirectiveElseIf(DirectiveLoc);
- if (Directive == ".else")
- return ParseDirectiveElse(DirectiveLoc);
- if (Directive == ".endif")
- return ParseDirectiveEndIf(DirectiveLoc);
- return true;
-}
-
-/// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
-void AsmParser::EatToEndOfStatement() {
- while (Lexer.isNot(AsmToken::EndOfStatement) &&
- Lexer.isNot(AsmToken::Eof))
- Lex();
-
- // Eat EOL.
- if (Lexer.is(AsmToken::EndOfStatement))
- Lex();
-}
-
-
-/// ParseParenExpr - Parse a paren expression and return it.
-/// NOTE: This assumes the leading '(' has already been consumed.
-///
-/// parenexpr ::= expr)
-///
-bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- if (ParseExpression(Res)) return true;
- if (Lexer.isNot(AsmToken::RParen))
- return TokError("expected ')' in parentheses expression");
- EndLoc = Lexer.getLoc();
- Lex();
- return false;
-}
-
-MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
- if (MCSymbol *S = Ctx.LookupSymbol(Name))
- return S;
-
- // If the label starts with L it is an assembler temporary label.
- if (Name.startswith("L"))
- return Ctx.CreateTemporarySymbol(Name);
-
- return Ctx.CreateSymbol(Name);
-}
-
-/// ParsePrimaryExpr - Parse a primary expression and return it.
-/// primaryexpr ::= (parenexpr
-/// primaryexpr ::= symbol
-/// primaryexpr ::= number
-/// primaryexpr ::= ~,+,- primaryexpr
-bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- switch (Lexer.getKind()) {
- default:
- return TokError("unknown token in expression");
- case AsmToken::Exclaim:
- Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res, EndLoc))
- return true;
- Res = MCUnaryExpr::CreateLNot(Res, getContext());
- return false;
- case AsmToken::String:
- case AsmToken::Identifier: {
- // This is a symbol reference.
- MCSymbol *Sym = CreateSymbol(getTok().getIdentifier());
- EndLoc = Lexer.getLoc();
- Lex(); // Eat identifier.
-
- // If this is an absolute variable reference, substitute it now to preserve
- // semantics in the face of reassignment.
- if (Sym->getValue() && isa<MCConstantExpr>(Sym->getValue())) {
- Res = Sym->getValue();
- return false;
- }
-
- // Otherwise create a symbol ref.
- Res = MCSymbolRefExpr::Create(Sym, getContext());
- return false;
- }
- case AsmToken::Integer:
- Res = MCConstantExpr::Create(getTok().getIntVal(), getContext());
- EndLoc = Lexer.getLoc();
- Lex(); // Eat token.
- return false;
- case AsmToken::LParen:
- Lex(); // Eat the '('.
- return ParseParenExpr(Res, EndLoc);
- case AsmToken::Minus:
- Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res, EndLoc))
- return true;
- Res = MCUnaryExpr::CreateMinus(Res, getContext());
- return false;
- case AsmToken::Plus:
- Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res, EndLoc))
- return true;
- Res = MCUnaryExpr::CreatePlus(Res, getContext());
- return false;
- case AsmToken::Tilde:
- Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res, EndLoc))
- return true;
- Res = MCUnaryExpr::CreateNot(Res, getContext());
- return false;
- }
-}
-
-bool AsmParser::ParseExpression(const MCExpr *&Res) {
- SMLoc EndLoc;
- return ParseExpression(Res, EndLoc);
-}
-
-/// ParseExpression - Parse an expression and return it.
-///
-/// expr ::= expr +,- expr -> lowest.
-/// expr ::= expr |,^,&,! expr -> middle.
-/// expr ::= expr *,/,%,<<,>> expr -> highest.
-/// expr ::= primaryexpr
-///
-bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
- Res = 0;
- return ParsePrimaryExpr(Res, EndLoc) ||
- ParseBinOpRHS(1, Res, EndLoc);
-}
-
-bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
- if (ParseParenExpr(Res, EndLoc))
- return true;
-
- return false;
-}
-
-bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
- const MCExpr *Expr;
-
- SMLoc StartLoc = Lexer.getLoc();
- if (ParseExpression(Expr))
- return true;
-
- if (!Expr->EvaluateAsAbsolute(Res))
- return Error(StartLoc, "expected absolute expression");
-
- return false;
-}
-
-static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
- MCBinaryExpr::Opcode &Kind) {
- switch (K) {
- default:
- return 0; // not a binop.
-
- // Lowest Precedence: &&, ||
- case AsmToken::AmpAmp:
- Kind = MCBinaryExpr::LAnd;
- return 1;
- case AsmToken::PipePipe:
- Kind = MCBinaryExpr::LOr;
- return 1;
-
- // Low Precedence: +, -, ==, !=, <>, <, <=, >, >=
- case AsmToken::Plus:
- Kind = MCBinaryExpr::Add;
- return 2;
- case AsmToken::Minus:
- Kind = MCBinaryExpr::Sub;
- return 2;
- case AsmToken::EqualEqual:
- Kind = MCBinaryExpr::EQ;
- return 2;
- case AsmToken::ExclaimEqual:
- case AsmToken::LessGreater:
- Kind = MCBinaryExpr::NE;
- return 2;
- case AsmToken::Less:
- Kind = MCBinaryExpr::LT;
- return 2;
- case AsmToken::LessEqual:
- Kind = MCBinaryExpr::LTE;
- return 2;
- case AsmToken::Greater:
- Kind = MCBinaryExpr::GT;
- return 2;
- case AsmToken::GreaterEqual:
- Kind = MCBinaryExpr::GTE;
- return 2;
-
- // Intermediate Precedence: |, &, ^
- //
- // FIXME: gas seems to support '!' as an infix operator?
- case AsmToken::Pipe:
- Kind = MCBinaryExpr::Or;
- return 3;
- case AsmToken::Caret:
- Kind = MCBinaryExpr::Xor;
- return 3;
- case AsmToken::Amp:
- Kind = MCBinaryExpr::And;
- return 3;
-
- // Highest Precedence: *, /, %, <<, >>
- case AsmToken::Star:
- Kind = MCBinaryExpr::Mul;
- return 4;
- case AsmToken::Slash:
- Kind = MCBinaryExpr::Div;
- return 4;
- case AsmToken::Percent:
- Kind = MCBinaryExpr::Mod;
- return 4;
- case AsmToken::LessLess:
- Kind = MCBinaryExpr::Shl;
- return 4;
- case AsmToken::GreaterGreater:
- Kind = MCBinaryExpr::Shr;
- return 4;
- }
-}
-
-
-/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
-/// Res contains the LHS of the expression on input.
-bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
- SMLoc &EndLoc) {
- while (1) {
- MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
- unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
-
- // If the next token is lower precedence than we are allowed to eat, return
- // successfully with what we ate already.
- if (TokPrec < Precedence)
- return false;
-
- Lex();
-
- // Eat the next primary expression.
- const MCExpr *RHS;
- if (ParsePrimaryExpr(RHS, EndLoc)) return true;
-
- // If BinOp binds less tightly with RHS than the operator after RHS, let
- // the pending operator take RHS as its LHS.
- MCBinaryExpr::Opcode Dummy;
- unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
- if (TokPrec < NextTokPrec) {
- if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
- }
-
- // Merge LHS and RHS according to operator.
- Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
- }
-}
-
-
-
-
-/// ParseStatement:
-/// ::= EndOfStatement
-/// ::= Label* Directive ...Operands... EndOfStatement
-/// ::= Label* Identifier OperandList* EndOfStatement
-bool AsmParser::ParseStatement() {
- if (Lexer.is(AsmToken::EndOfStatement)) {
- Lex();
- return false;
- }
-
- // Statements always start with an identifier.
- AsmToken ID = getTok();
- SMLoc IDLoc = ID.getLoc();
- StringRef IDVal;
- if (ParseIdentifier(IDVal))
- return TokError("unexpected token at start of statement");
-
- // FIXME: Recurse on local labels?
-
- // See what kind of statement we have.
- switch (Lexer.getKind()) {
- case AsmToken::Colon: {
- // identifier ':' -> Label.
- Lex();
-
- // Diagnose attempt to use a variable as a label.
- //
- // FIXME: Diagnostics. Note the location of the definition as a label.
- // FIXME: This doesn't diagnose assignment to a symbol which has been
- // implicitly marked as external.
- MCSymbol *Sym = CreateSymbol(IDVal);
- if (!Sym->isUndefined())
- return Error(IDLoc, "invalid symbol redefinition");
-
- // Emit the label.
- Out.EmitLabel(Sym);
-
- return ParseStatement();
- }
-
- case AsmToken::Equal:
- // identifier '=' ... -> assignment statement
- Lex();
-
- return ParseAssignment(IDVal);
-
- default: // Normal instruction or directive.
- break;
- }
-
- // Otherwise, we have a normal instruction or directive.
- if (IDVal[0] == '.') {
- // FIXME: This should be driven based on a hash lookup and callback.
- if (IDVal == ".section")
- return ParseDirectiveDarwinSection();
- if (IDVal == ".text")
- // FIXME: This changes behavior based on the -static flag to the
- // assembler.
- return ParseDirectiveSectionSwitch("__TEXT", "__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
- if (IDVal == ".const")
- return ParseDirectiveSectionSwitch("__TEXT", "__const");
- if (IDVal == ".static_const")
- return ParseDirectiveSectionSwitch("__TEXT", "__static_const");
- if (IDVal == ".cstring")
- return ParseDirectiveSectionSwitch("__TEXT","__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
- if (IDVal == ".literal4")
- return ParseDirectiveSectionSwitch("__TEXT", "__literal4",
- MCSectionMachO::S_4BYTE_LITERALS,
- 4);
- if (IDVal == ".literal8")
- return ParseDirectiveSectionSwitch("__TEXT", "__literal8",
- MCSectionMachO::S_8BYTE_LITERALS,
- 8);
- if (IDVal == ".literal16")
- return ParseDirectiveSectionSwitch("__TEXT","__literal16",
- MCSectionMachO::S_16BYTE_LITERALS,
- 16);
- if (IDVal == ".constructor")
- return ParseDirectiveSectionSwitch("__TEXT","__constructor");
- if (IDVal == ".destructor")
- return ParseDirectiveSectionSwitch("__TEXT","__destructor");
- if (IDVal == ".fvmlib_init0")
- return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0");
- if (IDVal == ".fvmlib_init1")
- return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1");
-
- // FIXME: The assembler manual claims that this has the self modify code
- // flag, at least on x86-32, but that does not appear to be correct.
- if (IDVal == ".symbol_stub")
- return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub",
- MCSectionMachO::S_SYMBOL_STUBS |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- // FIXME: Different on PPC and ARM.
- 0, 16);
- // FIXME: PowerPC only?
- if (IDVal == ".picsymbol_stub")
- return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub",
- MCSectionMachO::S_SYMBOL_STUBS |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 0, 26);
- if (IDVal == ".data")
- return ParseDirectiveSectionSwitch("__DATA", "__data");
- if (IDVal == ".static_data")
- return ParseDirectiveSectionSwitch("__DATA", "__static_data");
-
- // FIXME: The section names of these two are misspelled in the assembler
- // manual.
- if (IDVal == ".non_lazy_symbol_pointer")
- return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr",
- MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
- 4);
- if (IDVal == ".lazy_symbol_pointer")
- return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr",
- MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
- 4);
-
- if (IDVal == ".dyld")
- return ParseDirectiveSectionSwitch("__DATA", "__dyld");
- if (IDVal == ".mod_init_func")
- return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func",
- MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
- 4);
- if (IDVal == ".mod_term_func")
- return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func",
- MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
- 4);
- if (IDVal == ".const_data")
- return ParseDirectiveSectionSwitch("__DATA", "__const");
-
-
- if (IDVal == ".objc_class")
- return ParseDirectiveSectionSwitch("__OBJC", "__class",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_meta_class")
- return ParseDirectiveSectionSwitch("__OBJC", "__meta_class",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_cat_cls_meth")
- return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_cat_inst_meth")
- return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_protocol")
- return ParseDirectiveSectionSwitch("__OBJC", "__protocol",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_string_object")
- return ParseDirectiveSectionSwitch("__OBJC", "__string_object",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_cls_meth")
- return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_inst_meth")
- return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_cls_refs")
- return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
- MCSectionMachO::S_LITERAL_POINTERS,
- 4);
- if (IDVal == ".objc_message_refs")
- return ParseDirectiveSectionSwitch("__OBJC", "__message_refs",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
- MCSectionMachO::S_LITERAL_POINTERS,
- 4);
- if (IDVal == ".objc_symbols")
- return ParseDirectiveSectionSwitch("__OBJC", "__symbols",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_category")
- return ParseDirectiveSectionSwitch("__OBJC", "__category",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_class_vars")
- return ParseDirectiveSectionSwitch("__OBJC", "__class_vars",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_instance_vars")
- return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_module_info")
- return ParseDirectiveSectionSwitch("__OBJC", "__module_info",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_class_names")
- return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
- if (IDVal == ".objc_meth_var_types")
- return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
- if (IDVal == ".objc_meth_var_names")
- return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
- if (IDVal == ".objc_selector_strs")
- return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs",
- MCSectionMachO::S_CSTRING_LITERALS);
-
- // Assembler features
- if (IDVal == ".set")
- return ParseDirectiveSet();
-
- // Data directives
-
- if (IDVal == ".ascii")
- return ParseDirectiveAscii(false);
- if (IDVal == ".asciz")
- return ParseDirectiveAscii(true);
-
- if (IDVal == ".byte")
- return ParseDirectiveValue(1);
- if (IDVal == ".short")
- return ParseDirectiveValue(2);
- if (IDVal == ".long")
- return ParseDirectiveValue(4);
- if (IDVal == ".quad")
- return ParseDirectiveValue(8);
-
- // FIXME: Target hooks for IsPow2.
- if (IDVal == ".align")
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
- if (IDVal == ".align32")
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
- if (IDVal == ".balign")
- return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
- if (IDVal == ".balignw")
- return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
- if (IDVal == ".balignl")
- return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
- if (IDVal == ".p2align")
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
- if (IDVal == ".p2alignw")
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
- if (IDVal == ".p2alignl")
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
-
- if (IDVal == ".org")
- return ParseDirectiveOrg();
-
- if (IDVal == ".fill")
- return ParseDirectiveFill();
- if (IDVal == ".space")
- return ParseDirectiveSpace();
-
- // Symbol attribute directives
-
- if (IDVal == ".globl" || IDVal == ".global")
- return ParseDirectiveSymbolAttribute(MCStreamer::Global);
- if (IDVal == ".hidden")
- return ParseDirectiveSymbolAttribute(MCStreamer::Hidden);
- if (IDVal == ".indirect_symbol")
- return ParseDirectiveSymbolAttribute(MCStreamer::IndirectSymbol);
- if (IDVal == ".internal")
- return ParseDirectiveSymbolAttribute(MCStreamer::Internal);
- if (IDVal == ".lazy_reference")
- return ParseDirectiveSymbolAttribute(MCStreamer::LazyReference);
- if (IDVal == ".no_dead_strip")
- return ParseDirectiveSymbolAttribute(MCStreamer::NoDeadStrip);
- if (IDVal == ".private_extern")
- return ParseDirectiveSymbolAttribute(MCStreamer::PrivateExtern);
- if (IDVal == ".protected")
- return ParseDirectiveSymbolAttribute(MCStreamer::Protected);
- if (IDVal == ".reference")
- return ParseDirectiveSymbolAttribute(MCStreamer::Reference);
- if (IDVal == ".weak")
- return ParseDirectiveSymbolAttribute(MCStreamer::Weak);
- if (IDVal == ".weak_definition")
- return ParseDirectiveSymbolAttribute(MCStreamer::WeakDefinition);
- if (IDVal == ".weak_reference")
- return ParseDirectiveSymbolAttribute(MCStreamer::WeakReference);
-
- if (IDVal == ".comm")
- return ParseDirectiveComm(/*IsLocal=*/false);
- if (IDVal == ".lcomm")
- return ParseDirectiveComm(/*IsLocal=*/true);
- if (IDVal == ".zerofill")
- return ParseDirectiveDarwinZerofill();
- if (IDVal == ".desc")
- return ParseDirectiveDarwinSymbolDesc();
- if (IDVal == ".lsym")
- return ParseDirectiveDarwinLsym();
-
- if (IDVal == ".subsections_via_symbols")
- return ParseDirectiveDarwinSubsectionsViaSymbols();
- if (IDVal == ".abort")
- return ParseDirectiveAbort();
- if (IDVal == ".include")
- return ParseDirectiveInclude();
- if (IDVal == ".dump")
- return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true);
- if (IDVal == ".load")
- return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false);
-
- // Look up the handler in the handler table,
- bool(AsmParser::*Handler)(StringRef, SMLoc) = DirectiveMap[IDVal];
- if (Handler)
- return (this->*Handler)(IDVal, IDLoc);
-
- // Target hook for parsing target specific directives.
- if (!getTargetParser().ParseDirective(ID))
- return false;
-
- Warning(IDLoc, "ignoring directive for now");
- EatToEndOfStatement();
- return false;
- }
-
-
- SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
- if (getTargetParser().ParseInstruction(IDVal, IDLoc, ParsedOperands))
- // FIXME: Leaking ParsedOperands on failure.
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- // FIXME: Leaking ParsedOperands on failure.
- return TokError("unexpected token in argument list");
-
- // Eat the end of statement marker.
- Lex();
-
-
- MCInst Inst;
-
- bool MatchFail = getTargetParser().MatchInstruction(ParsedOperands, Inst);
-
- // Free any parsed operands.
- for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
- delete ParsedOperands[i];
-
- if (MatchFail) {
- // FIXME: We should give nicer diagnostics about the exact failure.
- Error(IDLoc, "unrecognized instruction");
- return true;
- }
-
- // Instruction is good, process it.
- Out.EmitInstruction(Inst);
-
- // Skip to end of line for now.
- return false;
-}
-
-bool AsmParser::ParseAssignment(const StringRef &Name) {
- // FIXME: Use better location, we should use proper tokens.
- SMLoc EqualLoc = Lexer.getLoc();
-
- const MCExpr *Value;
- SMLoc StartLoc = Lexer.getLoc();
- if (ParseExpression(Value))
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in assignment");
-
- // Eat the end of statement marker.
- Lex();
-
- // Validate that the LHS is allowed to be a variable (either it has not been
- // used as a symbol, or it is an absolute symbol).
- MCSymbol *Sym = getContext().LookupSymbol(Name);
- if (Sym) {
- // Diagnose assignment to a label.
- //
- // FIXME: Diagnostics. Note the location of the definition as a label.
- // FIXME: Diagnose assignment to protected identifier (e.g., register name).
- if (!Sym->isUndefined() && !Sym->isAbsolute())
- return Error(EqualLoc, "redefinition of '" + Name + "'");
- else if (!Sym->isVariable())
- return Error(EqualLoc, "invalid assignment to '" + Name + "'");
- else if (!isa<MCConstantExpr>(Sym->getValue()))
- return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
- Name + "'");
- } else
- Sym = CreateSymbol(Name);
-
- // FIXME: Handle '.'.
-
- // Do the assignment.
- Out.EmitAssignment(Sym, Value);
-
- return false;
-}
-
-/// ParseIdentifier:
-/// ::= identifier
-/// ::= string
-bool AsmParser::ParseIdentifier(StringRef &Res) {
- if (Lexer.isNot(AsmToken::Identifier) &&
- Lexer.isNot(AsmToken::String))
- return true;
-
- Res = getTok().getIdentifier();
-
- Lex(); // Consume the identifier token.
-
- return false;
-}
-
-/// ParseDirectiveSet:
-/// ::= .set identifier ',' expression
-bool AsmParser::ParseDirectiveSet() {
- StringRef Name;
-
- if (ParseIdentifier(Name))
- return TokError("expected identifier after '.set' directive");
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in '.set'");
- Lex();
-
- return ParseAssignment(Name);
-}
-
-/// ParseDirectiveSection:
-/// ::= .section identifier (',' identifier)*
-/// FIXME: This should actually parse out the segment, section, attributes and
-/// sizeof_stub fields.
-bool AsmParser::ParseDirectiveDarwinSection() {
- SMLoc Loc = Lexer.getLoc();
-
- StringRef SectionName;
- if (ParseIdentifier(SectionName))
- return Error(Loc, "expected identifier after '.section' directive");
-
- // Verify there is a following comma.
- if (!Lexer.is(AsmToken::Comma))
- return TokError("unexpected token in '.section' directive");
-
- std::string SectionSpec = SectionName;
- SectionSpec += ",";
-
- // Add all the tokens until the end of the line, ParseSectionSpecifier will
- // handle this.
- StringRef EOL = Lexer.LexUntilEndOfStatement();
- SectionSpec.append(EOL.begin(), EOL.end());
-
- Lex();
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.section' directive");
- Lex();
-
-
- StringRef Segment, Section;
- unsigned TAA, StubSize;
- std::string ErrorStr =
- MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
- TAA, StubSize);
-
- if (!ErrorStr.empty())
- return Error(Loc, ErrorStr.c_str());
-
- // FIXME: Arch specific.
- Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
- SectionKind()));
- return false;
-}
-
-/// ParseDirectiveSectionSwitch -
-bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
- const char *Section,
- unsigned TAA, unsigned Align,
- unsigned StubSize) {
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in section switching directive");
- Lex();
-
- // FIXME: Arch specific.
- Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
- SectionKind()));
-
- // Set the implicit alignment, if any.
- //
- // FIXME: This isn't really what 'as' does; I think it just uses the implicit
- // alignment on the section (e.g., if one manually inserts bytes into the
- // section, then just issueing the section switch directive will not realign
- // the section. However, this is arguably more reasonable behavior, and there
- // is no good reason for someone to intentionally emit incorrectly sized
- // values into the implicitly aligned sections.
- if (Align)
- Out.EmitValueToAlignment(Align, 0, 1, 0);
-
- return false;
-}
-
-bool AsmParser::ParseEscapedString(std::string &Data) {
- assert(Lexer.is(AsmToken::String) && "Unexpected current token!");
-
- Data = "";
- StringRef Str = getTok().getStringContents();
- for (unsigned i = 0, e = Str.size(); i != e; ++i) {
- if (Str[i] != '\\') {
- Data += Str[i];
- continue;
- }
-
- // Recognize escaped characters. Note that this escape semantics currently
- // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
- ++i;
- if (i == e)
- return TokError("unexpected backslash at end of string");
-
- // Recognize octal sequences.
- if ((unsigned) (Str[i] - '0') <= 7) {
- // Consume up to three octal characters.
- unsigned Value = Str[i] - '0';
-
- if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
- ++i;
- Value = Value * 8 + (Str[i] - '0');
-
- if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
- ++i;
- Value = Value * 8 + (Str[i] - '0');
- }
- }
-
- if (Value > 255)
- return TokError("invalid octal escape sequence (out of range)");
-
- Data += (unsigned char) Value;
- continue;
- }
-
- // Otherwise recognize individual escapes.
- switch (Str[i]) {
- default:
- // Just reject invalid escape sequences for now.
- return TokError("invalid escape sequence (unrecognized character)");
-
- case 'b': Data += '\b'; break;
- case 'f': Data += '\f'; break;
- case 'n': Data += '\n'; break;
- case 'r': Data += '\r'; break;
- case 't': Data += '\t'; break;
- case '"': Data += '"'; break;
- case '\\': Data += '\\'; break;
- }
- }
-
- return false;
-}
-
-/// ParseDirectiveAscii:
-/// ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ]
-bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- for (;;) {
- if (Lexer.isNot(AsmToken::String))
- return TokError("expected string in '.ascii' or '.asciz' directive");
-
- std::string Data;
- if (ParseEscapedString(Data))
- return true;
-
- Out.EmitBytes(Data, DEFAULT_ADDRSPACE);
- if (ZeroTerminated)
- Out.EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
-
- Lex();
-
- if (Lexer.is(AsmToken::EndOfStatement))
- break;
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in '.ascii' or '.asciz' directive");
- Lex();
- }
- }
-
- Lex();
- return false;
-}
-
-/// ParseDirectiveValue
-/// ::= (.byte | .short | ... ) [ expression (, expression)* ]
-bool AsmParser::ParseDirectiveValue(unsigned Size) {
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- for (;;) {
- const MCExpr *Value;
- SMLoc ATTRIBUTE_UNUSED StartLoc = Lexer.getLoc();
- if (ParseExpression(Value))
- return true;
-
- Out.EmitValue(Value, Size, DEFAULT_ADDRSPACE);
-
- if (Lexer.is(AsmToken::EndOfStatement))
- break;
-
- // FIXME: Improve diagnostic.
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
- }
- }
-
- Lex();
- return false;
-}
-
-/// ParseDirectiveSpace
-/// ::= .space expression [ , expression ]
-bool AsmParser::ParseDirectiveSpace() {
- int64_t NumBytes;
- if (ParseAbsoluteExpression(NumBytes))
- return true;
-
- int64_t FillExpr = 0;
- bool HasFillExpr = false;
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in '.space' directive");
- Lex();
-
- if (ParseAbsoluteExpression(FillExpr))
- return true;
-
- HasFillExpr = true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.space' directive");
- }
-
- Lex();
-
- if (NumBytes <= 0)
- return TokError("invalid number of bytes in '.space' directive");
-
- // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
- Out.EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
-
- return false;
-}
-
-/// ParseDirectiveFill
-/// ::= .fill expression , expression , expression
-bool AsmParser::ParseDirectiveFill() {
- int64_t NumValues;
- if (ParseAbsoluteExpression(NumValues))
- return true;
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in '.fill' directive");
- Lex();
-
- int64_t FillSize;
- if (ParseAbsoluteExpression(FillSize))
- return true;
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in '.fill' directive");
- Lex();
-
- int64_t FillExpr;
- if (ParseAbsoluteExpression(FillExpr))
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.fill' directive");
-
- Lex();
-
- if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
- return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
-
- for (uint64_t i = 0, e = NumValues; i != e; ++i)
- Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize,
- DEFAULT_ADDRSPACE);
-
- return false;
-}
-
-/// ParseDirectiveOrg
-/// ::= .org expression [ , expression ]
-bool AsmParser::ParseDirectiveOrg() {
- const MCExpr *Offset;
- SMLoc StartLoc = Lexer.getLoc();
- if (ParseExpression(Offset))
- return true;
-
- // Parse optional fill expression.
- int64_t FillExpr = 0;
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in '.org' directive");
- Lex();
-
- if (ParseAbsoluteExpression(FillExpr))
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.org' directive");
- }
-
- Lex();
-
- // FIXME: Only limited forms of relocatable expressions are accepted here, it
- // has to be relative to the current section.
- Out.EmitValueToOffset(Offset, FillExpr);
-
- return false;
-}
-
-/// ParseDirectiveAlign
-/// ::= {.align, ...} expression [ , expression [ , expression ]]
-bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
- SMLoc AlignmentLoc = Lexer.getLoc();
- int64_t Alignment;
- if (ParseAbsoluteExpression(Alignment))
- return true;
-
- SMLoc MaxBytesLoc;
- bool HasFillExpr = false;
- int64_t FillExpr = 0;
- int64_t MaxBytesToFill = 0;
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- // The fill expression can be omitted while specifying a maximum number of
- // alignment bytes, e.g:
- // .align 3,,4
- if (Lexer.isNot(AsmToken::Comma)) {
- HasFillExpr = true;
- if (ParseAbsoluteExpression(FillExpr))
- return true;
- }
-
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- MaxBytesLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(MaxBytesToFill))
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in directive");
- }
- }
-
- Lex();
-
- if (!HasFillExpr) {
- // FIXME: Sometimes fill with nop.
- FillExpr = 0;
- }
-
- // Compute alignment in bytes.
- if (IsPow2) {
- // FIXME: Diagnose overflow.
- if (Alignment >= 32) {
- Error(AlignmentLoc, "invalid alignment value");
- Alignment = 31;
- }
-
- Alignment = 1ULL << Alignment;
- }
-
- // Diagnose non-sensical max bytes to align.
- if (MaxBytesLoc.isValid()) {
- if (MaxBytesToFill < 1) {
- Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
- "many bytes, ignoring maximum bytes expression");
- MaxBytesToFill = 0;
- }
-
- if (MaxBytesToFill >= Alignment) {
- Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
- "has no effect");
- MaxBytesToFill = 0;
- }
- }
-
- // FIXME: Target specific behavior about how the "extra" bytes are filled.
- Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
-
- return false;
-}
-
-/// ParseDirectiveSymbolAttribute
-/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
-bool AsmParser::ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr) {
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- for (;;) {
- StringRef Name;
-
- if (ParseIdentifier(Name))
- return TokError("expected identifier in directive");
-
- MCSymbol *Sym = CreateSymbol(Name);
-
- Out.EmitSymbolAttribute(Sym, Attr);
-
- if (Lexer.is(AsmToken::EndOfStatement))
- break;
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
- }
- }
-
- Lex();
- return false;
-}
-
-/// ParseDirectiveDarwinSymbolDesc
-/// ::= .desc identifier , expression
-bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
- StringRef Name;
- if (ParseIdentifier(Name))
- return TokError("expected identifier in directive");
-
- // Handle the identifier as the key symbol.
- MCSymbol *Sym = CreateSymbol(Name);
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in '.desc' directive");
- Lex();
-
- SMLoc DescLoc = Lexer.getLoc();
- int64_t DescValue;
- if (ParseAbsoluteExpression(DescValue))
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.desc' directive");
-
- Lex();
-
- // Set the n_desc field of this Symbol to this DescValue
- Out.EmitSymbolDesc(Sym, DescValue);
-
- return false;
-}
-
-/// ParseDirectiveComm
-/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
-bool AsmParser::ParseDirectiveComm(bool IsLocal) {
- SMLoc IDLoc = Lexer.getLoc();
- StringRef Name;
- if (ParseIdentifier(Name))
- return TokError("expected identifier in directive");
-
- // Handle the identifier as the key symbol.
- MCSymbol *Sym = CreateSymbol(Name);
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Size;
- SMLoc SizeLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(Size))
- return true;
-
- int64_t Pow2Alignment = 0;
- SMLoc Pow2AlignmentLoc;
- if (Lexer.is(AsmToken::Comma)) {
- Lex();
- Pow2AlignmentLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(Pow2Alignment))
- return true;
-
- // If this target takes alignments in bytes (not log) validate and convert.
- if (Lexer.getMAI().getAlignmentIsInBytes()) {
- if (!isPowerOf2_64(Pow2Alignment))
- return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
- Pow2Alignment = Log2_64(Pow2Alignment);
- }
- }
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.comm' or '.lcomm' directive");
-
- Lex();
-
- // NOTE: a size of zero for a .comm should create a undefined symbol
- // but a size of .lcomm creates a bss symbol of size zero.
- if (Size < 0)
- return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
- "be less than zero");
-
- // NOTE: The alignment in the directive is a power of 2 value, the assember
- // may internally end up wanting an alignment in bytes.
- // FIXME: Diagnose overflow.
- if (Pow2Alignment < 0)
- return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
- "alignment, can't be less than zero");
-
- if (!Sym->isUndefined())
- return Error(IDLoc, "invalid symbol redefinition");
-
- // '.lcomm' is equivalent to '.zerofill'.
- // Create the Symbol as a common or local common with Size and Pow2Alignment
- if (IsLocal) {
- Out.EmitZerofill(getMachOSection("__DATA", "__bss",
- MCSectionMachO::S_ZEROFILL, 0,
- SectionKind()),
- Sym, Size, 1 << Pow2Alignment);
- return false;
- }
-
- Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
- return false;
-}
-
-/// ParseDirectiveDarwinZerofill
-/// ::= .zerofill segname , sectname [, identifier , size_expression [
-/// , align_expression ]]
-bool AsmParser::ParseDirectiveDarwinZerofill() {
- // FIXME: Handle quoted names here.
-
- if (Lexer.isNot(AsmToken::Identifier))
- return TokError("expected segment name after '.zerofill' directive");
- StringRef Segment = getTok().getString();
- Lex();
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- if (Lexer.isNot(AsmToken::Identifier))
- return TokError("expected section name after comma in '.zerofill' "
- "directive");
- StringRef Section = getTok().getString();
- Lex();
-
- // If this is the end of the line all that was wanted was to create the
- // the section but with no symbol.
- if (Lexer.is(AsmToken::EndOfStatement)) {
- // Create the zerofill section but no symbol
- Out.EmitZerofill(getMachOSection(Segment, Section,
- MCSectionMachO::S_ZEROFILL, 0,
- SectionKind()));
- return false;
- }
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- if (Lexer.isNot(AsmToken::Identifier))
- return TokError("expected identifier in directive");
-
- // handle the identifier as the key symbol.
- SMLoc IDLoc = Lexer.getLoc();
- MCSymbol *Sym = CreateSymbol(getTok().getString());
- Lex();
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Size;
- SMLoc SizeLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(Size))
- return true;
-
- int64_t Pow2Alignment = 0;
- SMLoc Pow2AlignmentLoc;
- if (Lexer.is(AsmToken::Comma)) {
- Lex();
- Pow2AlignmentLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(Pow2Alignment))
- return true;
- }
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.zerofill' directive");
-
- Lex();
-
- if (Size < 0)
- return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
- "than zero");
-
- // NOTE: The alignment in the directive is a power of 2 value, the assember
- // may internally end up wanting an alignment in bytes.
- // FIXME: Diagnose overflow.
- if (Pow2Alignment < 0)
- return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
- "can't be less than zero");
-
- if (!Sym->isUndefined())
- return Error(IDLoc, "invalid symbol redefinition");
-
- // Create the zerofill Symbol with Size and Pow2Alignment
- //
- // FIXME: Arch specific.
- Out.EmitZerofill(getMachOSection(Segment, Section,
- MCSectionMachO::S_ZEROFILL, 0,
- SectionKind()),
- Sym, Size, 1 << Pow2Alignment);
-
- return false;
-}
-
-/// ParseDirectiveDarwinSubsectionsViaSymbols
-/// ::= .subsections_via_symbols
-bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.subsections_via_symbols' directive");
-
- Lex();
-
- Out.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
-
- return false;
-}
-
-/// ParseDirectiveAbort
-/// ::= .abort [ "abort_string" ]
-bool AsmParser::ParseDirectiveAbort() {
- // FIXME: Use loc from directive.
- SMLoc Loc = Lexer.getLoc();
-
- StringRef Str = "";
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- if (Lexer.isNot(AsmToken::String))
- return TokError("expected string in '.abort' directive");
-
- Str = getTok().getString();
-
- Lex();
- }
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.abort' directive");
-
- Lex();
-
- // FIXME: Handle here.
- if (Str.empty())
- Error(Loc, ".abort detected. Assembly stopping.");
- else
- Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
-
- return false;
-}
-
-/// ParseDirectiveLsym
-/// ::= .lsym identifier , expression
-bool AsmParser::ParseDirectiveDarwinLsym() {
- StringRef Name;
- if (ParseIdentifier(Name))
- return TokError("expected identifier in directive");
-
- // Handle the identifier as the key symbol.
- MCSymbol *Sym = CreateSymbol(Name);
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in '.lsym' directive");
- Lex();
-
- const MCExpr *Value;
- SMLoc StartLoc = Lexer.getLoc();
- if (ParseExpression(Value))
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.lsym' directive");
-
- Lex();
-
- // We don't currently support this directive.
- //
- // FIXME: Diagnostic location!
- (void) Sym;
- return TokError("directive '.lsym' is unsupported");
-}
-
-/// ParseDirectiveInclude
-/// ::= .include "filename"
-bool AsmParser::ParseDirectiveInclude() {
- if (Lexer.isNot(AsmToken::String))
- return TokError("expected string in '.include' directive");
-
- std::string Filename = getTok().getString();
- SMLoc IncludeLoc = Lexer.getLoc();
- Lex();
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.include' directive");
-
- // Strip the quotes.
- Filename = Filename.substr(1, Filename.size()-2);
-
- // Attempt to switch the lexer to the included file before consuming the end
- // of statement to avoid losing it when we switch.
- if (EnterIncludeFile(Filename)) {
- PrintMessage(IncludeLoc,
- "Could not find include file '" + Filename + "'",
- "error");
- return true;
- }
-
- return false;
-}
-
-/// ParseDirectiveDarwinDumpOrLoad
-/// ::= ( .dump | .load ) "filename"
-bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
- if (Lexer.isNot(AsmToken::String))
- return TokError("expected string in '.dump' or '.load' directive");
-
- Lex();
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.dump' or '.load' directive");
-
- Lex();
-
- // FIXME: If/when .dump and .load are implemented they will be done in the
- // the assembly parser and not have any need for an MCStreamer API.
- if (IsDump)
- Warning(IDLoc, "ignoring directive .dump for now");
- else
- Warning(IDLoc, "ignoring directive .load for now");
-
- return false;
-}
-
-/// ParseDirectiveIf
-/// ::= .if expression
-bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
- // Consume the identifier that was the .if directive
- Lex();
-
- TheCondStack.push_back(TheCondState);
- TheCondState.TheCond = AsmCond::IfCond;
- if(TheCondState.Ignore) {
- EatToEndOfStatement();
- }
- else {
- int64_t ExprValue;
- if (ParseAbsoluteExpression(ExprValue))
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.if' directive");
-
- Lex();
-
- TheCondState.CondMet = ExprValue;
- TheCondState.Ignore = !TheCondState.CondMet;
- }
-
- return false;
-}
-
-/// ParseDirectiveElseIf
-/// ::= .elseif expression
-bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
- if (TheCondState.TheCond != AsmCond::IfCond &&
- TheCondState.TheCond != AsmCond::ElseIfCond)
- Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
- " an .elseif");
- TheCondState.TheCond = AsmCond::ElseIfCond;
-
- // Consume the identifier that was the .elseif directive
- Lex();
-
- bool LastIgnoreState = false;
- if (!TheCondStack.empty())
- LastIgnoreState = TheCondStack.back().Ignore;
- if (LastIgnoreState || TheCondState.CondMet) {
- TheCondState.Ignore = true;
- EatToEndOfStatement();
- }
- else {
- int64_t ExprValue;
- if (ParseAbsoluteExpression(ExprValue))
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.elseif' directive");
-
- Lex();
- TheCondState.CondMet = ExprValue;
- TheCondState.Ignore = !TheCondState.CondMet;
- }
-
- return false;
-}
-
-/// ParseDirectiveElse
-/// ::= .else
-bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
- // Consume the identifier that was the .else directive
- Lex();
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.else' directive");
-
- Lex();
-
- if (TheCondState.TheCond != AsmCond::IfCond &&
- TheCondState.TheCond != AsmCond::ElseIfCond)
- Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
- ".elseif");
- TheCondState.TheCond = AsmCond::ElseCond;
- bool LastIgnoreState = false;
- if (!TheCondStack.empty())
- LastIgnoreState = TheCondStack.back().Ignore;
- if (LastIgnoreState || TheCondState.CondMet)
- TheCondState.Ignore = true;
- else
- TheCondState.Ignore = false;
-
- return false;
-}
-
-/// ParseDirectiveEndIf
-/// ::= .endif
-bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
- // Consume the identifier that was the .endif directive
- Lex();
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.endif' directive");
-
- Lex();
-
- if ((TheCondState.TheCond == AsmCond::NoCond) ||
- TheCondStack.empty())
- Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
- ".else");
- if (!TheCondStack.empty()) {
- TheCondState = TheCondStack.back();
- TheCondStack.pop_back();
- }
-
- return false;
-}
-
-/// ParseDirectiveFile
-/// ::= .file [number] string
-bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
- // FIXME: I'm not sure what this is.
- int64_t FileNumber = -1;
- if (Lexer.is(AsmToken::Integer)) {
- FileNumber = getTok().getIntVal();
- Lex();
-
- if (FileNumber < 1)
- return TokError("file number less than one");
- }
-
- if (Lexer.isNot(AsmToken::String))
- return TokError("unexpected token in '.file' directive");
-
- StringRef ATTRIBUTE_UNUSED FileName = getTok().getString();
- Lex();
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.file' directive");
-
- // FIXME: Do something with the .file.
-
- return false;
-}
-
-/// ParseDirectiveLine
-/// ::= .line [number]
-bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- if (Lexer.isNot(AsmToken::Integer))
- return TokError("unexpected token in '.line' directive");
-
- int64_t LineNumber = getTok().getIntVal();
- (void) LineNumber;
- Lex();
-
- // FIXME: Do something with the .line.
- }
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.file' directive");
-
- return false;
-}
-
-
-/// ParseDirectiveLoc
-/// ::= .loc number [number [number]]
-bool AsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
- if (Lexer.isNot(AsmToken::Integer))
- return TokError("unexpected token in '.loc' directive");
-
- // FIXME: What are these fields?
- int64_t FileNumber = getTok().getIntVal();
- (void) FileNumber;
- // FIXME: Validate file.
-
- Lex();
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- if (Lexer.isNot(AsmToken::Integer))
- return TokError("unexpected token in '.loc' directive");
-
- int64_t Param2 = getTok().getIntVal();
- (void) Param2;
- Lex();
-
- if (Lexer.isNot(AsmToken::EndOfStatement)) {
- if (Lexer.isNot(AsmToken::Integer))
- return TokError("unexpected token in '.loc' directive");
-
- int64_t Param3 = getTok().getIntVal();
- (void) Param3;
- Lex();
-
- // FIXME: Do something with the .loc.
- }
- }
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.file' directive");
-
- return false;
-}
-
diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h
deleted file mode 100644
index 9336d35..0000000
--- a/tools/llvm-mc/AsmParser.h
+++ /dev/null
@@ -1,178 +0,0 @@
-//===- AsmParser.h - Parser for Assembly Files ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class declares the parser for assembly files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ASMPARSER_H
-#define ASMPARSER_H
-
-#include <vector>
-#include "AsmLexer.h"
-#include "AsmCond.h"
-#include "llvm/MC/MCAsmParser.h"
-#include "llvm/MC/MCSectionMachO.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/ADT/StringMap.h"
-
-namespace llvm {
-class AsmCond;
-class AsmToken;
-class MCContext;
-class MCExpr;
-class MCInst;
-class MCStreamer;
-class MCAsmInfo;
-class MCValue;
-class SourceMgr;
-class TargetAsmParser;
-class Twine;
-
-class AsmParser : public MCAsmParser {
-private:
- AsmLexer Lexer;
- MCContext &Ctx;
- MCStreamer &Out;
- SourceMgr &SrcMgr;
- TargetAsmParser *TargetParser;
-
- /// This is the current buffer index we're lexing from as managed by the
- /// SourceMgr object.
- int CurBuffer;
-
- AsmCond TheCondState;
- std::vector<AsmCond> TheCondStack;
-
- // FIXME: Figure out where this should leave, the code is a copy of that which
- // is also used by TargetLoweringObjectFile.
- mutable void *SectionUniquingMap;
-
- /// DirectiveMap - This is a table handlers for directives. Each handler is
- /// invoked after the directive identifier is read and is responsible for
- /// parsing and validating the rest of the directive. The handler is passed
- /// in the directive name and the location of the directive keyword.
- StringMap<bool(AsmParser::*)(StringRef, SMLoc)> DirectiveMap;
-public:
- AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
- const MCAsmInfo &_MAI);
- ~AsmParser();
-
- bool Run();
-
-
- void AddDirectiveHandler(StringRef Directive,
- bool (AsmParser::*Handler)(StringRef, SMLoc)) {
- DirectiveMap[Directive] = Handler;
- }
-public:
- TargetAsmParser &getTargetParser() const { return *TargetParser; }
- void setTargetParser(TargetAsmParser &P) { TargetParser = &P; }
-
- /// @name MCAsmParser Interface
- /// {
-
- virtual MCAsmLexer &getLexer() { return Lexer; }
- virtual MCContext &getContext() { return Ctx; }
- virtual MCStreamer &getStreamer() { return Out; }
-
- virtual void Warning(SMLoc L, const Twine &Meg);
- virtual bool Error(SMLoc L, const Twine &Msg);
-
- const AsmToken &Lex();
-
- bool ParseExpression(const MCExpr *&Res);
- virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc);
- virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
- virtual bool ParseAbsoluteExpression(int64_t &Res);
-
- /// }
-
-private:
- MCSymbol *CreateSymbol(StringRef Name);
-
- // FIXME: See comment on SectionUniquingMap.
- const MCSection *getMachOSection(const StringRef &Segment,
- const StringRef &Section,
- unsigned TypeAndAttributes,
- unsigned Reserved2,
- SectionKind Kind) const;
-
- bool ParseStatement();
-
- bool TokError(const char *Msg);
-
- void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const;
-
- /// EnterIncludeFile - Enter the specified file. This returns true on failure.
- bool EnterIncludeFile(const std::string &Filename);
-
- bool ParseConditionalAssemblyDirectives(StringRef Directive,
- SMLoc DirectiveLoc);
- void EatToEndOfStatement();
-
- bool ParseAssignment(const StringRef &Name);
-
- bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
- bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
- bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
-
- /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
- /// and set \arg Res to the identifier contents.
- bool ParseIdentifier(StringRef &Res);
-
- // Directive Parsing.
- bool ParseDirectiveDarwinSection(); // Darwin specific ".section".
- bool ParseDirectiveSectionSwitch(const char *Segment, const char *Section,
- unsigned TAA = 0, unsigned ImplicitAlign = 0,
- unsigned StubSize = 0);
- bool ParseDirectiveAscii(bool ZeroTerminated); // ".ascii", ".asciiz"
- bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
- bool ParseDirectiveFill(); // ".fill"
- bool ParseDirectiveSpace(); // ".space"
- bool ParseDirectiveSet(); // ".set"
- bool ParseDirectiveOrg(); // ".org"
- // ".align{,32}", ".p2align{,w,l}"
- bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
-
- /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
- /// accepts a single symbol (which should be a label or an external).
- bool ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr);
- bool ParseDirectiveDarwinSymbolDesc(); // Darwin specific ".desc"
- bool ParseDirectiveDarwinLsym(); // Darwin specific ".lsym"
-
- bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
- bool ParseDirectiveDarwinZerofill(); // Darwin specific ".zerofill"
-
- // Darwin specific ".subsections_via_symbols"
- bool ParseDirectiveDarwinSubsectionsViaSymbols();
- // Darwin specific .dump and .load
- bool ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump);
-
- bool ParseDirectiveAbort(); // ".abort"
- bool ParseDirectiveInclude(); // ".include"
-
- bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if"
- bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
- bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else"
- bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
-
- bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); // ".file"
- bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); // ".line"
- bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); // ".loc"
-
- /// ParseEscapedString - Parse the current token as a string which may include
- /// escaped characters and return the string contents.
- bool ParseEscapedString(std::string &Data);
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp
index 5fde712..dbfe7a5 100644
--- a/tools/llvm-mc/Disassembler.cpp
+++ b/tools/llvm-mc/Disassembler.cpp
@@ -47,32 +47,30 @@ public:
};
}
-static bool PrintInst(const llvm::MCDisassembler &DisAsm,
+static bool PrintInsts(const llvm::MCDisassembler &DisAsm,
llvm::MCInstPrinter &Printer, const ByteArrayTy &Bytes,
SourceMgr &SM) {
// Wrap the vector in a MemoryObject.
VectorMemoryObject memoryObject(Bytes);
- // Disassemble it to a string and get the size of the instruction.
- MCInst Inst;
+ // Disassemble it to strings.
uint64_t Size;
+ uint64_t Index;
- if (!DisAsm.getInstruction(Inst, Size, memoryObject, 0,
- /*REMOVE*/ nulls())) {
- SM.PrintMessage(SMLoc::getFromPointer(Bytes[0].second),
- "invalid instruction encoding", "error");
- return true;
- }
-
- Printer.printInst(&Inst);
- outs() << "\n";
-
- // If the disassembled instruction was smaller than the number of bytes we
- // read, reject the excess bytes.
- if (Bytes.size() != Size) {
- SM.PrintMessage(SMLoc::getFromPointer(Bytes[Size].second),
- "excess data detected in input", "error");
- return true;
+ for (Index = 0; Index < Bytes.size(); Index += Size) {
+ MCInst Inst;
+
+ if (DisAsm.getInstruction(Inst, Size, memoryObject, Index,
+ /*REMOVE*/ nulls())) {
+ Printer.printInst(&Inst);
+ outs() << "\n";
+ }
+ else {
+ SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
+ "invalid instruction encoding", "warning");
+ if (Size == 0)
+ Size = 1; // skip illegible bytes
+ }
}
return false;
@@ -117,15 +115,9 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
continue;
}
- // If this is the end of a line or start of a comment, process the
- // instruction we have so far.
+ // If this is the end of a line or start of a comment, remove the rest of
+ // the line.
if (Str[0] == '\n' || Str[0] == '#') {
- // If we have bytes to process, do so.
- if (!ByteArray.empty()) {
- ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM);
- ByteArray.clear();
- }
-
// Strip to the end of line if we already processed any bytes on this
// line. This strips the comment and/or the \n.
if (Str[0] == '\n')
@@ -159,7 +151,7 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
}
if (!ByteArray.empty())
- ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM);
+ ErrorOccurred |= PrintInsts(*DisAsm, *InstPrinter, ByteArray, SM);
return ErrorOccurred;
}
diff --git a/tools/llvm-mc/HexDisassembler.cpp b/tools/llvm-mc/HexDisassembler.cpp
deleted file mode 100644
index 7435c10..0000000
--- a/tools/llvm-mc/HexDisassembler.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-//===- HexDisassembler.cpp - Disassembler for hex strings -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class implements the disassembler of strings of bytes written in
-// hexadecimal, from standard input or from a file.
-//
-//===----------------------------------------------------------------------===//
-
-#include "HexDisassembler.h"
-
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCDisassembler.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstPrinter.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/MemoryObject.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/SourceMgr.h"
-using namespace llvm;
-
-typedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy;
-
-namespace {
-class VectorMemoryObject : public MemoryObject {
-private:
- const ByteArrayTy &Bytes;
-public:
- VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {}
-
- uint64_t getBase() const { return 0; }
- uint64_t getExtent() const { return Bytes.size(); }
-
- int readByte(uint64_t Addr, uint8_t *Byte) const {
- if (Addr > getExtent())
- return -1;
- *Byte = Bytes[Addr].first;
- return 0;
- }
-};
-}
-
-static bool PrintInst(const llvm::MCDisassembler &DisAsm,
- llvm::MCInstPrinter &Printer, const ByteArrayTy &Bytes,
- SourceMgr &SM) {
- // Wrap the vector in a MemoryObject.
- VectorMemoryObject memoryObject(Bytes);
-
- // Disassemble it to a string and get the size of the instruction.
- MCInst Inst;
- uint64_t Size;
-
- std::string verboseOStr;
- llvm::raw_string_ostream verboseOS(verboseOStr);
-
- if (!DisAsm.getInstruction(Inst, Size, memoryObject, 0, verboseOS)) {
- SM.PrintMessage(SMLoc::getFromPointer(Bytes[0].second),
- "invalid instruction encoding", "error");
- errs() << "Diagnostic log:" << '\n';
- errs() << verboseOS.str() << '\n';
- return true;
- }
-
- Printer.printInst(&Inst);
- outs() << "\n";
-
- // If the disassembled instruction was smaller than the number of bytes we
- // read, reject the excess bytes.
- if (Bytes.size() != Size) {
- SM.PrintMessage(SMLoc::getFromPointer(Bytes[Size].second),
- "excess data detected in input", "error");
- return true;
- }
-
- return false;
-}
-
-int HexDisassembler::disassemble(const Target &T, const std::string &Triple,
- MemoryBuffer &Buffer) {
- // Set up disassembler.
- llvm::OwningPtr<const llvm::MCAsmInfo> AsmInfo(T.createAsmInfo(Triple));
-
- if (!AsmInfo) {
- errs() << "error: no assembly info for target " << Triple << "\n";
- return -1;
- }
-
- llvm::OwningPtr<const llvm::MCDisassembler> DisAsm(T.createMCDisassembler());
- if (!DisAsm) {
- errs() << "error: no disassembler for target " << Triple << "\n";
- return -1;
- }
-
- llvm::MCInstPrinter *InstPrinter = T.createMCInstPrinter(0, *AsmInfo, outs());
-
- if (!InstPrinter) {
- errs() << "error: no instruction printer for target " << Triple << '\n';
- return -1;
- }
-
- bool ErrorOccurred = false;
-
- SourceMgr SM;
- SM.AddNewSourceBuffer(&Buffer, SMLoc());
-
- // Convert the input to a vector for disassembly.
- ByteArrayTy ByteArray;
-
- StringRef Str = Buffer.getBuffer();
- while (!Str.empty()) {
- // Strip horizontal whitespace.
- if (size_t Pos = Str.find_first_not_of(" \t\r")) {
- Str = Str.substr(Pos);
- continue;
- }
-
- // If this is the end of a line or start of a comment, process the
- // instruction we have so far.
- if (Str[0] == '\n' || Str[0] == '#') {
- // If we have bytes to process, do so.
- if (!ByteArray.empty()) {
- ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM);
- ByteArray.clear();
- }
-
- // Strip to the end of line if we already processed any bytes on this
- // line. This strips the comment and/or the \n.
- if (Str[0] == '\n')
- Str = Str.substr(1);
- else {
- Str = Str.substr(Str.find_first_of('\n'));
- if (!Str.empty())
- Str = Str.substr(1);
- }
- continue;
- }
-
- // Get the current token.
- size_t Next = Str.find_first_of(" \t\n\r#");
- StringRef Value = Str.substr(0, Next);
-
- // Convert to a byte and add to the byte vector.
- unsigned ByteVal;
- if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) {
- // If we have an error, print it and skip to the end of line.
- SM.PrintMessage(SMLoc::getFromPointer(Value.data()),
- "invalid input token", "error");
- ErrorOccurred = true;
- Str = Str.substr(Str.find('\n'));
- ByteArray.clear();
- continue;
- }
-
- ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data()));
- Str = Str.substr(Next);
- }
-
- if (!ByteArray.empty())
- ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM);
-
- return ErrorOccurred;
-}
diff --git a/tools/llvm-mc/HexDisassembler.h b/tools/llvm-mc/HexDisassembler.h
deleted file mode 100644
index d197aea..0000000
--- a/tools/llvm-mc/HexDisassembler.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- HexDisassembler.h - Disassembler for hex strings -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class implements the disassembler of strings of bytes written in
-// hexadecimal, from standard input or from a file.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef HEXDISASSEMBLER_H
-#define HEXDISASSEMBLER_H
-
-#include <string>
-
-namespace llvm {
-
-class Target;
-class MemoryBuffer;
-
-class HexDisassembler {
-public:
- static int disassemble(const Target &target,
- const std::string &tripleString,
- MemoryBuffer &buffer);
-};
-
-} // namespace llvm
-
-#endif
diff --git a/tools/llvm-mc/Makefile b/tools/llvm-mc/Makefile
index 5ce1a8f..5b0fe3f 100644
--- a/tools/llvm-mc/Makefile
+++ b/tools/llvm-mc/Makefile
@@ -13,7 +13,6 @@ TOOLNAME = llvm-mc
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
NO_INSTALL = 1
-CXXFLAGS = -fno-rtti
# Include this here so we can get the configuration of the targets
# that have been configured for construction. We have to do this
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index 342ae99..76ce080 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -46,6 +46,9 @@ OutputFilename("o", cl::desc("Output filename"),
static cl::opt<bool>
ShowEncoding("show-encoding", cl::desc("Show instruction encodings"));
+static cl::opt<bool>
+ShowInst("show-inst", cl::desc("Show internal instruction representation"));
+
static cl::opt<unsigned>
OutputAsmVariant("output-asm-variant",
cl::desc("Syntax variant to use for output printing"));
@@ -263,13 +266,14 @@ static int AssembleInput(const char *ProgName) {
if (FileType == OFT_AssemblyFile) {
IP.reset(TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *Out));
if (ShowEncoding)
- CE.reset(TheTarget->createCodeEmitter(*TM));
+ CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
Str.reset(createAsmStreamer(Ctx, *Out, *MAI,
TM->getTargetData()->isLittleEndian(),
- /*asmverbose*/true, IP.get(), CE.get()));
+ /*asmverbose*/true, IP.get(), CE.get(),
+ ShowInst));
} else {
assert(FileType == OFT_ObjectFile && "Invalid file type!");
- CE.reset(TheTarget->createCodeEmitter(*TM));
+ CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
Str.reset(createMachOStreamer(Ctx, *Out, CE.get()));
}
diff --git a/tools/llvm-nm/Makefile b/tools/llvm-nm/Makefile
index bdefaa6..ecf5f8c 100644
--- a/tools/llvm-nm/Makefile
+++ b/tools/llvm-nm/Makefile
@@ -13,6 +13,5 @@ LINK_COMPONENTS = archive bitreader
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-prof/Makefile b/tools/llvm-prof/Makefile
index b1fd330..86eb54d 100644
--- a/tools/llvm-prof/Makefile
+++ b/tools/llvm-prof/Makefile
@@ -13,6 +13,5 @@ LINK_COMPONENTS = bitreader analysis
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
-CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/tools/llvmc/Makefile b/tools/llvmc/Makefile
index df91728..8f99526 100644
--- a/tools/llvmc/Makefile
+++ b/tools/llvmc/Makefile
@@ -11,6 +11,7 @@ LEVEL = ../..
export LLVMC_BASED_DRIVER_NAME = llvmc
export LLVMC_BUILTIN_PLUGINS = Base Clang
+REQUIRES_RTTI = 1
DIRS = plugins driver
diff --git a/tools/llvmc/example/mcc16/driver/Main.cpp b/tools/llvmc/example/mcc16/driver/Main.cpp
index 5d50f9d..e66e2f9 100644
--- a/tools/llvmc/example/mcc16/driver/Main.cpp
+++ b/tools/llvmc/example/mcc16/driver/Main.cpp
@@ -37,11 +37,15 @@ int main(int argc, char** argv) {
DryRun.setHiddenFlag(llvm::cl::Hidden);
llvm::cl::SetVersionPrinter(PIC16VersionPrinter);
-
- TempDirname = "tmp-objs";
- // Remove the temp dir if already exists.
+ // Ask for a standard temp dir, but just cache its basename., and delete it.
llvm::sys::Path tempDir;
+ tempDir = llvm::sys::Path::GetTemporaryDirectory();
+ TempDirname = tempDir.getBasename();
+ tempDir.eraseFromDisk(true);
+
+ // We are creating a temp dir in current dir, with the cached name.
+ // But before that remove if one already exists with that name..
tempDir = TempDirname;
tempDir.eraseFromDisk(true);
diff --git a/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td b/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td
index 717e95e..f13b9f8 100644
--- a/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td
+++ b/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td
@@ -47,15 +47,24 @@ def OptionList : OptionList<[
(help "Optimization Level 3.")),
(switch_option "Od",
(help "Perform Debug-safe Optimizations only.")),
- (switch_option "r",
- (help "Use resource file for part info"),
- (really_hidden)),
+ (switch_option "w",
+ (help "Disable all warnings.")),
+// (switch_option "O1",
+// (help "Optimization level 1")),
+// (switch_option "O2",
+// (help "Optimization level 2. (Default)")),
+// (parameter_option "pre-RA-sched",
+// (help "Example of an option that is passed to llc")),
(parameter_option "regalloc",
- (help "Register allocator to use.(possible values: simple, linearscan, pbqp, local. default = pbqp)")),
- (prefix_list_option "Wa,",
+ (help "Register allocator to use.(possible values: simple, linearscan, pbqp, local. default = linearscan)")),
+ (prefix_list_option "Wa,", (comma_separated),
(help "Pass options to assembler (Run 'gpasm -help' for assembler options)")),
- (prefix_list_option "Wl,",
+ (prefix_list_option "Wl,", (comma_separated),
(help "Pass options to linker (Run 'mplink -help' for linker options)"))
+// (prefix_list_option "Wllc,",
+// (help "Pass options to llc")),
+// (prefix_list_option "Wo,",
+// (help "Pass options to llvm-ld"))
]>;
// Tools
@@ -75,6 +84,7 @@ class clang_based<string language, string cmd, string ext_E> : Tool<
(switch_on "E"), [(stop_compilation), (output_suffix ext_E)],
(switch_on "bc"),[(stop_compilation), (output_suffix "bc")],
(switch_on "g"), (append_cmd "-g"),
+ (switch_on "w"), (append_cmd "-w"),
(switch_on "O1"), (append_cmd ""),
(switch_on "O2"), (append_cmd ""),
(switch_on "O3"), (append_cmd ""),
@@ -83,9 +93,22 @@ class clang_based<string language, string cmd, string ext_E> : Tool<
(not_empty "I"), (forward "I"),
(switch_on "O0"), (append_cmd "-O0"),
(default), (append_cmd "-O1")))
+// (sink)
]>;
-def clang_cc : clang_based<"c", "$CALL(GetBinDir)clang -cc1 -I $CALL(GetStdHeadersDir) -triple=pic16- -emit-llvm-bc ", "i">;
+def clang_cc : clang_based<"c", "$CALL(GetBinDir)clang -cc1 -I $CALL(GetStdHeadersDir) -D $CALL(GetLowerCasePartDefine) -D $CALL(GetUpperCasePartDefine) -triple=pic16- -emit-llvm-bc ", "i">;
+
+//def clang_cc : Tool<[
+// (in_language "c"),
+// (out_language "llvm-bitcode"),
+// (output_suffix "bc"),
+// (cmd_line "$CALL(GetBinDir)clang-cc -I $CALL(GetStdHeadersDir) -triple=pic16- -emit-llvm-bc "),
+// (cmd_line kkkkk
+// (actions (case
+// (switch_on "g"), (append_cmd "g"),
+// (not_empty "I"), (forward "I"))),
+// (sink)
+//]>;
// pre-link-and-lto step.
@@ -93,12 +116,12 @@ def llvm_ld : Tool<[
(in_language "llvm-bitcode"),
(out_language "llvm-bitcode"),
(output_suffix "bc"),
- (cmd_line "$CALL(GetBinDir)llvm-ld -L $CALL(GetStdLibsDir) -instcombine -disable-licm-promotion $INFILE -b $OUTFILE -l std"),
+ (cmd_line "$CALL(GetBinDir)llvm-ld -L $CALL(GetStdLibsDir) -disable-gvn -disable-licm-promotion -disable-mem2reg $INFILE -b $OUTFILE -l std"),
(actions (case
(switch_on "O0"), (append_cmd "-disable-opt"),
(switch_on "O1"), (append_cmd "-disable-opt"),
- (switch_on "O2"), (append_cmd ""),
// Whenever O3 is not specified on the command line, default i.e. disable-inlining will always be added.
+ (switch_on "O2"), (append_cmd ""),
(switch_on "O3"), (append_cmd ""),
(default), (append_cmd "-disable-inlining"))),
(join)
@@ -109,9 +132,16 @@ def llvm_ld_optimizer : Tool<[
(in_language "llvm-bitcode"),
(out_language "llvm-bitcode"),
(output_suffix "bc"),
- (cmd_line "$CALL(GetBinDir)llvm-ld -instcombine -disable-inlining $INFILE -b $OUTFILE"),
+// FIXME: we are still not disabling licm-promotion.
+// -disable-licm-promotion and building stdn library causes c16-71 to fail.
+ (cmd_line "$CALL(GetBinDir)llvm-ld -disable-gvn -disable-mem2reg $INFILE -b $OUTFILE"),
(actions (case
- (switch_on "O0"), (append_cmd "-disable-opt")))
+ (switch_on "O0"), (append_cmd "-disable-opt"),
+ (switch_on "O1"), (append_cmd "-disable-opt"),
+// Whenever O3 is not specified on the command line, default i.e. disable-inlining will always be added.
+ (switch_on "O2"), (append_cmd ""),
+ (switch_on "O3"), (append_cmd ""),
+ (default), (append_cmd "-disable-inlining")))
]>;
// optimizer step.
@@ -119,7 +149,7 @@ def pic16passes : Tool<[
(in_language "llvm-bitcode"),
(out_language "llvm-bitcode"),
(output_suffix "obc"),
- (cmd_line "$CALL(GetBinDir)opt -pic16overlay $INFILE -f -o $OUTFILE"),
+ (cmd_line "$CALL(GetBinDir)opt -pic16cg -pic16overlay $INFILE -f -o $OUTFILE"),
(actions (case
(switch_on "O0"), (append_cmd "-disable-opt")))
]>;
@@ -131,19 +161,20 @@ def llc : Tool<[
(cmd_line "$CALL(GetBinDir)llc -march=pic16 -disable-jump-tables -pre-RA-sched=list-burr -f $INFILE -o $OUTFILE"),
(actions (case
(switch_on "S"), (stop_compilation),
+// (not_empty "Wllc,"), (unpack_values "Wllc,"),
+// (not_empty "pre-RA-sched"), (forward "pre-RA-sched")))
(not_empty "regalloc"), (forward "regalloc"),
- (empty "regalloc"), (append_cmd "-regalloc=pbqp")))
+ (empty "regalloc"), (append_cmd "-regalloc=linearscan")))
]>;
def gpasm : Tool<[
(in_language "assembler"),
(out_language "object-code"),
(output_suffix "o"),
- (cmd_line "$CALL(GetBinDir)gpasm -r decimal -I $CALL(GetStdAsmHeadersDir) -C -c -w 2 $INFILE -o $OUTFILE"),
+ (cmd_line "$CALL(GetBinDir)gpasm -z -r decimal -I $CALL(GetStdAsmHeadersDir) -C -c -w 2 $INFILE -o $OUTFILE"),
(actions (case
(switch_on "c"), (stop_compilation),
(switch_on "g"), (append_cmd "-g"),
- (switch_on "r"), (append_cmd "-z"),
(not_empty "p"), (forward "p"),
(empty "p"), (append_cmd "-p 16f1xxx"),
(not_empty "Wa,"), (forward_value "Wa,")))
@@ -153,18 +184,18 @@ def mplink : Tool<[
(in_language "object-code"),
(out_language "executable"),
(output_suffix "cof"),
- (cmd_line "$CALL(GetBinDir)mplink -k $CALL(GetStdLinkerScriptsDir) -l $CALL(GetStdLibsDir) intrinsics.lib stdn.lib $INFILE -o $OUTFILE"),
+ (cmd_line "$CALL(GetBinDir)mplink -e -k $CALL(GetStdLinkerScriptsDir) -l $CALL(GetStdLibsDir) intrinsics.lib stdn.lib $INFILE -o $OUTFILE"),
(actions (case
(not_empty "Wl,"), (forward_value "Wl,"),
- (switch_on "r"), (append_cmd "-e"),
(switch_on "X"), (append_cmd "-x"),
(not_empty "L"), (forward_as "L", "-l"),
(not_empty "K"), (forward_as "K", "-k"),
(not_empty "m"), (forward "m"),
(not_empty "p"), [(forward "p"), (append_cmd "-c")],
(empty "p"), (append_cmd "-p 16f1xxx -c"),
- (not_empty "k"), (forward_value "k"),
- (not_empty "l"), (forward_value "l"))),
+// (not_empty "l"), [(unpack_values "l"),(append_cmd ".lib")])),
+ (not_empty "k"), (forward "k"),
+ (not_empty "l"), (forward "l"))),
(join)
]>;
diff --git a/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp b/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp
index a6d2ff6..9b2f9fc5 100644
--- a/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp
+++ b/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp
@@ -9,6 +9,8 @@ namespace llvmc {
extern char *ProgramName;
}
+
+
// Returns the platform specific directory separator via #ifdefs.
// FIXME: This currently work on linux and windows only. It does not
// work on other unices.
@@ -21,6 +23,43 @@ static std::string GetDirSeparator() {
}
namespace hooks {
+// Get preprocessor define for the part.
+// It is __partname format in lower case.
+std::string
+GetLowerCasePartDefine(void) {
+ std::string Partname;
+ if (AutoGeneratedParameter_p.empty()) {
+ Partname = "16f1xxx";
+ } else {
+ Partname = AutoGeneratedParameter_p;
+ }
+
+ std::string LowerCase;
+ for (unsigned i = 0; i <= Partname.size(); i++) {
+ LowerCase.push_back(std::tolower(Partname[i]));
+ }
+
+ return "__" + LowerCase;
+}
+
+std::string
+GetUpperCasePartDefine(void) {
+ std::string Partname;
+ if (AutoGeneratedParameter_p.empty()) {
+ Partname = "16f1xxx";
+ } else {
+ Partname = AutoGeneratedParameter_p;
+ }
+
+ std::string UpperCase;
+ for (unsigned i = 0; i <= Partname.size(); i++) {
+ UpperCase.push_back(std::toupper(Partname[i]));
+ }
+
+ return "__" + UpperCase;
+}
+
+
// Get the dir where c16 executables reside.
std::string GetBinDir() {
// Construct a Path object from the program name.
diff --git a/tools/llvmc/plugins/Base/Base.td.in b/tools/llvmc/plugins/Base/Base.td.in
index cf0ff68..1acd969 100644
--- a/tools/llvmc/plugins/Base/Base.td.in
+++ b/tools/llvmc/plugins/Base/Base.td.in
@@ -50,10 +50,18 @@ def OptList : OptionList<[
(help "Choose linker (possible values: gcc, g++)")),
(parameter_option "mtune",
(help "Target a specific CPU type"), (hidden)),
+
+ // TODO: Add a conditional compilation mechanism to make Darwin-only options
+ // like '-arch' really Darwin-only.
+
+ (parameter_option "arch",
+ (help "Compile for the specified target architecture"), (hidden)),
(parameter_option "march",
(help "A synonym for -mtune"), (hidden)),
(parameter_option "mcpu",
(help "A deprecated synonym for -mtune"), (hidden)),
+ (switch_option "mfix-and-continue",
+ (help "Needed by gdb to load .o files dynamically"), (hidden)),
(parameter_option "MF",
(help "Specify a file to write dependencies to"), (hidden)),
(parameter_list_option "MT",
@@ -61,6 +69,9 @@ def OptList : OptionList<[
(hidden)),
(parameter_list_option "include",
(help "Include the named file prior to preprocessing")),
+ (parameter_list_option "iquote",
+ (help "Search dir only for files requested with #inlcude \"file\""),
+ (hidden)),
(parameter_list_option "framework",
(help "Specifies a framework to link against")),
(parameter_list_option "weak_framework",
@@ -85,7 +96,19 @@ def OptList : OptionList<[
(help "Pass options to opt")),
(prefix_list_option "m",
(help "Enable or disable various extensions (-mmmx, -msse, etc.)"),
- (hidden))
+ (hidden)),
+ (switch_option "dynamiclib", (hidden),
+ (help "Produce a dynamic library")),
+ (switch_option "prebind", (hidden),
+ (help "Prebind all undefined symbols")),
+ (switch_option "dead_strip", (hidden),
+ (help "Remove unreachable blocks of code")),
+ (switch_option "single_module", (hidden),
+ (help "Build the library so it contains only one module")),
+ (parameter_option "compatibility_version", (hidden),
+ (help "Compatibility version number")),
+ (parameter_option "current_version", (hidden),
+ (help "Current version number"))
]>;
// Option preprocessor.
@@ -129,14 +152,17 @@ class llvm_gcc_based <string cmd_prefix, string in_lang, string E_ext> : Tool<
(switch_on ["emit-llvm", "c"]), (stop_compilation),
(switch_on "fsyntax-only"), (stop_compilation),
(not_empty "include"), (forward "include"),
+ (not_empty "iquote"), (forward "iquote"),
(not_empty "save-temps"), (append_cmd "-save-temps"),
(not_empty "I"), (forward "I"),
(not_empty "F"), (forward "F"),
(not_empty "D"), (forward "D"),
+ (not_empty "arch"), (forward "arch"),
(not_empty "march"), (forward "march"),
(not_empty "mtune"), (forward "mtune"),
(not_empty "mcpu"), (forward "mcpu"),
(not_empty "m"), (forward "m"),
+ (switch_on "mfix-and-continue"), (forward "mfix-and-continue"),
(switch_on "m32"), (forward "m32"),
(switch_on "m64"), (forward "m64"),
(switch_on "O0"), (forward "O0"),
@@ -183,6 +209,7 @@ def llvm_gcc_assembler : Tool<
(cmd_line "@LLVMGCCCOMMAND@ -c -x assembler $INFILE -o $OUTFILE"),
(actions (case
(switch_on "c"), (stop_compilation),
+ (not_empty "arch"), (forward "arch"),
(not_empty "Wa,"), (forward_value "Wa,")))
]>;
@@ -218,12 +245,21 @@ class llvm_gcc_based_linker <string cmd_prefix> : Tool<
(switch_on "pthread"), (append_cmd "-lpthread"),
(not_empty "L"), (forward "L"),
(not_empty "F"), (forward "F"),
+ (not_empty "arch"), (forward "arch"),
(not_empty "framework"), (forward "framework"),
(not_empty "weak_framework"), (forward "weak_framework"),
(switch_on "m32"), (forward "m32"),
(switch_on "m64"), (forward "m64"),
(not_empty "l"), (forward "l"),
- (not_empty "Wl,"), (forward "Wl,")))
+ (not_empty "Wl,"), (forward "Wl,"),
+ (switch_on "dynamiclib"), (forward "dynamiclib"),
+ (switch_on "prebind"), (forward "prebind"),
+ (switch_on "dead_strip"), (forward "dead_strip"),
+ (switch_on "single_module"), (forward "single_module"),
+ (not_empty "compatibility_version"),
+ (forward "compatibility_version"),
+ (not_empty "current_version"),
+ (forward "current_version")))
]>;
// Default linker
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index 46e967a..0a58aa7 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -15,13 +15,11 @@
#include "LTOModule.h"
#include "LTOCodeGenerator.h"
-
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
@@ -29,7 +27,6 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/CodeGen/FileWriters.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -392,32 +389,15 @@ bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out,
// Make sure everything is still good.
passes.add(createVerifierPass());
- FunctionPassManager* codeGenPasses =
- new FunctionPassManager(new ExistingModuleProvider(mergedModule));
+ FunctionPassManager* codeGenPasses = new FunctionPassManager(mergedModule);
codeGenPasses->add(new TargetData(*_target->getTargetData()));
- ObjectCodeEmitter* oce = NULL;
-
- switch (_target->addPassesToEmitFile(*codeGenPasses, out,
- TargetMachine::AssemblyFile,
- CodeGenOpt::Aggressive)) {
- case FileModel::ElfFile:
- oce = AddELFWriter(*codeGenPasses, out, *_target);
- break;
- case FileModel::AsmFile:
- break;
- case FileModel::MachOFile:
- case FileModel::Error:
- case FileModel::None:
- errMsg = "target file type not supported";
- return true;
- }
-
- if (_target->addPassesToEmitFileFinish(*codeGenPasses, oce,
- CodeGenOpt::Aggressive)) {
- errMsg = "target does not support generation of this file type";
- return true;
+ if (_target->addPassesToEmitFile(*codeGenPasses, out,
+ TargetMachine::CGFT_AssemblyFile,
+ CodeGenOpt::Aggressive)) {
+ errMsg = "target file type not supported";
+ return true;
}
// Run our queue of passes all at once now, efficiently.
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp
index 64de668..15fb3f5 100644
--- a/tools/lto/LTOModule.cpp
+++ b/tools/lto/LTOModule.cpp
@@ -17,7 +17,6 @@
#include "llvm/Constants.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Bitcode/ReaderWriter.h"
@@ -69,14 +68,13 @@ bool LTOModule::isBitcodeFileForTarget(const char* path,
// takes ownership of buffer
bool LTOModule::isTargetMatch(MemoryBuffer* buffer, const char* triplePrefix)
{
- OwningPtr<ModuleProvider> mp(getBitcodeModuleProvider(buffer,
- getGlobalContext()));
- // on success, mp owns buffer and both are deleted at end of this method
- if (!mp) {
+ OwningPtr<Module> m(getLazyBitcodeModule(buffer, getGlobalContext()));
+ // on success, m owns buffer and both are deleted at end of this method
+ if (!m) {
delete buffer;
return false;
}
- std::string actualTarget = mp->getModule()->getTargetTriple();
+ std::string actualTarget = m->getTargetTriple();
return (strncmp(actualTarget.c_str(), triplePrefix,
strlen(triplePrefix)) == 0);
}
diff --git a/tools/lto/Makefile b/tools/lto/Makefile
index f0bc67c..3120aa5 100644
--- a/tools/lto/Makefile
+++ b/tools/lto/Makefile
@@ -17,7 +17,6 @@ include $(LEVEL)/Makefile.config
LINK_LIBS_IN_SHARED = 1
SHARED_LIBRARY = 1
-CXXFLAGS = -fno-rtti
LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter
diff --git a/tools/opt/Makefile b/tools/opt/Makefile
index 2f184a6..726cad8 100644
--- a/tools/opt/Makefile
+++ b/tools/opt/Makefile
@@ -8,7 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../..
TOOLNAME = opt
-CXXFLAGS = -fno-rtti
LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 6ed8c9d..5200180 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -14,7 +14,6 @@
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/CallGraphSCCPass.h"
#include "llvm/Bitcode/ReaderWriter.h"
@@ -427,7 +426,7 @@ int main(int argc, char **argv) {
FunctionPassManager *FPasses = NULL;
if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
- FPasses = new FunctionPassManager(new ExistingModuleProvider(M.get()));
+ FPasses = new FunctionPassManager(M.get());
if (TD)
FPasses->add(new TargetData(*TD));
}
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
index 76cdafc..b02cc3e 100644
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -333,6 +333,8 @@ TEST(APFloatTest, toString) {
ASSERT_EQ("1.01E-2", convertToString(1.01E-2, 5, 1));
ASSERT_EQ("0.7853981633974483", convertToString(0.78539816339744830961, 0, 3));
ASSERT_EQ("4.940656458412465E-324", convertToString(4.9406564584124654e-324, 0, 3));
+ ASSERT_EQ("873.1834", convertToString(873.1834, 0, 1));
+ ASSERT_EQ("8.731834E+2", convertToString(873.1834, 0, 0));
}
#ifdef GTEST_HAS_DEATH_TEST
diff --git a/unittests/ADT/BitVectorTest.cpp b/unittests/ADT/BitVectorTest.cpp
index 5348281..4fe11c1 100644
--- a/unittests/ADT/BitVectorTest.cpp
+++ b/unittests/ADT/BitVectorTest.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#ifndef XFAIL
#include "llvm/ADT/BitVector.h"
#include "gtest/gtest.h"
@@ -137,4 +138,45 @@ TEST(BitVectorTest, TrivialOperation) {
EXPECT_TRUE(Vec.empty());
}
+TEST(BitVectorTest, CompoundAssignment) {
+ BitVector A;
+ A.resize(10);
+ A.set(4);
+ A.set(7);
+
+ BitVector B;
+ B.resize(50);
+ B.set(5);
+ B.set(18);
+
+ A |= B;
+ EXPECT_TRUE(A.test(4));
+ EXPECT_TRUE(A.test(5));
+ EXPECT_TRUE(A.test(7));
+ EXPECT_TRUE(A.test(18));
+ EXPECT_EQ(4U, A.count());
+ EXPECT_EQ(50U, A.size());
+
+ B.resize(10);
+ B.set();
+ B.reset(2);
+ B.reset(7);
+ A &= B;
+ EXPECT_FALSE(A.test(2));
+ EXPECT_FALSE(A.test(7));
+ EXPECT_EQ(2U, A.count());
+ EXPECT_EQ(50U, A.size());
+
+ B.resize(100);
+ B.set();
+
+ A ^= B;
+ EXPECT_TRUE(A.test(2));
+ EXPECT_TRUE(A.test(7));
+ EXPECT_EQ(98U, A.count());
+ EXPECT_EQ(100U, A.size());
}
+
+}
+
+#endif
diff --git a/unittests/ADT/Makefile b/unittests/ADT/Makefile
index c56b951..fe08328 100644
--- a/unittests/ADT/Makefile
+++ b/unittests/ADT/Makefile
@@ -12,4 +12,12 @@ TESTNAME = ADT
LINK_COMPONENTS := core support
include $(LEVEL)/Makefile.config
+
+# Xfail BitVectorTest for now on PPC Darwin. 7598360.
+ifeq ($(ARCH),PowerPC)
+ifeq ($(TARGET_OS),Darwin)
+CPP.Flags += -DXFAIL
+endif
+endif
+
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/ADT/SmallBitVectorTest.cpp b/unittests/ADT/SmallBitVectorTest.cpp
index a5c60de..a2cc652 100644
--- a/unittests/ADT/SmallBitVectorTest.cpp
+++ b/unittests/ADT/SmallBitVectorTest.cpp
@@ -137,4 +137,43 @@ TEST(SmallBitVectorTest, TrivialOperation) {
EXPECT_TRUE(Vec.empty());
}
+TEST(SmallBitVectorTest, CompoundAssignment) {
+ SmallBitVector A;
+ A.resize(10);
+ A.set(4);
+ A.set(7);
+
+ SmallBitVector B;
+ B.resize(50);
+ B.set(5);
+ B.set(18);
+
+ A |= B;
+ EXPECT_TRUE(A.test(4));
+ EXPECT_TRUE(A.test(5));
+ EXPECT_TRUE(A.test(7));
+ EXPECT_TRUE(A.test(18));
+ EXPECT_EQ(4U, A.count());
+ EXPECT_EQ(50U, A.size());
+
+ B.resize(10);
+ B.set();
+ B.reset(2);
+ B.reset(7);
+ A &= B;
+ EXPECT_FALSE(A.test(2));
+ EXPECT_FALSE(A.test(7));
+ EXPECT_EQ(2U, A.count());
+ EXPECT_EQ(50U, A.size());
+
+ B.resize(100);
+ B.set();
+
+ A ^= B;
+ EXPECT_TRUE(A.test(2));
+ EXPECT_TRUE(A.test(7));
+ EXPECT_EQ(98U, A.count());
+ EXPECT_EQ(100U, A.size());
+}
+
}
diff --git a/unittests/ADT/StringMapTest.cpp b/unittests/ADT/StringMapTest.cpp
index 3dcdc39..413f068 100644
--- a/unittests/ADT/StringMapTest.cpp
+++ b/unittests/ADT/StringMapTest.cpp
@@ -191,6 +191,7 @@ TEST_F(StringMapTest, StringMapEntryTest) {
testKeyFirst, testKeyFirst + testKeyLength, 1u);
EXPECT_STREQ(testKey, entry->first());
EXPECT_EQ(1u, entry->second);
+ free(entry);
}
// Test insert() method.
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
index a58a087..a36ec3b 100644
--- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
@@ -12,7 +12,6 @@
#include "llvm/LLVMContext.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/ExecutionEngine/JIT.h"
@@ -25,7 +24,6 @@ using namespace llvm;
int dummy;
-#if 0
namespace {
struct FunctionEmittedEvent {
@@ -238,4 +236,3 @@ testing::Environment* const jit_env =
testing::AddGlobalTestEnvironment(new JITEnvironment);
} // anonymous namespace
-#endif
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
index bed2d22..84ee0e3 100644
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -23,7 +23,6 @@
#include "llvm/GlobalVariable.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
@@ -58,7 +57,6 @@ std::string DumpFunction(const Function *F) {
return Result;
}
-#if 0
class RecordingJITMemoryManager : public JITMemoryManager {
const OwningPtr<JITMemoryManager> Base;
public:
@@ -179,7 +177,6 @@ public:
return Base->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
}
};
-#endif
bool LoadAssemblyInto(Module *M, const char *assembly) {
SMDiagnostic Error;
@@ -196,16 +193,11 @@ class JITTest : public testing::Test {
protected:
virtual void SetUp() {
M = new Module("<main>", Context);
- MP = new ExistingModuleProvider(M);
-#if 0
RJMM = new RecordingJITMemoryManager;
RJMM->setPoisonMemory(true);
-#endif
std::string Error;
- TheJIT.reset(EngineBuilder(MP).setEngineKind(EngineKind::JIT)
-#if 0
+ TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT)
.setJITMemoryManager(RJMM)
-#endif
.setErrorStr(&Error).create());
ASSERT_TRUE(TheJIT.get() != NULL) << Error;
}
@@ -215,11 +207,8 @@ class JITTest : public testing::Test {
}
LLVMContext Context;
- Module *M; // Owned by MP.
- ModuleProvider *MP; // Owned by ExecutionEngine.
-#if 0
+ Module *M; // Owned by ExecutionEngine.
RecordingJITMemoryManager *RJMM;
-#endif
OwningPtr<ExecutionEngine> TheJIT;
};
@@ -231,14 +220,13 @@ class JITTest : public testing::Test {
TEST(JIT, GlobalInFunction) {
LLVMContext context;
Module *M = new Module("<main>", context);
- ExistingModuleProvider *MP = new ExistingModuleProvider(M);
JITMemoryManager *MemMgr = JITMemoryManager::CreateDefaultMemManager();
// Tell the memory manager to poison freed memory so that accessing freed
// memory is more easily tested.
MemMgr->setPoisonMemory(true);
std::string Error;
- OwningPtr<ExecutionEngine> JIT(EngineBuilder(MP)
+ OwningPtr<ExecutionEngine> JIT(EngineBuilder(M)
.setEngineKind(EngineKind::JIT)
.setErrorStr(&Error)
.setJITMemoryManager(MemMgr)
@@ -436,9 +424,9 @@ TEST_F(JITTest, ModuleDeletion) {
"} ");
Function *func = M->getFunction("main");
TheJIT->getPointerToFunction(func);
- TheJIT->deleteModuleProvider(MP);
+ TheJIT->removeModule(M);
+ delete M;
-#if 0
SmallPtrSet<const void*, 2> FunctionsDeallocated;
for (unsigned i = 0, e = RJMM->deallocateFunctionBodyCalls.size();
i != e; ++i) {
@@ -472,7 +460,6 @@ TEST_F(JITTest, ModuleDeletion) {
}
EXPECT_EQ(RJMM->startExceptionTableCalls.size(),
NumTablesDeallocated);
-#endif
}
// ARM and PPC still emit stubs for calls since the target may be too far away
@@ -507,18 +494,14 @@ TEST_F(JITTest, NoStubs) {
// We should now allocate no more stubs, we have the code to foo
// and the existing stub for bar.
-#if 0
int stubsBefore = RJMM->stubsAllocated;
-#endif
Function *func = M->getFunction("main");
TheJIT->getPointerToFunction(func);
Function *bar = M->getFunction("bar");
TheJIT->getPointerToFunction(bar);
-#if 0
ASSERT_EQ(stubsBefore, RJMM->stubsAllocated);
-#endif
}
#endif // !ARM && !PPC
@@ -661,36 +644,70 @@ std::string AssembleToBitcode(LLVMContext &Context, const char *Assembly) {
}
// Returns a newly-created ExecutionEngine that reads the bitcode in 'Bitcode'
-// lazily. The associated ModuleProvider (owned by the ExecutionEngine) is
-// returned in MP. Both will be NULL on an error. Bitcode must live at least
-// as long as the ExecutionEngine.
+// lazily. The associated Module (owned by the ExecutionEngine) is returned in
+// M. Both will be NULL on an error. Bitcode must live at least as long as the
+// ExecutionEngine.
ExecutionEngine *getJITFromBitcode(
- LLVMContext &Context, const std::string &Bitcode, ModuleProvider *&MP) {
+ LLVMContext &Context, const std::string &Bitcode, Module *&M) {
// c_str() is null-terminated like MemoryBuffer::getMemBuffer requires.
MemoryBuffer *BitcodeBuffer =
MemoryBuffer::getMemBuffer(Bitcode.c_str(),
Bitcode.c_str() + Bitcode.size(),
"Bitcode for test");
std::string errMsg;
- MP = getBitcodeModuleProvider(BitcodeBuffer, Context, &errMsg);
- if (MP == NULL) {
+ M = getLazyBitcodeModule(BitcodeBuffer, Context, &errMsg);
+ if (M == NULL) {
ADD_FAILURE() << errMsg;
delete BitcodeBuffer;
return NULL;
}
- ExecutionEngine *TheJIT = EngineBuilder(MP)
+ ExecutionEngine *TheJIT = EngineBuilder(M)
.setEngineKind(EngineKind::JIT)
.setErrorStr(&errMsg)
.create();
if (TheJIT == NULL) {
ADD_FAILURE() << errMsg;
- delete MP;
- MP = NULL;
+ delete M;
+ M = NULL;
return NULL;
}
return TheJIT;
}
+TEST(LazyLoadedJITTest, MaterializableAvailableExternallyFunctionIsntCompiled) {
+ LLVMContext Context;
+ const std::string Bitcode =
+ AssembleToBitcode(Context,
+ "define available_externally i32 "
+ " @JITTest_AvailableExternallyFunction() { "
+ " ret i32 7 "
+ "} "
+ " "
+ "define i32 @func() { "
+ " %result = tail call i32 "
+ " @JITTest_AvailableExternallyFunction() "
+ " ret i32 %result "
+ "} ");
+ ASSERT_FALSE(Bitcode.empty()) << "Assembling failed";
+ Module *M;
+ OwningPtr<ExecutionEngine> TheJIT(getJITFromBitcode(Context, Bitcode, M));
+ ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT.";
+ TheJIT->DisableLazyCompilation(true);
+
+ Function *funcIR = M->getFunction("func");
+ Function *availableFunctionIR =
+ M->getFunction("JITTest_AvailableExternallyFunction");
+
+ // Double-check that the available_externally function is still unmaterialized
+ // when getPointerToFunction needs to find out if it's available_externally.
+ EXPECT_TRUE(availableFunctionIR->isMaterializable());
+
+ int32_t (*func)() = reinterpret_cast<int32_t(*)()>(
+ (intptr_t)TheJIT->getPointerToFunction(funcIR));
+ EXPECT_EQ(42, func()) << "func should return 42 from the static version,"
+ << " not 7 from the IR version.";
+}
+
TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) {
LLVMContext Context;
const std::string Bitcode =
@@ -711,16 +728,15 @@ TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) {
" ret i32 %result "
"} ");
ASSERT_FALSE(Bitcode.empty()) << "Assembling failed";
- ModuleProvider *MP;
- OwningPtr<ExecutionEngine> TheJIT(getJITFromBitcode(Context, Bitcode, MP));
+ Module *M;
+ OwningPtr<ExecutionEngine> TheJIT(getJITFromBitcode(Context, Bitcode, M));
ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT.";
TheJIT->DisableLazyCompilation(true);
- Module *M = MP->getModule();
Function *recur1IR = M->getFunction("recur1");
Function *recur2IR = M->getFunction("recur2");
- EXPECT_TRUE(recur1IR->hasNotBeenReadFromBitcode());
- EXPECT_TRUE(recur2IR->hasNotBeenReadFromBitcode());
+ EXPECT_TRUE(recur1IR->isMaterializable());
+ EXPECT_TRUE(recur2IR->isMaterializable());
int32_t (*recur1)(int32_t) = reinterpret_cast<int32_t(*)(int32_t)>(
(intptr_t)TheJIT->getPointerToFunction(recur1IR));
diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
new file mode 100644
index 0000000..8997d39
--- /dev/null
+++ b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
@@ -0,0 +1,164 @@
+//===- MultiJITTest.cpp - Unit tests for instantiating multiple JITs ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Assembly/Parser.h"
+#include "llvm/ExecutionEngine/GenericValue.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/Support/SourceMgr.h"
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+
+bool LoadAssemblyInto(Module *M, const char *assembly) {
+ SMDiagnostic Error;
+ bool success =
+ NULL != ParseAssemblyString(assembly, M, Error, M->getContext());
+ std::string errMsg;
+ raw_string_ostream os(errMsg);
+ Error.Print("", os);
+ EXPECT_TRUE(success) << os.str();
+ return success;
+}
+
+void createModule1(LLVMContext &Context1, Module *&M1, Function *&FooF1) {
+ M1 = new Module("test1", Context1);
+ LoadAssemblyInto(M1,
+ "define i32 @add1(i32 %ArgX1) { "
+ "entry: "
+ " %addresult = add i32 1, %ArgX1 "
+ " ret i32 %addresult "
+ "} "
+ " "
+ "define i32 @foo1() { "
+ "entry: "
+ " %add1 = call i32 @add1(i32 10) "
+ " ret i32 %add1 "
+ "} ");
+ FooF1 = M1->getFunction("foo1");
+}
+
+void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) {
+ M2 = new Module("test2", Context2);
+ LoadAssemblyInto(M2,
+ "define i32 @add2(i32 %ArgX2) { "
+ "entry: "
+ " %addresult = add i32 2, %ArgX2 "
+ " ret i32 %addresult "
+ "} "
+ " "
+ "define i32 @foo2() { "
+ "entry: "
+ " %add2 = call i32 @add2(i32 10) "
+ " ret i32 %add2 "
+ "} ");
+ FooF2 = M2->getFunction("foo2");
+}
+
+TEST(MultiJitTest, EagerMode) {
+ LLVMContext Context1;
+ Module *M1 = 0;
+ Function *FooF1 = 0;
+ createModule1(Context1, M1, FooF1);
+
+ LLVMContext Context2;
+ Module *M2 = 0;
+ Function *FooF2 = 0;
+ createModule2(Context2, M2, FooF2);
+
+ // Now we create the JIT in eager mode
+ OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ EE1->DisableLazyCompilation(true);
+ OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ EE2->DisableLazyCompilation(true);
+
+ // Call the `foo' function with no arguments:
+ std::vector<GenericValue> noargs;
+ GenericValue gv1 = EE1->runFunction(FooF1, noargs);
+ GenericValue gv2 = EE2->runFunction(FooF2, noargs);
+
+ // Import result of execution:
+ EXPECT_EQ(gv1.IntVal, 11);
+ EXPECT_EQ(gv2.IntVal, 12);
+
+ EE1->freeMachineCodeForFunction(FooF1);
+ EE2->freeMachineCodeForFunction(FooF2);
+}
+
+TEST(MultiJitTest, LazyMode) {
+ LLVMContext Context1;
+ Module *M1 = 0;
+ Function *FooF1 = 0;
+ createModule1(Context1, M1, FooF1);
+
+ LLVMContext Context2;
+ Module *M2 = 0;
+ Function *FooF2 = 0;
+ createModule2(Context2, M2, FooF2);
+
+ // Now we create the JIT in lazy mode
+ OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ EE1->DisableLazyCompilation(false);
+ OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ EE2->DisableLazyCompilation(false);
+
+ // Call the `foo' function with no arguments:
+ std::vector<GenericValue> noargs;
+ GenericValue gv1 = EE1->runFunction(FooF1, noargs);
+ GenericValue gv2 = EE2->runFunction(FooF2, noargs);
+
+ // Import result of execution:
+ EXPECT_EQ(gv1.IntVal, 11);
+ EXPECT_EQ(gv2.IntVal, 12);
+
+ EE1->freeMachineCodeForFunction(FooF1);
+ EE2->freeMachineCodeForFunction(FooF2);
+}
+
+extern "C" {
+ extern void *getPointerToNamedFunction(const char *Name);
+}
+
+TEST(MultiJitTest, JitPool) {
+ LLVMContext Context1;
+ Module *M1 = 0;
+ Function *FooF1 = 0;
+ createModule1(Context1, M1, FooF1);
+
+ LLVMContext Context2;
+ Module *M2 = 0;
+ Function *FooF2 = 0;
+ createModule2(Context2, M2, FooF2);
+
+ // Now we create two JITs
+ OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+
+ Function *F1 = EE1->FindFunctionNamed("foo1");
+ void *foo1 = EE1->getPointerToFunction(F1);
+
+ Function *F2 = EE2->FindFunctionNamed("foo2");
+ void *foo2 = EE2->getPointerToFunction(F2);
+
+ // Function in M1
+ EXPECT_EQ(getPointerToNamedFunction("foo1"), foo1);
+
+ // Function in M2
+ EXPECT_EQ(getPointerToNamedFunction("foo2"), foo2);
+
+ // Symbol search
+ EXPECT_EQ((intptr_t)getPointerToNamedFunction("getPointerToNamedFunction"),
+ (intptr_t)&getPointerToNamedFunction);
+}
+
+} // anonymous namespace
diff --git a/unittests/Makefile.unittest b/unittests/Makefile.unittest
index e417435..6fbef54 100644
--- a/unittests/Makefile.unittest
+++ b/unittests/Makefile.unittest
@@ -14,6 +14,12 @@
# Set up variables for building a unit test.
ifdef TESTNAME
+CPP.Flags += -DGTEST_HAS_RTTI=0
+# gcc's TR1 <tuple> header depends on RTTI, so force googletest to use
+# its own tuple implementation. When we import googletest >=1.4.0, we
+# can drop this line.
+CPP.Flags += -DGTEST_HAS_TR1_TUPLE=0
+
include $(LEVEL)/Makefile.common
LLVMUnitTestExe = $(BuildMode)/$(TESTNAME)Tests$(EXEEXT)
diff --git a/unittests/Support/TypeBuilderTest.cpp b/unittests/Support/TypeBuilderTest.cpp
index a5c5e67..e805827 100644
--- a/unittests/Support/TypeBuilderTest.cpp
+++ b/unittests/Support/TypeBuilderTest.cpp
@@ -19,9 +19,16 @@ namespace {
TEST(TypeBuilderTest, Void) {
EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, true>::get(getGlobalContext())));
EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, false>::get(getGlobalContext())));
- // Special case for C compatibility:
+ // Special cases for C compatibility:
EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
(TypeBuilder<void*, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+ (TypeBuilder<const void*, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+ (TypeBuilder<volatile void*, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+ (TypeBuilder<const volatile void*, false>::get(
+ getGlobalContext())));
}
TEST(TypeBuilderTest, HostIntegers) {
diff --git a/unittests/VMCore/DerivedTypesTest.cpp b/unittests/VMCore/DerivedTypesTest.cpp
index 11b4dff..2e0450d 100644
--- a/unittests/VMCore/DerivedTypesTest.cpp
+++ b/unittests/VMCore/DerivedTypesTest.cpp
@@ -18,14 +18,16 @@ namespace {
TEST(OpaqueTypeTest, RegisterWithContext) {
LLVMContext C;
- LLVMContextImpl *pImpl = C.pImpl;
+ LLVMContextImpl *pImpl = C.pImpl;
- EXPECT_EQ(0u, pImpl->OpaqueTypes.size());
+ // 1 refers to the AlwaysOpaqueTy allocated in the Context's constructor and
+ // destroyed in the destructor.
+ EXPECT_EQ(1u, pImpl->OpaqueTypes.size());
{
PATypeHolder Type = OpaqueType::get(C);
- EXPECT_EQ(1u, pImpl->OpaqueTypes.size());
+ EXPECT_EQ(2u, pImpl->OpaqueTypes.size());
}
- EXPECT_EQ(0u, pImpl->OpaqueTypes.size());
+ EXPECT_EQ(1u, pImpl->OpaqueTypes.size());
}
} // namespace
diff --git a/unittests/VMCore/PassManagerTest.cpp b/unittests/VMCore/PassManagerTest.cpp
index 092ce3d..cb8f9eb 100644
--- a/unittests/VMCore/PassManagerTest.cpp
+++ b/unittests/VMCore/PassManagerTest.cpp
@@ -32,10 +32,6 @@
#include "llvm/Assembly/PrintModulePass.h"
#include "gtest/gtest.h"
-int dummy;
-
-#if 0
-
namespace llvm {
namespace {
// ND = no deps
@@ -529,4 +525,3 @@ namespace llvm {
}
}
-#endif
diff --git a/unittests/VMCore/VerifierTest.cpp b/unittests/VMCore/VerifierTest.cpp
new file mode 100644
index 0000000..c8838c5
--- /dev/null
+++ b/unittests/VMCore/VerifierTest.cpp
@@ -0,0 +1,44 @@
+//===- llvm/unittest/VMCore/VerifierTest.cpp - Verifier unit tests --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Analysis/Verifier.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+TEST(VerifierTest, Branch_i1) {
+ LLVMContext &C = getGlobalContext();
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
+ Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage);
+ BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
+ BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
+ ReturnInst::Create(C, Exit);
+
+ // To avoid triggering an assertion in BranchInst::Create, we first create
+ // a branch with an 'i1' condition ...
+
+ Constant *False = ConstantInt::getFalse(C);
+ BranchInst *BI = BranchInst::Create(Exit, Exit, False, Entry);
+
+ // ... then use setOperand to redirect it to a value of different type.
+
+ Constant *Zero32 = ConstantInt::get(IntegerType::get(C, 32), 0);
+ BI->setOperand(0, Zero32);
+
+ EXPECT_TRUE(verifyFunction(*F, ReturnStatusAction));
+}
+
+}
+}
diff --git a/utils/FileCheck/FileCheck.cpp b/utils/FileCheck/FileCheck.cpp
index 078028a..3c4742c 100644
--- a/utils/FileCheck/FileCheck.cpp
+++ b/utils/FileCheck/FileCheck.cpp
@@ -340,12 +340,10 @@ unsigned Pattern::ComputeMatchDistance(StringRef Buffer,
if (ExampleString.empty())
ExampleString = RegExStr;
- unsigned Distance = 0;
- for (unsigned i = 0, e = ExampleString.size(); i != e; ++i)
- if (Buffer.substr(i, 1) != ExampleString.substr(i, 1))
- ++Distance;
-
- return Distance;
+ // Only compare up to the first line in the buffer, or the string size.
+ StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
+ BufferPrefix = BufferPrefix.split('\n').first;
+ return BufferPrefix.edit_distance(ExampleString);
}
void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
@@ -383,10 +381,15 @@ void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
double BestQuality = 0;
// Use an arbitrary 4k limit on how far we will search.
- for (size_t i = 0, e = std::min(4096, int(Buffer.size())); i != e; ++i) {
+ for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
if (Buffer[i] == '\n')
++NumLinesForward;
+ // Patterns have leading whitespace stripped, so skip whitespace when
+ // looking for something which looks like a pattern.
+ if (Buffer[i] == ' ' || Buffer[i] == '\t')
+ continue;
+
// Compute the "quality" of this match as an arbitrary combination of the
// match distance and the number of lines skipped to get to this match.
unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
@@ -529,6 +532,9 @@ static bool ReadCheckFile(SourceMgr &SM,
// Scan ahead to the end of line.
size_t EOL = Buffer.find_first_of("\n\r");
+ // Remember the location of the start of the pattern, for diagnostics.
+ SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
+
// Parse the pattern.
Pattern P;
if (P.ParsePattern(Buffer.substr(0, EOL), SM))
@@ -555,7 +561,7 @@ static bool ReadCheckFile(SourceMgr &SM,
// Okay, add the string we captured to the output vector and move on.
CheckStrings.push_back(CheckString(P,
- SMLoc::getFromPointer(Buffer.data()),
+ PatternLoc,
IsCheckNext));
std::swap(NotMatches, CheckStrings.back().NotStrings);
}
diff --git a/utils/GenLibDeps.pl b/utils/GenLibDeps.pl
index 6d0b13e..b320a91 100755
--- a/utils/GenLibDeps.pl
+++ b/utils/GenLibDeps.pl
@@ -9,10 +9,12 @@
# Syntax: GenLibDeps.pl [-flat] <directory_with_libraries_in_it> [path_to_nm_binary]
#
use strict;
-
+use warnings;
# Parse arguments...
my $FLAT = 0;
my $WHY = 0;
+my $PEROBJ = 0;
+my $PEROBJINCL = 0;
while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) {
shift;
last if /^--$/; # Stop processing arguments on --
@@ -20,6 +22,8 @@ while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) {
# List command line options here...
if (/^-flat$/) { $FLAT = 1; next; }
if (/^-why/) { $WHY = 1; $FLAT = 1; next; }
+ if (/^-perobj$/) { $PEROBJ = 1; next; }
+ if (/^-perobjincl/) { $PEROBJINCL = 1; next;}
print "Unknown option: $_ : ignoring!\n";
}
@@ -47,6 +51,19 @@ if (!defined($nmPath) || $nmPath eq "") {
die "Can't find 'nm'" if (! -x "$nmPath");
}
+my $ranlibPath;
+if ($PEROBJ) {
+ $ranlibPath = $ARGV[2];
+ if (defined($ENV{RANLIB})) {
+ chomp($ranlibPath=$ENV{RANLIB});
+ }
+
+ if (!defined($ranlibPath) || $ranlibPath eq "") {
+ chomp($ranlibPath=`which ranlib`);
+ die "Can't find 'ranlib'" if (! -x "$ranlibPath");
+ }
+}
+
# Open the directory and read its contents, sorting by name and differentiating
# by whether its a library (.a) or an object file (.o)
opendir DIR,$Directory;
@@ -60,6 +77,93 @@ my @objs = grep(/LLVM.*\.o$/,sort(@files));
my %libdefs;
my %objdefs;
+my %libobjs;
+my %objdeps=();
+# Gather library definitions at object file granularity (optional)
+if ($PEROBJ) {
+ foreach my $lib (@libs ) {
+ `$ranlibPath $Directory/$lib`;
+ my $libpath = $lib;
+ $libpath =~ s/^libLLVM(.*)\.a/$1/;
+ $libpath =~ s/(.+)CodeGen$/Target\/$1/;
+ $libpath =~ s/(.+)AsmPrinter$/Target\/$1\/AsmPrinter/;
+ $libpath =~ s/(.+)AsmParser$/Target\/$1\/AsmParser/;
+ $libpath =~ s/(.+)Info$/Target\/$1\/TargetInfo/;
+ $libpath =~ s/(.+)Disassembler$/Target\/$1\/Disassembler/;
+ $libpath =~ s/SelectionDAG/CodeGen\/SelectionDAG/;
+ $libpath =~ s/^AsmPrinter/CodeGen\/AsmPrinter/;
+ $libpath =~ s/^BitReader/Bitcode\/Reader/;
+ $libpath =~ s/^BitWriter/Bitcode\/Writer/;
+ $libpath =~ s/^CBackend/Target\/CBackend/;
+ $libpath =~ s/^CppBackend/Target\/CppBackend/;
+ $libpath =~ s/^MSIL/Target\/MSIL/;
+ $libpath =~ s/^Core/VMCore/;
+ $libpath =~ s/^Instrumentation/Transforms\/Instrumentation/;
+ $libpath =~ s/^Interpreter/ExecutionEngine\/Interpreter/;
+ $libpath =~ s/^JIT/ExecutionEngine\/JIT/;
+ $libpath =~ s/^ScalarOpts/Transforms\/Scalar/;
+ $libpath =~ s/^TransformUtils/Transforms\/Utils/;
+ $libpath =~ s/^ipa/Analysis\/IPA/;
+ $libpath =~ s/^ipo/Transforms\/IPO/;
+ $libpath =~ s/^pic16passes/Target\/PIC16\/PIC16Passes/;
+ $libpath = "lib/".$libpath."/";
+ open DEFS, "$nmPath -sg $Directory/$lib|";
+ while (<DEFS>) {
+ chomp;
+ if (/^([^ ]*) in ([^ ]*)/) {
+ my $objfile = $libpath.$2;
+ $objdefs{$1} = $objfile;
+ $objdeps{$objfile} = {};
+ $libobjs{$lib}{$objfile}=1;
+# my $p = "../llvm/".$objfile;
+# $p =~ s/Support\/reg(.*).o/Support\/reg$1.c/;
+# $p =~ s/.o$/.cpp/;
+# unless (-e $p) {
+# die "$p\n"
+# }
+ }
+ }
+ close DEFS or die "nm failed";
+ }
+ foreach my $lib (@libs ) {
+ my $libpath = $lib;
+ $libpath =~ s/^libLLVM(.*)\.a/$1/;
+ $libpath =~ s/(.+)CodeGen$/Target\/$1/;
+ $libpath =~ s/(.+)AsmPrinter$/Target\/$1\/AsmPrinter/;
+ $libpath =~ s/(.+)AsmParser$/Target\/$1\/AsmParser/;
+ $libpath =~ s/(.+)Info$/Target\/$1\/TargetInfo/;
+ $libpath =~ s/(.+)Disassembler$/Target\/$1\/Disassembler/;
+ $libpath =~ s/SelectionDAG/CodeGen\/SelectionDAG/;
+ $libpath =~ s/^AsmPrinter/CodeGen\/AsmPrinter/;
+ $libpath =~ s/^BitReader/Bitcode\/Reader/;
+ $libpath =~ s/^BitWriter/Bitcode\/Writer/;
+ $libpath =~ s/^CBackend/Target\/CBackend/;
+ $libpath =~ s/^CppBackend/Target\/CppBackend/;
+ $libpath =~ s/^MSIL/Target\/MSIL/;
+ $libpath =~ s/^Core/VMCore/;
+ $libpath =~ s/^Instrumentation/Transforms\/Instrumentation/;
+ $libpath =~ s/^Interpreter/ExecutionEngine\/Interpreter/;
+ $libpath =~ s/^JIT/ExecutionEngine\/JIT/;
+ $libpath =~ s/^ScalarOpts/Transforms\/Scalar/;
+ $libpath =~ s/^TransformUtils/Transforms\/Utils/;
+ $libpath =~ s/^ipa/Analysis\/IPA/;
+ $libpath =~ s/^ipo/Transforms\/IPO/;
+ $libpath =~ s/^pic16passes/Target\/PIC16\/PIC16Passes/;
+ $libpath = "lib/".$libpath."/";
+ open UDEFS, "$nmPath -Aup $Directory/$lib|";
+ while (<UDEFS>) {
+ chomp;
+ if (/:([^:]+):/) {
+ my $obj = $libpath.$1;
+ s/[^ ]+: *U //;
+ if (defined($objdefs{$_})) {
+ $objdeps{$obj}{$objdefs{$_}}=1;
+ }
+ }
+ }
+ close UDEFS or die "nm failed"
+ }
+} else {
# Gather definitions from the libraries
foreach my $lib (@libs ) {
open DEFS, "$nmPath -g $Directory/$lib|";
@@ -72,6 +176,7 @@ foreach my $lib (@libs ) {
}
close DEFS or die "nm failed";
}
+}
# Gather definitions from the object files.
foreach my $obj (@objs ) {
@@ -109,6 +214,11 @@ sub gen_one_entry {
$DepLibs{$libdefs{$_}} = [] unless exists $DepLibs{$libdefs{$_}};
push(@{$DepLibs{$libdefs{$_}}}, $_);
} elsif (defined($objdefs{$_}) && $objdefs{$_} ne $lib) {
+ if ($PEROBJ && !$PEROBJINCL) {
+ # -perobjincl makes .a files depend on .o files they contain themselves
+ # default is don't depend on these.
+ next if defined $libobjs{$lib}{$objdefs{$_}};
+ }
my $libroot = $lib;
$libroot =~ s/lib(.*).a/$1/;
if ($objdefs{$_} ne "$libroot.o") {
@@ -144,6 +254,25 @@ sub gen_one_entry {
}
close UNDEFS or die "nm failed";
}
+ if ($PEROBJINCL) {
+ # include the .a's objects
+ for my $obj (keys %{$libobjs{$lib}}) {
+ $DepLibs{$obj} = ["<.a object>"] unless exists $DepLibs{$obj};
+ }
+ my $madechange = 1;
+ while($madechange) {
+ $madechange = 0;
+ my %temp = %DepLibs;
+ foreach my $obj (keys %DepLibs) {
+ foreach my $objdeps (keys %{$objdeps{$obj}}) {
+ next if defined $temp{$objdeps};
+ push(@{$temp{$objdeps}}, $obj);
+ $madechange = 1;
+ }
+ }
+ %DepLibs = %temp;
+ }
+ }
for my $key (sort keys %DepLibs) {
if ($FLAT) {
@@ -209,6 +338,18 @@ foreach my $lib (@libs) {
gen_one_entry($lib);
}
+if ($PEROBJ) {
+ foreach my $obj (keys %objdeps) {
+ print "$obj:";
+ if (!$PEROBJINCL) {
+ foreach my $dep (keys %{$objdeps{$obj}}) {
+ print " $dep";
+ }
+ }
+ print "\n";
+ }
+}
+
if (!$FLAT) {
print DOT "}\n";
close DOT;
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index ce1521d..b823e57 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -140,7 +140,7 @@ static std::string FlattenVariants(const std::string &AsmString,
}
/// TokenizeAsmString - Tokenize a simplified assembly string.
-static void TokenizeAsmString(const StringRef &AsmString,
+static void TokenizeAsmString(StringRef AsmString,
SmallVectorImpl<StringRef> &Tokens) {
unsigned Prev = 0;
bool InTok = true;
@@ -207,7 +207,7 @@ static void TokenizeAsmString(const StringRef &AsmString,
Tokens.push_back(AsmString.substr(Prev));
}
-static bool IsAssemblerInstruction(const StringRef &Name,
+static bool IsAssemblerInstruction(StringRef Name,
const CodeGenInstruction &CGI,
const SmallVectorImpl<StringRef> &Tokens) {
// Ignore "codegen only" instructions.
@@ -528,10 +528,10 @@ private:
private:
/// getTokenClass - Lookup or create the class for the given token.
- ClassInfo *getTokenClass(const StringRef &Token);
+ ClassInfo *getTokenClass(StringRef Token);
/// getOperandClass - Lookup or create the class for the given operand.
- ClassInfo *getOperandClass(const StringRef &Token,
+ ClassInfo *getOperandClass(StringRef Token,
const CodeGenInstruction::OperandInfo &OI);
/// BuildRegisterClasses - Build the ClassInfo* instances for register
@@ -581,7 +581,7 @@ void InstructionInfo::dump() {
}
}
-static std::string getEnumNameForToken(const StringRef &Str) {
+static std::string getEnumNameForToken(StringRef Str) {
std::string Res;
for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) {
@@ -603,7 +603,7 @@ static std::string getEnumNameForToken(const StringRef &Str) {
}
/// getRegisterRecord - Get the register record for \arg name, or 0.
-static Record *getRegisterRecord(CodeGenTarget &Target, const StringRef &Name) {
+static Record *getRegisterRecord(CodeGenTarget &Target, StringRef Name) {
for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) {
const CodeGenRegister &Reg = Target.getRegisters()[i];
if (Name == Reg.TheDef->getValueAsString("AsmName"))
@@ -613,7 +613,7 @@ static Record *getRegisterRecord(CodeGenTarget &Target, const StringRef &Name) {
return 0;
}
-ClassInfo *AsmMatcherInfo::getTokenClass(const StringRef &Token) {
+ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
ClassInfo *&Entry = TokenClasses[Token];
if (!Entry) {
@@ -631,7 +631,7 @@ ClassInfo *AsmMatcherInfo::getTokenClass(const StringRef &Token) {
}
ClassInfo *
-AsmMatcherInfo::getOperandClass(const StringRef &Token,
+AsmMatcherInfo::getOperandClass(StringRef Token,
const CodeGenInstruction::OperandInfo &OI) {
if (OI.Rec->isSubClassOf("RegisterClass")) {
ClassInfo *CI = RegisterClassClasses[OI.Rec];
@@ -782,10 +782,16 @@ void AsmMatcherInfo::BuildRegisterClasses(CodeGenTarget &Target,
void AsmMatcherInfo::BuildOperandClasses(CodeGenTarget &Target) {
std::vector<Record*> AsmOperands;
AsmOperands = Records.getAllDerivedDefinitions("AsmOperandClass");
+
+ // Pre-populate AsmOperandClasses map.
+ for (std::vector<Record*>::iterator it = AsmOperands.begin(),
+ ie = AsmOperands.end(); it != ie; ++it)
+ AsmOperandClasses[*it] = new ClassInfo();
+
unsigned Index = 0;
for (std::vector<Record*>::iterator it = AsmOperands.begin(),
ie = AsmOperands.end(); it != ie; ++it, ++Index) {
- ClassInfo *CI = new ClassInfo();
+ ClassInfo *CI = AsmOperandClasses[*it];
CI->Kind = ClassInfo::UserClass0 + Index;
Init *Super = (*it)->getValueInit("SuperClass");
@@ -938,10 +944,29 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
OperandName.str() + "'");
}
- const CodeGenInstruction::OperandInfo &OI = II->Instr->OperandList[Idx];
+ // FIXME: This is annoying, the named operand may be tied (e.g.,
+ // XCHG8rm). What we want is the untied operand, which we now have to
+ // grovel for. Only worry about this for single entry operands, we have to
+ // clean this up anyway.
+ const CodeGenInstruction::OperandInfo *OI = &II->Instr->OperandList[Idx];
+ if (OI->Constraints[0].isTied()) {
+ unsigned TiedOp = OI->Constraints[0].getTiedOperand();
+
+ // The tied operand index is an MIOperand index, find the operand that
+ // contains it.
+ for (unsigned i = 0, e = II->Instr->OperandList.size(); i != e; ++i) {
+ if (II->Instr->OperandList[i].MIOperandNo == TiedOp) {
+ OI = &II->Instr->OperandList[i];
+ break;
+ }
+ }
+
+ assert(OI && "Unable to find tied operand target!");
+ }
+
InstructionInfo::Operand Op;
- Op.Class = getOperandClass(Token, OI);
- Op.OperandInfo = &OI;
+ Op.Class = getOperandClass(Token, *OI);
+ Op.OperandInfo = OI;
II->Operands.push_back(Op);
}
}
@@ -950,6 +975,16 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
}
+static std::pair<unsigned, unsigned> *
+GetTiedOperandAtIndex(SmallVectorImpl<std::pair<unsigned, unsigned> > &List,
+ unsigned Index) {
+ for (unsigned i = 0, e = List.size(); i != e; ++i)
+ if (Index == List[i].first)
+ return &List[i];
+
+ return 0;
+}
+
static void EmitConvertToMCInst(CodeGenTarget &Target,
std::vector<InstructionInfo*> &Infos,
raw_ostream &OS) {
@@ -990,6 +1025,19 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
if (Op.OperandInfo)
MIOperandList.push_back(std::make_pair(Op.OperandInfo->MIOperandNo, i));
}
+
+ // Find any tied operands.
+ SmallVector<std::pair<unsigned, unsigned>, 4> TiedOperands;
+ for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) {
+ const CodeGenInstruction::OperandInfo &OpInfo = II.Instr->OperandList[i];
+ for (unsigned j = 0, e = OpInfo.Constraints.size(); j != e; ++j) {
+ const CodeGenInstruction::ConstraintInfo &CI = OpInfo.Constraints[j];
+ if (CI.isTied())
+ TiedOperands.push_back(std::make_pair(OpInfo.MIOperandNo + j,
+ CI.getTiedOperand()));
+ }
+ }
+
std::sort(MIOperandList.begin(), MIOperandList.end());
// Compute the total number of operands.
@@ -1008,14 +1056,20 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
assert(CurIndex <= Op.OperandInfo->MIOperandNo &&
"Duplicate match for instruction operand!");
- Signature += "_";
-
// Skip operands which weren't matched by anything, this occurs when the
// .td file encodes "implicit" operands as explicit ones.
//
// FIXME: This should be removed from the MCInst structure.
- for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex)
- Signature += "Imp";
+ for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
+ std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+ CurIndex);
+ if (!Tie)
+ Signature += "__Imp";
+ else
+ Signature += "__Tie" + utostr(Tie->second);
+ }
+
+ Signature += "__";
// Registers are always converted the same, don't duplicate the conversion
// function based on them.
@@ -1033,8 +1087,14 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
}
// Add any trailing implicit operands.
- for (; CurIndex != NumMIOperands; ++CurIndex)
- Signature += "Imp";
+ for (; CurIndex != NumMIOperands; ++CurIndex) {
+ std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+ CurIndex);
+ if (!Tie)
+ Signature += "__Imp";
+ else
+ Signature += "__Tie" + utostr(Tie->second);
+ }
II.ConversionFnKind = Signature;
@@ -1054,8 +1114,22 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second];
// Add the implicit operands.
- for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex)
- CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
+ for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
+ // See if this is a tied operand.
+ std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+ CurIndex);
+
+ if (!Tie) {
+ // If not, this is some implicit operand. Just assume it is a register
+ // for now.
+ CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
+ } else {
+ // Copy the tied operand.
+ assert(Tie->first>Tie->second && "Tied operand preceeds its target!");
+ CvtOS << " Inst.addOperand(Inst.getOperand("
+ << Tie->second << "));\n";
+ }
+ }
CvtOS << " ((" << TargetOperandClass << "*)Operands["
<< MIOperandList[i].second
@@ -1065,8 +1139,22 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
}
// And add trailing implicit operands.
- for (; CurIndex != NumMIOperands; ++CurIndex)
- CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
+ for (; CurIndex != NumMIOperands; ++CurIndex) {
+ std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
+ CurIndex);
+
+ if (!Tie) {
+ // If not, this is some implicit operand. Just assume it is a register
+ // for now.
+ CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
+ } else {
+ // Copy the tied operand.
+ assert(Tie->first>Tie->second && "Tied operand preceeds its target!");
+ CvtOS << " Inst.addOperand(Inst.getOperand("
+ << Tie->second << "));\n";
+ }
+ }
+
CvtOS << " break;\n";
}
@@ -1367,7 +1455,7 @@ static void EmitMatchTokenString(CodeGenTarget &Target,
Matches.push_back(StringPair(CI.ValueName, "return " + CI.Name + ";"));
}
- OS << "static MatchClassKind MatchTokenString(const StringRef &Name) {\n";
+ OS << "static MatchClassKind MatchTokenString(StringRef Name) {\n";
EmitStringMatcher("Name", Matches, OS);
@@ -1390,7 +1478,7 @@ static void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
"return " + utostr(i + 1) + ";"));
}
- OS << "static unsigned MatchRegisterName(const StringRef &Name) {\n";
+ OS << "static unsigned MatchRegisterName(StringRef Name) {\n";
EmitStringMatcher("Name", Matches, OS);
@@ -1407,9 +1495,11 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
AsmMatcherInfo Info(AsmParser);
Info.BuildInfo(Target);
- // Sort the instruction table using the partial order on classes.
- std::sort(Info.Instructions.begin(), Info.Instructions.end(),
- less_ptr<InstructionInfo>());
+ // Sort the instruction table using the partial order on classes. We use
+ // stable_sort to ensure that ambiguous instructions are still
+ // deterministically ordered.
+ std::stable_sort(Info.Instructions.begin(), Info.Instructions.end(),
+ less_ptr<InstructionInfo>());
DEBUG_WITH_TYPE("instruction_info", {
for (std::vector<InstructionInfo*>::iterator
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index ff83c76..3a38dd4 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -13,339 +13,15 @@
//===----------------------------------------------------------------------===//
#include "AsmWriterEmitter.h"
+#include "AsmWriterInst.h"
#include "CodeGenTarget.h"
#include "Record.h"
#include "StringToOffsetTable.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
using namespace llvm;
-
-static bool isIdentChar(char C) {
- return (C >= 'a' && C <= 'z') ||
- (C >= 'A' && C <= 'Z') ||
- (C >= '0' && C <= '9') ||
- C == '_';
-}
-
-// This should be an anon namespace, this works around a GCC warning.
-namespace llvm {
- struct AsmWriterOperand {
- enum OpType {
- // Output this text surrounded by quotes to the asm.
- isLiteralTextOperand,
- // This is the name of a routine to call to print the operand.
- isMachineInstrOperand,
- // Output this text verbatim to the asm writer. It is code that
- // will output some text to the asm.
- isLiteralStatementOperand
- } OperandType;
-
- /// Str - For isLiteralTextOperand, this IS the literal text. For
- /// isMachineInstrOperand, this is the PrinterMethodName for the operand..
- /// For isLiteralStatementOperand, this is the code to insert verbatim
- /// into the asm writer.
- std::string Str;
-
- /// MiOpNo - For isMachineInstrOperand, this is the operand number of the
- /// machine instruction.
- unsigned MIOpNo;
-
- /// MiModifier - For isMachineInstrOperand, this is the modifier string for
- /// an operand, specified with syntax like ${opname:modifier}.
- std::string MiModifier;
-
- // To make VS STL happy
- AsmWriterOperand(OpType op = isLiteralTextOperand):OperandType(op) {}
-
- AsmWriterOperand(const std::string &LitStr,
- OpType op = isLiteralTextOperand)
- : OperandType(op), Str(LitStr) {}
-
- AsmWriterOperand(const std::string &Printer, unsigned OpNo,
- const std::string &Modifier,
- OpType op = isMachineInstrOperand)
- : OperandType(op), Str(Printer), MIOpNo(OpNo),
- MiModifier(Modifier) {}
-
- bool operator!=(const AsmWriterOperand &Other) const {
- if (OperandType != Other.OperandType || Str != Other.Str) return true;
- if (OperandType == isMachineInstrOperand)
- return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier;
- return false;
- }
- bool operator==(const AsmWriterOperand &Other) const {
- return !operator!=(Other);
- }
-
- /// getCode - Return the code that prints this operand.
- std::string getCode() const;
- };
-}
-
-namespace llvm {
- class AsmWriterInst {
- public:
- std::vector<AsmWriterOperand> Operands;
- const CodeGenInstruction *CGI;
-
- AsmWriterInst(const CodeGenInstruction &CGI, Record *AsmWriter);
-
- /// MatchesAllButOneOp - If this instruction is exactly identical to the
- /// specified instruction except for one differing operand, return the
- /// differing operand number. Otherwise return ~0.
- unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const;
-
- private:
- void AddLiteralString(const std::string &Str) {
- // If the last operand was already a literal text string, append this to
- // it, otherwise add a new operand.
- if (!Operands.empty() &&
- Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand)
- Operands.back().Str.append(Str);
- else
- Operands.push_back(AsmWriterOperand(Str));
- }
- };
-}
-
-
-std::string AsmWriterOperand::getCode() const {
- if (OperandType == isLiteralTextOperand) {
- if (Str.size() == 1)
- return "O << '" + Str + "'; ";
- return "O << \"" + Str + "\"; ";
- }
-
- if (OperandType == isLiteralStatementOperand)
- return Str;
-
- std::string Result = Str + "(MI";
- if (MIOpNo != ~0U)
- Result += ", " + utostr(MIOpNo);
- if (!MiModifier.empty())
- Result += ", \"" + MiModifier + '"';
- return Result + "); ";
-}
-
-
-/// ParseAsmString - Parse the specified Instruction's AsmString into this
-/// AsmWriterInst.
-///
-AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, Record *AsmWriter) {
- this->CGI = &CGI;
-
- unsigned Variant = AsmWriter->getValueAsInt("Variant");
- int FirstOperandColumn = AsmWriter->getValueAsInt("FirstOperandColumn");
- int OperandSpacing = AsmWriter->getValueAsInt("OperandSpacing");
-
- unsigned CurVariant = ~0U; // ~0 if we are outside a {.|.|.} region, other #.
-
- // This is the number of tabs we've seen if we're doing columnar layout.
- unsigned CurColumn = 0;
-
-
- // NOTE: Any extensions to this code need to be mirrored in the
- // AsmPrinter::printInlineAsm code that executes as compile time (assuming
- // that inline asm strings should also get the new feature)!
- const std::string &AsmString = CGI.AsmString;
- std::string::size_type LastEmitted = 0;
- while (LastEmitted != AsmString.size()) {
- std::string::size_type DollarPos =
- AsmString.find_first_of("${|}\\", LastEmitted);
- if (DollarPos == std::string::npos) DollarPos = AsmString.size();
-
- // Emit a constant string fragment.
-
- if (DollarPos != LastEmitted) {
- if (CurVariant == Variant || CurVariant == ~0U) {
- for (; LastEmitted != DollarPos; ++LastEmitted)
- switch (AsmString[LastEmitted]) {
- case '\n':
- AddLiteralString("\\n");
- break;
- case '\t':
- // If the asm writer is not using a columnar layout, \t is not
- // magic.
- if (FirstOperandColumn == -1 || OperandSpacing == -1) {
- AddLiteralString("\\t");
- } else {
- // We recognize a tab as an operand delimeter.
- unsigned DestColumn = FirstOperandColumn +
- CurColumn++ * OperandSpacing;
- Operands.push_back(
- AsmWriterOperand("O.PadToColumn(" +
- utostr(DestColumn) + ");\n",
- AsmWriterOperand::isLiteralStatementOperand));
- }
- break;
- case '"':
- AddLiteralString("\\\"");
- break;
- case '\\':
- AddLiteralString("\\\\");
- break;
- default:
- AddLiteralString(std::string(1, AsmString[LastEmitted]));
- break;
- }
- } else {
- LastEmitted = DollarPos;
- }
- } else if (AsmString[DollarPos] == '\\') {
- if (DollarPos+1 != AsmString.size() &&
- (CurVariant == Variant || CurVariant == ~0U)) {
- if (AsmString[DollarPos+1] == 'n') {
- AddLiteralString("\\n");
- } else if (AsmString[DollarPos+1] == 't') {
- // If the asm writer is not using a columnar layout, \t is not
- // magic.
- if (FirstOperandColumn == -1 || OperandSpacing == -1) {
- AddLiteralString("\\t");
- break;
- }
-
- // We recognize a tab as an operand delimeter.
- unsigned DestColumn = FirstOperandColumn +
- CurColumn++ * OperandSpacing;
- Operands.push_back(
- AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ");\n",
- AsmWriterOperand::isLiteralStatementOperand));
- break;
- } else if (std::string("${|}\\").find(AsmString[DollarPos+1])
- != std::string::npos) {
- AddLiteralString(std::string(1, AsmString[DollarPos+1]));
- } else {
- throw "Non-supported escaped character found in instruction '" +
- CGI.TheDef->getName() + "'!";
- }
- LastEmitted = DollarPos+2;
- continue;
- }
- } else if (AsmString[DollarPos] == '{') {
- if (CurVariant != ~0U)
- throw "Nested variants found for instruction '" +
- CGI.TheDef->getName() + "'!";
- LastEmitted = DollarPos+1;
- CurVariant = 0; // We are now inside of the variant!
- } else if (AsmString[DollarPos] == '|') {
- if (CurVariant == ~0U)
- throw "'|' character found outside of a variant in instruction '"
- + CGI.TheDef->getName() + "'!";
- ++CurVariant;
- ++LastEmitted;
- } else if (AsmString[DollarPos] == '}') {
- if (CurVariant == ~0U)
- throw "'}' character found outside of a variant in instruction '"
- + CGI.TheDef->getName() + "'!";
- ++LastEmitted;
- CurVariant = ~0U;
- } else if (DollarPos+1 != AsmString.size() &&
- AsmString[DollarPos+1] == '$') {
- if (CurVariant == Variant || CurVariant == ~0U) {
- AddLiteralString("$"); // "$$" -> $
- }
- LastEmitted = DollarPos+2;
- } else {
- // Get the name of the variable.
- std::string::size_type VarEnd = DollarPos+1;
-
- // handle ${foo}bar as $foo by detecting whether the character following
- // the dollar sign is a curly brace. If so, advance VarEnd and DollarPos
- // so the variable name does not contain the leading curly brace.
- bool hasCurlyBraces = false;
- if (VarEnd < AsmString.size() && '{' == AsmString[VarEnd]) {
- hasCurlyBraces = true;
- ++DollarPos;
- ++VarEnd;
- }
-
- while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
- ++VarEnd;
- std::string VarName(AsmString.begin()+DollarPos+1,
- AsmString.begin()+VarEnd);
-
- // Modifier - Support ${foo:modifier} syntax, where "modifier" is passed
- // into printOperand. Also support ${:feature}, which is passed into
- // PrintSpecial.
- std::string Modifier;
-
- // In order to avoid starting the next string at the terminating curly
- // brace, advance the end position past it if we found an opening curly
- // brace.
- if (hasCurlyBraces) {
- if (VarEnd >= AsmString.size())
- throw "Reached end of string before terminating curly brace in '"
- + CGI.TheDef->getName() + "'";
-
- // Look for a modifier string.
- if (AsmString[VarEnd] == ':') {
- ++VarEnd;
- if (VarEnd >= AsmString.size())
- throw "Reached end of string before terminating curly brace in '"
- + CGI.TheDef->getName() + "'";
-
- unsigned ModifierStart = VarEnd;
- while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
- ++VarEnd;
- Modifier = std::string(AsmString.begin()+ModifierStart,
- AsmString.begin()+VarEnd);
- if (Modifier.empty())
- throw "Bad operand modifier name in '"+ CGI.TheDef->getName() + "'";
- }
-
- if (AsmString[VarEnd] != '}')
- throw "Variable name beginning with '{' did not end with '}' in '"
- + CGI.TheDef->getName() + "'";
- ++VarEnd;
- }
- if (VarName.empty() && Modifier.empty())
- throw "Stray '$' in '" + CGI.TheDef->getName() +
- "' asm string, maybe you want $$?";
-
- if (VarName.empty()) {
- // Just a modifier, pass this into PrintSpecial.
- Operands.push_back(AsmWriterOperand("PrintSpecial", ~0U, Modifier));
- } else {
- // Otherwise, normal operand.
- unsigned OpNo = CGI.getOperandNamed(VarName);
- CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
-
- if (CurVariant == Variant || CurVariant == ~0U) {
- unsigned MIOp = OpInfo.MIOperandNo;
- Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp,
- Modifier));
- }
- }
- LastEmitted = VarEnd;
- }
- }
-
- Operands.push_back(AsmWriterOperand("return;",
- AsmWriterOperand::isLiteralStatementOperand));
-}
-
-/// MatchesAllButOneOp - If this instruction is exactly identical to the
-/// specified instruction except for one differing operand, return the differing
-/// operand number. If more than one operand mismatches, return ~1, otherwise
-/// if the instructions are identical return ~0.
-unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{
- if (Operands.size() != Other.Operands.size()) return ~1;
-
- unsigned MismatchOperand = ~0U;
- for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
- if (Operands[i] != Other.Operands[i]) {
- if (MismatchOperand != ~0U) // Already have one mismatch?
- return ~1U;
- else
- MismatchOperand = i;
- }
- }
- return MismatchOperand;
-}
-
static void PrintCases(std::vector<std::pair<std::string,
AsmWriterOperand> > &OpsToPrint, raw_ostream &O) {
O << " case " << OpsToPrint.back().first << ": ";
@@ -580,7 +256,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
E = Target.inst_end(); I != E; ++I)
if (!I->second.AsmString.empty() &&
I->second.TheDef->getName() != "PHI")
- Instructions.push_back(AsmWriterInst(I->second, AsmWriter));
+ Instructions.push_back(
+ AsmWriterInst(I->second,
+ AsmWriter->getValueAsInt("Variant"),
+ AsmWriter->getValueAsInt("FirstOperandColumn"),
+ AsmWriter->getValueAsInt("OperandSpacing")));
// Get the instruction numbering.
Target.getInstructionsByEnumValue(NumberedInstructions);
@@ -692,24 +372,6 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
StringTable.EmitString(O);
O << ";\n\n";
- O << "\n#ifndef NO_ASM_WRITER_BOILERPLATE\n";
-
- O << " if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {\n"
- << " printInlineAsm(MI);\n"
- << " return;\n"
- << " } else if (MI->isLabel()) {\n"
- << " printLabel(MI);\n"
- << " return;\n"
- << " } else if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {\n"
- << " printImplicitDef(MI);\n"
- << " return;\n"
- << " } else if (MI->getOpcode() == TargetInstrInfo::KILL) {\n"
- << " printKill(MI);\n"
- << " return;\n"
- << " }\n\n";
-
- O << "\n#endif\n";
-
O << " O << \"\\t\";\n\n";
O << " // Emit the opcode for the instruction.\n"
@@ -832,11 +494,55 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
<< "}\n";
}
+void AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) {
+ CodeGenTarget Target;
+ Record *AsmWriter = Target.getAsmWriter();
+ std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+
+ std::vector<const CodeGenInstruction*> NumberedInstructions;
+ Target.getInstructionsByEnumValue(NumberedInstructions);
+
+ StringToOffsetTable StringTable;
+ O <<
+"\n\n#ifdef GET_INSTRUCTION_NAME\n"
+"#undef GET_INSTRUCTION_NAME\n\n"
+"/// getInstructionName: This method is automatically generated by tblgen\n"
+"/// from the instruction set description. This returns the enum name of the\n"
+"/// specified instruction.\n"
+ "const char *" << Target.getName() << ClassName
+ << "::getInstructionName(unsigned Opcode) {\n"
+ << " assert(Opcode < " << NumberedInstructions.size()
+ << " && \"Invalid instruction number!\");\n"
+ << "\n"
+ << " static const unsigned InstAsmOffset[] = {";
+ for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+ const CodeGenInstruction &Inst = *NumberedInstructions[i];
+
+ std::string AsmName = Inst.TheDef->getName();
+ if ((i % 14) == 0)
+ O << "\n ";
+
+ O << StringTable.GetOrAddStringOffset(AsmName) << ", ";
+ }
+ O << "0\n"
+ << " };\n"
+ << "\n";
+
+ O << " const char *Strs =\n";
+ StringTable.EmitString(O);
+ O << ";\n";
+
+ O << " return Strs+InstAsmOffset[Opcode];\n"
+ << "}\n\n#endif\n";
+}
+
+
void AsmWriterEmitter::run(raw_ostream &O) {
EmitSourceFileHeader("Assembly Writer Source Fragment", O);
EmitPrintInstruction(O);
EmitGetRegisterName(O);
+ EmitGetInstructionName(O);
}
diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h
index 7862caa..9f7d776 100644
--- a/utils/TableGen/AsmWriterEmitter.h
+++ b/utils/TableGen/AsmWriterEmitter.h
@@ -37,6 +37,7 @@ namespace llvm {
private:
void EmitPrintInstruction(raw_ostream &o);
void EmitGetRegisterName(raw_ostream &o);
+ void EmitGetInstructionName(raw_ostream &o);
AsmWriterInst *getAsmWriterInstByID(unsigned ID) const {
assert(ID < NumberedInstructions.size());
diff --git a/utils/TableGen/AsmWriterInst.cpp b/utils/TableGen/AsmWriterInst.cpp
new file mode 100644
index 0000000..508e453
--- /dev/null
+++ b/utils/TableGen/AsmWriterInst.cpp
@@ -0,0 +1,264 @@
+//===- AsmWriterInst.h - Classes encapsulating a printable inst -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes implement a parser for assembly strings.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AsmWriterInst.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace llvm;
+
+static bool isIdentChar(char C) {
+ return (C >= 'a' && C <= 'z') ||
+ (C >= 'A' && C <= 'Z') ||
+ (C >= '0' && C <= '9') ||
+ C == '_';
+}
+
+std::string AsmWriterOperand::getCode() const {
+ if (OperandType == isLiteralTextOperand) {
+ if (Str.size() == 1)
+ return "O << '" + Str + "'; ";
+ return "O << \"" + Str + "\"; ";
+ }
+
+ if (OperandType == isLiteralStatementOperand)
+ return Str;
+
+ std::string Result = Str + "(MI";
+ if (MIOpNo != ~0U)
+ Result += ", " + utostr(MIOpNo);
+ if (!MiModifier.empty())
+ Result += ", \"" + MiModifier + '"';
+ return Result + "); ";
+}
+
+/// ParseAsmString - Parse the specified Instruction's AsmString into this
+/// AsmWriterInst.
+///
+AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
+ unsigned Variant,
+ int FirstOperandColumn,
+ int OperandSpacing) {
+ this->CGI = &CGI;
+
+ unsigned CurVariant = ~0U; // ~0 if we are outside a {.|.|.} region, other #.
+
+ // This is the number of tabs we've seen if we're doing columnar layout.
+ unsigned CurColumn = 0;
+
+
+ // NOTE: Any extensions to this code need to be mirrored in the
+ // AsmPrinter::printInlineAsm code that executes as compile time (assuming
+ // that inline asm strings should also get the new feature)!
+ const std::string &AsmString = CGI.AsmString;
+ std::string::size_type LastEmitted = 0;
+ while (LastEmitted != AsmString.size()) {
+ std::string::size_type DollarPos =
+ AsmString.find_first_of("${|}\\", LastEmitted);
+ if (DollarPos == std::string::npos) DollarPos = AsmString.size();
+
+ // Emit a constant string fragment.
+
+ if (DollarPos != LastEmitted) {
+ if (CurVariant == Variant || CurVariant == ~0U) {
+ for (; LastEmitted != DollarPos; ++LastEmitted)
+ switch (AsmString[LastEmitted]) {
+ case '\n':
+ AddLiteralString("\\n");
+ break;
+ case '\t':
+ // If the asm writer is not using a columnar layout, \t is not
+ // magic.
+ if (FirstOperandColumn == -1 || OperandSpacing == -1) {
+ AddLiteralString("\\t");
+ } else {
+ // We recognize a tab as an operand delimeter.
+ unsigned DestColumn = FirstOperandColumn +
+ CurColumn++ * OperandSpacing;
+ Operands.push_back(
+ AsmWriterOperand(
+ "O.PadToColumn(" +
+ utostr(DestColumn) + ");\n",
+ AsmWriterOperand::isLiteralStatementOperand));
+ }
+ break;
+ case '"':
+ AddLiteralString("\\\"");
+ break;
+ case '\\':
+ AddLiteralString("\\\\");
+ break;
+ default:
+ AddLiteralString(std::string(1, AsmString[LastEmitted]));
+ break;
+ }
+ } else {
+ LastEmitted = DollarPos;
+ }
+ } else if (AsmString[DollarPos] == '\\') {
+ if (DollarPos+1 != AsmString.size() &&
+ (CurVariant == Variant || CurVariant == ~0U)) {
+ if (AsmString[DollarPos+1] == 'n') {
+ AddLiteralString("\\n");
+ } else if (AsmString[DollarPos+1] == 't') {
+ // If the asm writer is not using a columnar layout, \t is not
+ // magic.
+ if (FirstOperandColumn == -1 || OperandSpacing == -1) {
+ AddLiteralString("\\t");
+ break;
+ }
+
+ // We recognize a tab as an operand delimeter.
+ unsigned DestColumn = FirstOperandColumn +
+ CurColumn++ * OperandSpacing;
+ Operands.push_back(
+ AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ");\n",
+ AsmWriterOperand::isLiteralStatementOperand));
+ break;
+ } else if (std::string("${|}\\").find(AsmString[DollarPos+1])
+ != std::string::npos) {
+ AddLiteralString(std::string(1, AsmString[DollarPos+1]));
+ } else {
+ throw "Non-supported escaped character found in instruction '" +
+ CGI.TheDef->getName() + "'!";
+ }
+ LastEmitted = DollarPos+2;
+ continue;
+ }
+ } else if (AsmString[DollarPos] == '{') {
+ if (CurVariant != ~0U)
+ throw "Nested variants found for instruction '" +
+ CGI.TheDef->getName() + "'!";
+ LastEmitted = DollarPos+1;
+ CurVariant = 0; // We are now inside of the variant!
+ } else if (AsmString[DollarPos] == '|') {
+ if (CurVariant == ~0U)
+ throw "'|' character found outside of a variant in instruction '"
+ + CGI.TheDef->getName() + "'!";
+ ++CurVariant;
+ ++LastEmitted;
+ } else if (AsmString[DollarPos] == '}') {
+ if (CurVariant == ~0U)
+ throw "'}' character found outside of a variant in instruction '"
+ + CGI.TheDef->getName() + "'!";
+ ++LastEmitted;
+ CurVariant = ~0U;
+ } else if (DollarPos+1 != AsmString.size() &&
+ AsmString[DollarPos+1] == '$') {
+ if (CurVariant == Variant || CurVariant == ~0U) {
+ AddLiteralString("$"); // "$$" -> $
+ }
+ LastEmitted = DollarPos+2;
+ } else {
+ // Get the name of the variable.
+ std::string::size_type VarEnd = DollarPos+1;
+
+ // handle ${foo}bar as $foo by detecting whether the character following
+ // the dollar sign is a curly brace. If so, advance VarEnd and DollarPos
+ // so the variable name does not contain the leading curly brace.
+ bool hasCurlyBraces = false;
+ if (VarEnd < AsmString.size() && '{' == AsmString[VarEnd]) {
+ hasCurlyBraces = true;
+ ++DollarPos;
+ ++VarEnd;
+ }
+
+ while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
+ ++VarEnd;
+ std::string VarName(AsmString.begin()+DollarPos+1,
+ AsmString.begin()+VarEnd);
+
+ // Modifier - Support ${foo:modifier} syntax, where "modifier" is passed
+ // into printOperand. Also support ${:feature}, which is passed into
+ // PrintSpecial.
+ std::string Modifier;
+
+ // In order to avoid starting the next string at the terminating curly
+ // brace, advance the end position past it if we found an opening curly
+ // brace.
+ if (hasCurlyBraces) {
+ if (VarEnd >= AsmString.size())
+ throw "Reached end of string before terminating curly brace in '"
+ + CGI.TheDef->getName() + "'";
+
+ // Look for a modifier string.
+ if (AsmString[VarEnd] == ':') {
+ ++VarEnd;
+ if (VarEnd >= AsmString.size())
+ throw "Reached end of string before terminating curly brace in '"
+ + CGI.TheDef->getName() + "'";
+
+ unsigned ModifierStart = VarEnd;
+ while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
+ ++VarEnd;
+ Modifier = std::string(AsmString.begin()+ModifierStart,
+ AsmString.begin()+VarEnd);
+ if (Modifier.empty())
+ throw "Bad operand modifier name in '"+ CGI.TheDef->getName() + "'";
+ }
+
+ if (AsmString[VarEnd] != '}')
+ throw "Variable name beginning with '{' did not end with '}' in '"
+ + CGI.TheDef->getName() + "'";
+ ++VarEnd;
+ }
+ if (VarName.empty() && Modifier.empty())
+ throw "Stray '$' in '" + CGI.TheDef->getName() +
+ "' asm string, maybe you want $$?";
+
+ if (VarName.empty()) {
+ // Just a modifier, pass this into PrintSpecial.
+ Operands.push_back(AsmWriterOperand("PrintSpecial",
+ ~0U,
+ ~0U,
+ Modifier));
+ } else {
+ // Otherwise, normal operand.
+ unsigned OpNo = CGI.getOperandNamed(VarName);
+ CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
+
+ if (CurVariant == Variant || CurVariant == ~0U) {
+ unsigned MIOp = OpInfo.MIOperandNo;
+ Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName,
+ OpNo,
+ MIOp,
+ Modifier));
+ }
+ }
+ LastEmitted = VarEnd;
+ }
+ }
+
+ Operands.push_back(AsmWriterOperand("return;",
+ AsmWriterOperand::isLiteralStatementOperand));
+}
+
+/// MatchesAllButOneOp - If this instruction is exactly identical to the
+/// specified instruction except for one differing operand, return the differing
+/// operand number. If more than one operand mismatches, return ~1, otherwise
+/// if the instructions are identical return ~0.
+unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{
+ if (Operands.size() != Other.Operands.size()) return ~1;
+
+ unsigned MismatchOperand = ~0U;
+ for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+ if (Operands[i] != Other.Operands[i]) {
+ if (MismatchOperand != ~0U) // Already have one mismatch?
+ return ~1U;
+ else
+ MismatchOperand = i;
+ }
+ }
+ return MismatchOperand;
+}
diff --git a/utils/TableGen/AsmWriterInst.h b/utils/TableGen/AsmWriterInst.h
new file mode 100644
index 0000000..20b8588
--- /dev/null
+++ b/utils/TableGen/AsmWriterInst.h
@@ -0,0 +1,113 @@
+//===- AsmWriterInst.h - Classes encapsulating a printable inst -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes implement a parser for assembly strings. The parser splits
+// the string into operands, which can be literal strings (the constant bits of
+// the string), actual operands (i.e., operands from the MachineInstr), and
+// dynamically-generated text, specified by raw C++ code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASMWRITER_INST_H
+#define ASMWRITER_INST_H
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+ class CodeGenInstruction;
+ class Record;
+
+ struct AsmWriterOperand {
+ enum OpType {
+ // Output this text surrounded by quotes to the asm.
+ isLiteralTextOperand,
+ // This is the name of a routine to call to print the operand.
+ isMachineInstrOperand,
+ // Output this text verbatim to the asm writer. It is code that
+ // will output some text to the asm.
+ isLiteralStatementOperand
+ } OperandType;
+
+ /// Str - For isLiteralTextOperand, this IS the literal text. For
+ /// isMachineInstrOperand, this is the PrinterMethodName for the operand..
+ /// For isLiteralStatementOperand, this is the code to insert verbatim
+ /// into the asm writer.
+ std::string Str;
+
+ /// CGIOpNo - For isMachineInstrOperand, this is the index of the operand in
+ /// the CodeGenInstruction.
+ unsigned CGIOpNo;
+
+ /// MiOpNo - For isMachineInstrOperand, this is the operand number of the
+ /// machine instruction.
+ unsigned MIOpNo;
+
+ /// MiModifier - For isMachineInstrOperand, this is the modifier string for
+ /// an operand, specified with syntax like ${opname:modifier}.
+ std::string MiModifier;
+
+ // To make VS STL happy
+ AsmWriterOperand(OpType op = isLiteralTextOperand):OperandType(op) {}
+
+ AsmWriterOperand(const std::string &LitStr,
+ OpType op = isLiteralTextOperand)
+ : OperandType(op), Str(LitStr) {}
+
+ AsmWriterOperand(const std::string &Printer,
+ unsigned _CGIOpNo,
+ unsigned _MIOpNo,
+ const std::string &Modifier,
+ OpType op = isMachineInstrOperand)
+ : OperandType(op), Str(Printer), CGIOpNo(_CGIOpNo), MIOpNo(_MIOpNo),
+ MiModifier(Modifier) {}
+
+ bool operator!=(const AsmWriterOperand &Other) const {
+ if (OperandType != Other.OperandType || Str != Other.Str) return true;
+ if (OperandType == isMachineInstrOperand)
+ return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier;
+ return false;
+ }
+ bool operator==(const AsmWriterOperand &Other) const {
+ return !operator!=(Other);
+ }
+
+ /// getCode - Return the code that prints this operand.
+ std::string getCode() const;
+ };
+
+ class AsmWriterInst {
+ public:
+ std::vector<AsmWriterOperand> Operands;
+ const CodeGenInstruction *CGI;
+
+ AsmWriterInst(const CodeGenInstruction &CGI,
+ unsigned Variant,
+ int FirstOperandColumn,
+ int OperandSpacing);
+
+ /// MatchesAllButOneOp - If this instruction is exactly identical to the
+ /// specified instruction except for one differing operand, return the
+ /// differing operand number. Otherwise return ~0.
+ unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const;
+
+ private:
+ void AddLiteralString(const std::string &Str) {
+ // If the last operand was already a literal text string, append this to
+ // it, otherwise add a new operand.
+ if (!Operands.empty() &&
+ Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand)
+ Operands.back().Str.append(Str);
+ else
+ Operands.push_back(AsmWriterOperand(Str));
+ }
+ };
+}
+
+#endif
diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt
index ce9b66f..a2678a2 100644
--- a/utils/TableGen/CMakeLists.txt
+++ b/utils/TableGen/CMakeLists.txt
@@ -1,6 +1,7 @@
add_executable(tblgen
AsmMatcherEmitter.cpp
AsmWriterEmitter.cpp
+ AsmWriterInst.cpp
CallingConvEmitter.cpp
ClangDiagnosticsEmitter.cpp
CodeEmitterGen.cpp
@@ -8,7 +9,11 @@ add_executable(tblgen
CodeGenInstruction.cpp
CodeGenTarget.cpp
DAGISelEmitter.cpp
+ DAGISelMatcherEmitter.cpp
+ DAGISelMatcherGen.cpp
+ DAGISelMatcher.cpp
DisassemblerEmitter.cpp
+ EDEmitter.cpp
FastISelEmitter.cpp
InstrEnumEmitter.cpp
InstrInfoEmitter.cpp
diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp
index 714a39c..f1857f5 100644
--- a/utils/TableGen/CodeEmitterGen.cpp
+++ b/utils/TableGen/CodeEmitterGen.cpp
@@ -35,7 +35,7 @@ void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) {
R->getName() == "IMPLICIT_DEF" ||
R->getName() == "SUBREG_TO_REG" ||
R->getName() == "COPY_TO_REGCLASS" ||
- R->getName() == "DEBUG_VALUE") continue;
+ R->getName() == "DBG_VALUE") continue;
BitsInit *BI = R->getValueAsBitsInit("Inst");
@@ -113,7 +113,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
R->getName() == "IMPLICIT_DEF" ||
R->getName() == "SUBREG_TO_REG" ||
R->getName() == "COPY_TO_REGCLASS" ||
- R->getName() == "DEBUG_VALUE") {
+ R->getName() == "DBG_VALUE") {
o << " 0U,\n";
continue;
}
@@ -152,7 +152,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
InstName == "IMPLICIT_DEF" ||
InstName == "SUBREG_TO_REG" ||
InstName == "COPY_TO_REGCLASS" ||
- InstName == "DEBUG_VALUE") continue;
+ InstName == "DBG_VALUE") continue;
BitsInit *BI = R->getValueAsBitsInit("Inst");
const std::vector<RecordVal> &Vals = R->getValues();
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index cf79365..94d3534 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -674,6 +674,15 @@ TreePatternNode *TreePatternNode::clone() const {
return New;
}
+/// RemoveAllTypes - Recursively strip all the types of this tree.
+void TreePatternNode::RemoveAllTypes() {
+ removeTypes();
+ if (isLeaf()) return;
+ for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+ getChild(i)->RemoveAllTypes();
+}
+
+
/// SubstituteFormalArguments - Replace the formal arguments in this tree
/// with actual values specified by ArgMap.
void TreePatternNode::
@@ -768,7 +777,7 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
/// references from the register file information, for example.
///
static std::vector<unsigned char> getImplicitType(Record *R, bool NotRegisters,
- TreePattern &TP) {
+ TreePattern &TP) {
// Some common return values
std::vector<unsigned char> Unknown(1, EEVT::isUnknown);
std::vector<unsigned char> Other(1, MVT::Other);
@@ -825,6 +834,48 @@ getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const {
return &CDP.getIntrinsicInfo(IID);
}
+/// getComplexPatternInfo - If this node corresponds to a ComplexPattern,
+/// return the ComplexPattern information, otherwise return null.
+const ComplexPattern *
+TreePatternNode::getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const {
+ if (!isLeaf()) return 0;
+
+ DefInit *DI = dynamic_cast<DefInit*>(getLeafValue());
+ if (DI && DI->getDef()->isSubClassOf("ComplexPattern"))
+ return &CGP.getComplexPattern(DI->getDef());
+ return 0;
+}
+
+/// NodeHasProperty - Return true if this node has the specified property.
+bool TreePatternNode::NodeHasProperty(SDNP Property,
+ const CodeGenDAGPatterns &CGP) const {
+ if (isLeaf()) {
+ if (const ComplexPattern *CP = getComplexPatternInfo(CGP))
+ return CP->hasProperty(Property);
+ return false;
+ }
+
+ Record *Operator = getOperator();
+ if (!Operator->isSubClassOf("SDNode")) return false;
+
+ return CGP.getSDNodeInfo(Operator).hasProperty(Property);
+}
+
+
+
+
+/// TreeHasProperty - Return true if any node in this tree has the specified
+/// property.
+bool TreePatternNode::TreeHasProperty(SDNP Property,
+ const CodeGenDAGPatterns &CGP) const {
+ if (NodeHasProperty(Property, CGP))
+ return true;
+ for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+ if (getChild(i)->TreeHasProperty(Property, CGP))
+ return true;
+ return false;
+}
+
/// isCommutativeIntrinsic - Return true if the node corresponds to a
/// commutative intrinsic.
bool
@@ -845,7 +896,9 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
if (DefInit *DI = dynamic_cast<DefInit*>(getLeafValue())) {
// If it's a regclass or something else known, include the type.
return UpdateNodeType(getImplicitType(DI->getDef(), NotRegisters, TP),TP);
- } else if (IntInit *II = dynamic_cast<IntInit*>(getLeafValue())) {
+ }
+
+ if (IntInit *II = dynamic_cast<IntInit*>(getLeafValue())) {
// Int inits are always integers. :)
bool MadeChange = UpdateNodeType(MVT::iAny, TP);
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index c51232a..f1f7bca 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -216,8 +216,15 @@ public:
void setChild(unsigned i, TreePatternNode *N) {
Children[i] = N;
}
+
+ /// hasChild - Return true if N is any of our children.
+ bool hasChild(const TreePatternNode *N) const {
+ for (unsigned i = 0, e = Children.size(); i != e; ++i)
+ if (Children[i] == N) return true;
+ return false;
+ }
- const std::vector<std::string> &getPredicateFns() const { return PredicateFns; }
+ const std::vector<std::string> &getPredicateFns() const {return PredicateFns;}
void clearPredicateFns() { PredicateFns.clear(); }
void setPredicateFns(const std::vector<std::string> &Fns) {
assert(PredicateFns.empty() && "Overwriting non-empty predicate list!");
@@ -237,6 +244,18 @@ public:
/// CodeGenIntrinsic information for it, otherwise return a null pointer.
const CodeGenIntrinsic *getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const;
+ /// getComplexPatternInfo - If this node corresponds to a ComplexPattern,
+ /// return the ComplexPattern information, otherwise return null.
+ const ComplexPattern *
+ getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const;
+
+ /// NodeHasProperty - Return true if this node has the specified property.
+ bool NodeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
+
+ /// TreeHasProperty - Return true if any node in this tree has the specified
+ /// property.
+ bool TreeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
+
/// isCommutativeIntrinsic - Return true if the node is an intrinsic which is
/// marked isCommutative.
bool isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const;
@@ -249,6 +268,9 @@ public: // Higher level manipulation routines.
/// clone - Return a new copy of this tree.
///
TreePatternNode *clone() const;
+
+ /// RemoveAllTypes - Recursively strip all the types of this tree.
+ void RemoveAllTypes();
/// isIsomorphicTo - Return true if this node is recursively isomorphic to
/// the specified node. For this comparison, all of the state of the node
@@ -298,6 +320,11 @@ public: // Higher level manipulation routines.
bool canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP);
};
+inline raw_ostream &operator<<(raw_ostream &OS, const TreePatternNode &TPN) {
+ TPN.print(OS);
+ return OS;
+}
+
/// TreePattern - Represent a pattern, used for instructions, pattern
/// fragments, etc.
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index 684431a..d31502b 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -33,10 +33,10 @@ static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
I->ParseOperandName(Name, false);
// Build the string for the operand
- std::string OpConstraint = "(1 << TOI::EARLY_CLOBBER)";
- if (!I->OperandList[Op.first].Constraints[Op.second].empty())
+ if (!I->OperandList[Op.first].Constraints[Op.second].isNone())
throw "Operand '" + Name + "' cannot have multiple constraints!";
- I->OperandList[Op.first].Constraints[Op.second] = OpConstraint;
+ I->OperandList[Op.first].Constraints[Op.second] =
+ CodeGenInstruction::ConstraintInfo::getEarlyClobber();
return;
}
@@ -65,13 +65,11 @@ static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp);
- // Build the string for the operand.
- std::string OpConstraint =
- "((" + utostr(FlatOpNo) + " << 16) | (1 << TOI::TIED_TO))";
- if (!I->OperandList[DestOp.first].Constraints[DestOp.second].empty())
+ if (!I->OperandList[DestOp.first].Constraints[DestOp.second].isNone())
throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
- I->OperandList[DestOp.first].Constraints[DestOp.second] = OpConstraint;
+ I->OperandList[DestOp.first].Constraints[DestOp.second] =
+ CodeGenInstruction::ConstraintInfo::getTied(FlatOpNo);
}
static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) {
@@ -210,18 +208,13 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
// For backward compatibility: isTwoAddress means operand 1 is tied to
// operand 0.
if (isTwoAddress) {
- if (!OperandList[1].Constraints[0].empty())
+ if (!OperandList[1].Constraints[0].isNone())
throw R->getName() + ": cannot use isTwoAddress property: instruction "
"already has constraint set!";
- OperandList[1].Constraints[0] = "((0 << 16) | (1 << TOI::TIED_TO))";
+ OperandList[1].Constraints[0] =
+ CodeGenInstruction::ConstraintInfo::getTied(0);
}
- // Any operands with unset constraints get 0 as their constraint.
- for (unsigned op = 0, e = OperandList.size(); op != e; ++op)
- for (unsigned j = 0, e = OperandList[op].MINumOperands; j != e; ++j)
- if (OperandList[op].Constraints[j].empty())
- OperandList[op].Constraints[j] = "0";
-
// Parse the DisableEncoding field.
std::string DisableEncoding = R->getValueAsString("DisableEncoding");
while (1) {
diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h
index d22ac3e..285da14 100644
--- a/utils/TableGen/CodeGenInstruction.h
+++ b/utils/TableGen/CodeGenInstruction.h
@@ -32,6 +32,36 @@ namespace llvm {
/// instruction.
std::string AsmString;
+ class ConstraintInfo {
+ enum { None, EarlyClobber, Tied } Kind;
+ unsigned OtherTiedOperand;
+ public:
+ ConstraintInfo() : Kind(None) {}
+
+ static ConstraintInfo getEarlyClobber() {
+ ConstraintInfo I;
+ I.Kind = EarlyClobber;
+ I.OtherTiedOperand = 0;
+ return I;
+ }
+
+ static ConstraintInfo getTied(unsigned Op) {
+ ConstraintInfo I;
+ I.Kind = Tied;
+ I.OtherTiedOperand = Op;
+ return I;
+ }
+
+ bool isNone() const { return Kind == None; }
+ bool isEarlyClobber() const { return Kind == EarlyClobber; }
+ bool isTied() const { return Kind == Tied; }
+
+ unsigned getTiedOperand() const {
+ assert(isTied());
+ return OtherTiedOperand;
+ }
+ };
+
/// OperandInfo - The information we keep track of for each operand in the
/// operand list for a tablegen instruction.
struct OperandInfo {
@@ -67,7 +97,7 @@ namespace llvm {
/// Constraint info for this operand. This operand can have pieces, so we
/// track constraint info for each.
- std::vector<std::string> Constraints;
+ std::vector<ConstraintInfo> Constraints;
OperandInfo(Record *R, const std::string &N, const std::string &PMN,
unsigned MION, unsigned MINO, DagInit *MIOI)
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index c9af5f7..2688091 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -337,10 +337,10 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*>
throw "Could not find 'COPY_TO_REGCLASS' instruction!";
const CodeGenInstruction *COPY_TO_REGCLASS = &I->second;
- I = getInstructions().find("DEBUG_VALUE");
+ I = getInstructions().find("DBG_VALUE");
if (I == Instructions.end())
- throw "Could not find 'DEBUG_VALUE' instruction!";
- const CodeGenInstruction *DEBUG_VALUE = &I->second;
+ throw "Could not find 'DBG_VALUE' instruction!";
+ const CodeGenInstruction *DBG_VALUE = &I->second;
// Print out the rest of the instructions now.
NumberedInstructions.push_back(PHI);
@@ -354,7 +354,7 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*>
NumberedInstructions.push_back(IMPLICIT_DEF);
NumberedInstructions.push_back(SUBREG_TO_REG);
NumberedInstructions.push_back(COPY_TO_REGCLASS);
- NumberedInstructions.push_back(DEBUG_VALUE);
+ NumberedInstructions.push_back(DBG_VALUE);
for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II)
if (&II->second != PHI &&
&II->second != INLINEASM &&
@@ -367,7 +367,7 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*>
&II->second != IMPLICIT_DEF &&
&II->second != SUBREG_TO_REG &&
&II->second != COPY_TO_REGCLASS &&
- &II->second != DEBUG_VALUE)
+ &II->second != DBG_VALUE)
NumberedInstructions.push_back(&II->second);
}
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index c97582b..f0cebed 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "DAGISelEmitter.h"
+#include "DAGISelMatcher.h"
#include "Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
@@ -55,19 +56,6 @@ static bool NodeIsComplexPattern(TreePatternNode *N) {
isSubClassOf("ComplexPattern"));
}
-/// NodeGetComplexPattern - return the pointer to the ComplexPattern if N
-/// is a leaf node and a subclass of ComplexPattern, else it returns NULL.
-static const ComplexPattern *NodeGetComplexPattern(TreePatternNode *N,
- CodeGenDAGPatterns &CGP) {
- if (N->isLeaf() &&
- dynamic_cast<DefInit*>(N->getLeafValue()) &&
- static_cast<DefInit*>(N->getLeafValue())->getDef()->
- isSubClassOf("ComplexPattern")) {
- return &CGP.getComplexPattern(static_cast<DefInit*>(N->getLeafValue())
- ->getDef());
- }
- return NULL;
-}
/// getPatternSize - Return the 'size' of this pattern. We want to match large
/// patterns before small ones. This is used to determine the size of a
@@ -91,7 +79,7 @@ static unsigned getPatternSize(TreePatternNode *P, CodeGenDAGPatterns &CGP) {
// Later we can allow complexity / cost for each pattern to be (optionally)
// specified. To get best possible pattern match we'll need to dynamically
// calculate the complexity of all patterns a dag can potentially map to.
- const ComplexPattern *AM = NodeGetComplexPattern(P, CGP);
+ const ComplexPattern *AM = P->getComplexPatternInfo(CGP);
if (AM)
Size += AM->getNumOperands() * 3;
@@ -217,68 +205,10 @@ static MVT::SimpleValueType getRegisterValueType(Record *R, const CodeGenTarget
return VT;
}
-
-/// RemoveAllTypes - A quick recursive walk over a pattern which removes all
-/// type information from it.
-static void RemoveAllTypes(TreePatternNode *N) {
- N->removeTypes();
- if (!N->isLeaf())
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
- RemoveAllTypes(N->getChild(i));
-}
-
-/// NodeHasProperty - return true if TreePatternNode has the specified
-/// property.
-static bool NodeHasProperty(TreePatternNode *N, SDNP Property,
- CodeGenDAGPatterns &CGP) {
- if (N->isLeaf()) {
- const ComplexPattern *CP = NodeGetComplexPattern(N, CGP);
- if (CP)
- return CP->hasProperty(Property);
- return false;
- }
- Record *Operator = N->getOperator();
- if (!Operator->isSubClassOf("SDNode")) return false;
-
- return CGP.getSDNodeInfo(Operator).hasProperty(Property);
-}
-
-static bool PatternHasProperty(TreePatternNode *N, SDNP Property,
- CodeGenDAGPatterns &CGP) {
- if (NodeHasProperty(N, Property, CGP))
- return true;
-
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
- TreePatternNode *Child = N->getChild(i);
- if (PatternHasProperty(Child, Property, CGP))
- return true;
- }
-
- return false;
-}
-
static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
return CGP.getSDNodeInfo(Op).getEnumName();
}
-static
-bool DisablePatternForFastISel(TreePatternNode *N, CodeGenDAGPatterns &CGP) {
- bool isStore = !N->isLeaf() &&
- getOpcodeName(N->getOperator(), CGP) == "ISD::STORE";
- if (!isStore && NodeHasProperty(N, SDNPHasChain, CGP))
- return false;
-
- bool HasChain = false;
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
- TreePatternNode *Child = N->getChild(i);
- if (PatternHasProperty(Child, SDNPHasChain, CGP)) {
- HasChain = true;
- break;
- }
- }
- return HasChain;
-}
-
//===----------------------------------------------------------------------===//
// Node Transformation emitter implementation.
//
@@ -340,14 +270,14 @@ void DAGISelEmitter::EmitPredicateFunctions(raw_ostream &OS) {
if (P->getOnlyTree()->isLeaf())
OS << "inline bool Predicate_" << PatFragRecord->getName()
- << "(SDNode *N) {\n";
+ << "(SDNode *N) const {\n";
else {
std::string ClassName =
CGP.getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName();
const char *C2 = ClassName == "SDNode" ? "N" : "inN";
OS << "inline bool Predicate_" << PatFragRecord->getName()
- << "(SDNode *" << C2 << ") {\n";
+ << "(SDNode *" << C2 << ") const {\n";
if (ClassName != "SDNode")
OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n";
}
@@ -463,760 +393,860 @@ public:
/// matches, and the SDNode for the result has the RootName specified name.
void EmitMatchCode(TreePatternNode *N, TreePatternNode *P,
const std::string &RootName, const std::string &ChainSuffix,
- bool &FoundChain) {
-
- // Save loads/stores matched by a pattern.
- if (!N->isLeaf() && N->getName().empty()) {
- if (NodeHasProperty(N, SDNPMemOperand, CGP))
- LSI.push_back(getNodeName(RootName));
- }
-
- bool isRoot = (P == NULL);
- // Emit instruction predicates. Each predicate is just a string for now.
- if (isRoot) {
- // Record input varargs info.
- NumInputRootOps = N->getNumChildren();
+ bool &FoundChain);
- if (DisablePatternForFastISel(N, CGP))
- emitCheck("OptLevel != CodeGenOpt::None");
+ void EmitChildMatchCode(TreePatternNode *Child, TreePatternNode *Parent,
+ const std::string &RootName,
+ const std::string &ChainSuffix, bool &FoundChain);
- emitCheck(PredicateCheck);
- }
+ /// EmitResultCode - Emit the action for a pattern. Now that it has matched
+ /// we actually have to build a DAG!
+ std::vector<std::string>
+ EmitResultCode(TreePatternNode *N, std::vector<Record*> DstRegs,
+ bool InFlagDecled, bool ResNodeDecled,
+ bool LikeLeaf = false, bool isRoot = false);
- if (N->isLeaf()) {
- if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
- emitCheck("cast<ConstantSDNode>(" + getNodeName(RootName) +
- ")->getSExtValue() == INT64_C(" +
- itostr(II->getValue()) + ")");
- return;
- } else if (!NodeIsComplexPattern(N)) {
- assert(0 && "Cannot match this as a leaf value!");
- abort();
- }
+ /// InsertOneTypeCheck - Insert a type-check for an unresolved type in 'Pat'
+ /// and add it to the tree. 'Pat' and 'Other' are isomorphic trees except that
+ /// 'Pat' may be missing types. If we find an unresolved type to add a check
+ /// for, this returns true otherwise false if Pat has all types.
+ bool InsertOneTypeCheck(TreePatternNode *Pat, TreePatternNode *Other,
+ const std::string &Prefix, bool isRoot = false) {
+ // Did we find one?
+ if (Pat->getExtTypes() != Other->getExtTypes()) {
+ // Move a type over from 'other' to 'pat'.
+ Pat->setTypes(Other->getExtTypes());
+ // The top level node type is checked outside of the select function.
+ if (!isRoot)
+ emitCheck(Prefix + ".getValueType() == " +
+ getName(Pat->getTypeNum(0)));
+ return true;
}
- // If this node has a name associated with it, capture it in VariableMap. If
- // we already saw this in the pattern, emit code to verify dagness.
- if (!N->getName().empty()) {
- std::string &VarMapEntry = VariableMap[N->getName()];
- if (VarMapEntry.empty()) {
- VarMapEntry = RootName;
- } else {
- // If we get here, this is a second reference to a specific name. Since
- // we already have checked that the first reference is valid, we don't
- // have to recursively match it, just check that it's the same as the
- // previously named thing.
- emitCheck(VarMapEntry + " == " + RootName);
- return;
- }
-
- if (!N->isLeaf())
- OperatorMap[N->getName()] = N->getOperator();
- }
-
+ unsigned OpNo = (unsigned)Pat->NodeHasProperty(SDNPHasChain, CGP);
+ for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i, ++OpNo)
+ if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i),
+ Prefix + utostr(OpNo)))
+ return true;
+ return false;
+ }
- // Emit code to load the child nodes and match their contents recursively.
- unsigned OpNo = 0;
- bool NodeHasChain = NodeHasProperty (N, SDNPHasChain, CGP);
- bool HasChain = PatternHasProperty(N, SDNPHasChain, CGP);
- bool EmittedUseCheck = false;
- if (HasChain) {
- if (NodeHasChain)
- OpNo = 1;
- if (!isRoot) {
- // Multiple uses of actual result?
- emitCheck(getValueName(RootName) + ".hasOneUse()");
- EmittedUseCheck = true;
- if (NodeHasChain) {
- // If the immediate use can somehow reach this node through another
- // path, then can't fold it either or it will create a cycle.
- // e.g. In the following diagram, XX can reach ld through YY. If
- // ld is folded into XX, then YY is both a predecessor and a successor
- // of XX.
- //
- // [ld]
- // ^ ^
- // | |
- // / \---
- // / [YY]
- // | ^
- // [XX]-------|
- bool NeedCheck = P != Pattern;
- if (!NeedCheck) {
- const SDNodeInfo &PInfo = CGP.getSDNodeInfo(P->getOperator());
- NeedCheck =
- P->getOperator() == CGP.get_intrinsic_void_sdnode() ||
- P->getOperator() == CGP.get_intrinsic_w_chain_sdnode() ||
- P->getOperator() == CGP.get_intrinsic_wo_chain_sdnode() ||
- PInfo.getNumOperands() > 1 ||
- PInfo.hasProperty(SDNPHasChain) ||
- PInfo.hasProperty(SDNPInFlag) ||
- PInfo.hasProperty(SDNPOptInFlag);
+private:
+ /// EmitInFlagSelectCode - Emit the flag operands for the DAG that is
+ /// being built.
+ void EmitInFlagSelectCode(TreePatternNode *N, const std::string &RootName,
+ bool &ChainEmitted, bool &InFlagDecled,
+ bool &ResNodeDecled, bool isRoot = false) {
+ const CodeGenTarget &T = CGP.getTargetInfo();
+ unsigned OpNo = (unsigned)N->NodeHasProperty(SDNPHasChain, CGP);
+ bool HasInFlag = N->NodeHasProperty(SDNPInFlag, CGP);
+ for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
+ TreePatternNode *Child = N->getChild(i);
+ if (!Child->isLeaf()) {
+ EmitInFlagSelectCode(Child, RootName + utostr(OpNo), ChainEmitted,
+ InFlagDecled, ResNodeDecled);
+ } else {
+ if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
+ if (!Child->getName().empty()) {
+ std::string Name = RootName + utostr(OpNo);
+ if (Duplicates.find(Name) != Duplicates.end())
+ // A duplicate! Do not emit a copy for this node.
+ continue;
}
- if (NeedCheck) {
- std::string ParentName(RootName.begin(), RootName.end()-1);
- emitCheck("IsLegalAndProfitableToFold(" + getNodeName(RootName) +
- ", " + getNodeName(ParentName) + ", N)");
+ Record *RR = DI->getDef();
+ if (RR->isSubClassOf("Register")) {
+ MVT::SimpleValueType RVT = getRegisterValueType(RR, T);
+ if (RVT == MVT::Flag) {
+ if (!InFlagDecled) {
+ emitCode("SDValue InFlag = " +
+ getValueName(RootName + utostr(OpNo)) + ";");
+ InFlagDecled = true;
+ } else
+ emitCode("InFlag = " +
+ getValueName(RootName + utostr(OpNo)) + ";");
+ } else {
+ if (!ChainEmitted) {
+ emitCode("SDValue Chain = CurDAG->getEntryNode();");
+ ChainName = "Chain";
+ ChainEmitted = true;
+ }
+ if (!InFlagDecled) {
+ emitCode("SDValue InFlag(0, 0);");
+ InFlagDecled = true;
+ }
+ std::string Decl = (!ResNodeDecled) ? "SDNode *" : "";
+ emitCode(Decl + "ResNode = CurDAG->getCopyToReg(" + ChainName +
+ ", " + getNodeName(RootName) + "->getDebugLoc()" +
+ ", " + getQualifiedName(RR) +
+ ", " + getValueName(RootName + utostr(OpNo)) +
+ ", InFlag).getNode();");
+ ResNodeDecled = true;
+ emitCode(ChainName + " = SDValue(ResNode, 0);");
+ emitCode("InFlag = SDValue(ResNode, 1);");
+ }
}
}
}
-
- if (NodeHasChain) {
- if (FoundChain) {
- emitCheck("(" + ChainName + ".getNode() == " +
- getNodeName(RootName) + " || "
- "IsChainCompatible(" + ChainName + ".getNode(), " +
- getNodeName(RootName) + "))");
- OrigChains.push_back(std::make_pair(ChainName,
- getValueName(RootName)));
- } else
- FoundChain = true;
- ChainName = "Chain" + ChainSuffix;
- emitInit("SDValue " + ChainName + " = " + getNodeName(RootName) +
- "->getOperand(0);");
- }
}
- // Don't fold any node which reads or writes a flag and has multiple uses.
- // FIXME: We really need to separate the concepts of flag and "glue". Those
- // real flag results, e.g. X86CMP output, can have multiple uses.
- // FIXME: If the optional incoming flag does not exist. Then it is ok to
- // fold it.
- if (!isRoot &&
- (PatternHasProperty(N, SDNPInFlag, CGP) ||
- PatternHasProperty(N, SDNPOptInFlag, CGP) ||
- PatternHasProperty(N, SDNPOutFlag, CGP))) {
- if (!EmittedUseCheck) {
- // Multiple uses of actual result?
- emitCheck(getValueName(RootName) + ".hasOneUse()");
- }
+ if (HasInFlag) {
+ if (!InFlagDecled) {
+ emitCode("SDValue InFlag = " + getNodeName(RootName) +
+ "->getOperand(" + utostr(OpNo) + ");");
+ InFlagDecled = true;
+ } else
+ emitCode("InFlag = " + getNodeName(RootName) +
+ "->getOperand(" + utostr(OpNo) + ");");
}
+ }
+};
+
- // If there are node predicates for this, emit the calls.
- for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
- emitCheck(N->getPredicateFns()[i] + "(" + getNodeName(RootName) + ")");
-
- // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
- // a constant without a predicate fn that has more that one bit set, handle
- // this as a special case. This is usually for targets that have special
- // handling of certain large constants (e.g. alpha with it's 8/16/32-bit
- // handling stuff). Using these instructions is often far more efficient
- // than materializing the constant. Unfortunately, both the instcombiner
- // and the dag combiner can often infer that bits are dead, and thus drop
- // them from the mask in the dag. For example, it might turn 'AND X, 255'
- // into 'AND X, 254' if it knows the low bit is set. Emit code that checks
- // to handle this.
- if (!N->isLeaf() &&
- (N->getOperator()->getName() == "and" ||
- N->getOperator()->getName() == "or") &&
- N->getChild(1)->isLeaf() &&
- N->getChild(1)->getPredicateFns().empty()) {
- if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
- if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits.
- emitInit("SDValue " + RootName + "0" + " = " +
- getNodeName(RootName) + "->getOperand(" + utostr(0) + ");");
- emitInit("SDValue " + RootName + "1" + " = " +
- getNodeName(RootName) + "->getOperand(" + utostr(1) + ");");
-
- unsigned NTmp = TmpNo++;
- emitCode("ConstantSDNode *Tmp" + utostr(NTmp) +
- " = dyn_cast<ConstantSDNode>(" +
- getNodeName(RootName + "1") + ");");
- emitCheck("Tmp" + utostr(NTmp));
- const char *MaskPredicate = N->getOperator()->getName() == "or"
- ? "CheckOrMask(" : "CheckAndMask(";
- emitCheck(MaskPredicate + getValueName(RootName + "0") +
- ", Tmp" + utostr(NTmp) +
- ", INT64_C(" + itostr(II->getValue()) + "))");
-
- EmitChildMatchCode(N->getChild(0), N, RootName + utostr(0),
- ChainSuffix + utostr(0), FoundChain);
- return;
+/// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
+/// if the match fails. At this point, we already know that the opcode for N
+/// matches, and the SDNode for the result has the RootName specified name.
+void PatternCodeEmitter::EmitMatchCode(TreePatternNode *N, TreePatternNode *P,
+ const std::string &RootName,
+ const std::string &ChainSuffix,
+ bool &FoundChain) {
+
+ // Save loads/stores matched by a pattern.
+ if (!N->isLeaf() && N->getName().empty()) {
+ if (N->NodeHasProperty(SDNPMemOperand, CGP))
+ LSI.push_back(getNodeName(RootName));
+ }
+
+ bool isRoot = (P == NULL);
+ // Emit instruction predicates. Each predicate is just a string for now.
+ if (isRoot) {
+ // Record input varargs info.
+ NumInputRootOps = N->getNumChildren();
+ emitCheck(PredicateCheck);
+ }
+
+ if (N->isLeaf()) {
+ if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
+ emitCheck("cast<ConstantSDNode>(" + getNodeName(RootName) +
+ ")->getSExtValue() == INT64_C(" +
+ itostr(II->getValue()) + ")");
+ return;
+ } else if (!NodeIsComplexPattern(N)) {
+ assert(0 && "Cannot match this as a leaf value!");
+ abort();
+ }
+ }
+
+ // If this node has a name associated with it, capture it in VariableMap. If
+ // we already saw this in the pattern, emit code to verify dagness.
+ if (!N->getName().empty()) {
+ std::string &VarMapEntry = VariableMap[N->getName()];
+ if (VarMapEntry.empty()) {
+ VarMapEntry = RootName;
+ } else {
+ // If we get here, this is a second reference to a specific name. Since
+ // we already have checked that the first reference is valid, we don't
+ // have to recursively match it, just check that it's the same as the
+ // previously named thing.
+ emitCheck(VarMapEntry + " == " + RootName);
+ return;
+ }
+
+ if (!N->isLeaf())
+ OperatorMap[N->getName()] = N->getOperator();
+ }
+
+
+ // Emit code to load the child nodes and match their contents recursively.
+ unsigned OpNo = 0;
+ bool NodeHasChain = N->NodeHasProperty(SDNPHasChain, CGP);
+ bool HasChain = N->TreeHasProperty(SDNPHasChain, CGP);
+ if (HasChain) {
+ if (NodeHasChain)
+ OpNo = 1;
+ if (!isRoot) {
+ // Check if it's profitable to fold the node. e.g. Check for multiple uses
+ // of actual result?
+ std::string ParentName(RootName.begin(), RootName.end()-1);
+ emitCheck("IsProfitableToFold(" + getValueName(RootName) +
+ ", " + getNodeName(ParentName) + ", N)");
+ if (NodeHasChain) {
+ // If the immediate use can somehow reach this node through another
+ // path, then can't fold it either or it will create a cycle.
+ // e.g. In the following diagram, XX can reach ld through YY. If
+ // ld is folded into XX, then YY is both a predecessor and a successor
+ // of XX.
+ //
+ // [ld]
+ // ^ ^
+ // | |
+ // / \---
+ // / [YY]
+ // | ^
+ // [XX]-------|
+
+ // We know we need the check if N's parent is not the root.
+ bool NeedCheck = P != Pattern;
+ if (!NeedCheck) {
+ const SDNodeInfo &PInfo = CGP.getSDNodeInfo(P->getOperator());
+ NeedCheck =
+ P->getOperator() == CGP.get_intrinsic_void_sdnode() ||
+ P->getOperator() == CGP.get_intrinsic_w_chain_sdnode() ||
+ P->getOperator() == CGP.get_intrinsic_wo_chain_sdnode() ||
+ PInfo.getNumOperands() > 1 ||
+ PInfo.hasProperty(SDNPHasChain) ||
+ PInfo.hasProperty(SDNPInFlag) ||
+ PInfo.hasProperty(SDNPOptInFlag);
+ }
+
+ if (NeedCheck) {
+ emitCheck("IsLegalToFold(" + getValueName(RootName) +
+ ", " + getNodeName(ParentName) + ", N)");
}
}
}
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
- emitInit("SDValue " + getValueName(RootName + utostr(OpNo)) + " = " +
- getNodeName(RootName) + "->getOperand(" + utostr(OpNo) + ");");
-
- EmitChildMatchCode(N->getChild(i), N, RootName + utostr(OpNo),
- ChainSuffix + utostr(OpNo), FoundChain);
+ if (NodeHasChain) {
+ if (FoundChain) {
+ emitCheck("(" + ChainName + ".getNode() == " +
+ getNodeName(RootName) + " || "
+ "IsChainCompatible(" + ChainName + ".getNode(), " +
+ getNodeName(RootName) + "))");
+ OrigChains.push_back(std::make_pair(ChainName,
+ getValueName(RootName)));
+ } else
+ FoundChain = true;
+ ChainName = "Chain" + ChainSuffix;
+ emitInit("SDValue " + ChainName + " = " + getNodeName(RootName) +
+ "->getOperand(0);");
}
-
- // Handle cases when root is a complex pattern.
- const ComplexPattern *CP;
- if (isRoot && N->isLeaf() && (CP = NodeGetComplexPattern(N, CGP))) {
- std::string Fn = CP->getSelectFunc();
- unsigned NumOps = CP->getNumOperands();
- for (unsigned i = 0; i < NumOps; ++i) {
- emitDecl("CPTmp" + RootName + "_" + utostr(i));
- emitCode("SDValue CPTmp" + RootName + "_" + utostr(i) + ";");
- }
- if (CP->hasProperty(SDNPHasChain)) {
- emitDecl("CPInChain");
- emitDecl("Chain" + ChainSuffix);
- emitCode("SDValue CPInChain;");
- emitCode("SDValue Chain" + ChainSuffix + ";");
- }
-
- std::string Code = Fn + "(" +
- getNodeName(RootName) + ", " +
- getValueName(RootName);
- for (unsigned i = 0; i < NumOps; i++)
- Code += ", CPTmp" + RootName + "_" + utostr(i);
- if (CP->hasProperty(SDNPHasChain)) {
- ChainName = "Chain" + ChainSuffix;
- Code += ", CPInChain, Chain" + ChainSuffix;
+ }
+
+ // If there are node predicates for this, emit the calls.
+ for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
+ emitCheck(N->getPredicateFns()[i] + "(" + getNodeName(RootName) + ")");
+
+ // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
+ // a constant without a predicate fn that has more that one bit set, handle
+ // this as a special case. This is usually for targets that have special
+ // handling of certain large constants (e.g. alpha with it's 8/16/32-bit
+ // handling stuff). Using these instructions is often far more efficient
+ // than materializing the constant. Unfortunately, both the instcombiner
+ // and the dag combiner can often infer that bits are dead, and thus drop
+ // them from the mask in the dag. For example, it might turn 'AND X, 255'
+ // into 'AND X, 254' if it knows the low bit is set. Emit code that checks
+ // to handle this.
+ if (!N->isLeaf() &&
+ (N->getOperator()->getName() == "and" ||
+ N->getOperator()->getName() == "or") &&
+ N->getChild(1)->isLeaf() &&
+ N->getChild(1)->getPredicateFns().empty()) {
+ if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
+ if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits.
+ emitInit("SDValue " + RootName + "0" + " = " +
+ getNodeName(RootName) + "->getOperand(" + utostr(0) + ");");
+ emitInit("SDValue " + RootName + "1" + " = " +
+ getNodeName(RootName) + "->getOperand(" + utostr(1) + ");");
+
+ unsigned NTmp = TmpNo++;
+ emitCode("ConstantSDNode *Tmp" + utostr(NTmp) +
+ " = dyn_cast<ConstantSDNode>(" +
+ getNodeName(RootName + "1") + ");");
+ emitCheck("Tmp" + utostr(NTmp));
+ const char *MaskPredicate = N->getOperator()->getName() == "or"
+ ? "CheckOrMask(" : "CheckAndMask(";
+ emitCheck(MaskPredicate + getValueName(RootName + "0") +
+ ", Tmp" + utostr(NTmp) +
+ ", INT64_C(" + itostr(II->getValue()) + "))");
+
+ EmitChildMatchCode(N->getChild(0), N, RootName + utostr(0),
+ ChainSuffix + utostr(0), FoundChain);
+ return;
}
- emitCheck(Code + ")");
}
}
+
+ for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
+ emitInit("SDValue " + getValueName(RootName + utostr(OpNo)) + " = " +
+ getNodeName(RootName) + "->getOperand(" + utostr(OpNo) + ");");
+
+ EmitChildMatchCode(N->getChild(i), N, RootName + utostr(OpNo),
+ ChainSuffix + utostr(OpNo), FoundChain);
+ }
+
+ // Handle cases when root is a complex pattern.
+ const ComplexPattern *CP;
+ if (isRoot && N->isLeaf() && (CP = N->getComplexPatternInfo(CGP))) {
+ std::string Fn = CP->getSelectFunc();
+ unsigned NumOps = CP->getNumOperands();
+ for (unsigned i = 0; i < NumOps; ++i) {
+ emitDecl("CPTmp" + RootName + "_" + utostr(i));
+ emitCode("SDValue CPTmp" + RootName + "_" + utostr(i) + ";");
+ }
+ if (CP->hasProperty(SDNPHasChain)) {
+ emitDecl("CPInChain");
+ emitDecl("Chain" + ChainSuffix);
+ emitCode("SDValue CPInChain;");
+ emitCode("SDValue Chain" + ChainSuffix + ";");
+ }
+
+ std::string Code = Fn + "(" +
+ getNodeName(RootName) + ", " +
+ getValueName(RootName);
+ for (unsigned i = 0; i < NumOps; i++)
+ Code += ", CPTmp" + RootName + "_" + utostr(i);
+ if (CP->hasProperty(SDNPHasChain)) {
+ ChainName = "Chain" + ChainSuffix;
+ Code += ", CPInChain, Chain" + ChainSuffix;
+ }
+ emitCheck(Code + ")");
+ }
+}
- void EmitChildMatchCode(TreePatternNode *Child, TreePatternNode *Parent,
- const std::string &RootName,
- const std::string &ChainSuffix, bool &FoundChain) {
- if (!Child->isLeaf()) {
- // If it's not a leaf, recursively match.
- const SDNodeInfo &CInfo = CGP.getSDNodeInfo(Child->getOperator());
- emitCheck(getNodeName(RootName) + "->getOpcode() == " +
- CInfo.getEnumName());
- EmitMatchCode(Child, Parent, RootName, ChainSuffix, FoundChain);
- bool HasChain = false;
- if (NodeHasProperty(Child, SDNPHasChain, CGP)) {
- HasChain = true;
- FoldedChains.push_back(std::make_pair(getValueName(RootName),
- CInfo.getNumResults()));
- }
- if (NodeHasProperty(Child, SDNPOutFlag, CGP)) {
- assert(FoldedFlag.first == "" && FoldedFlag.second == 0 &&
- "Pattern folded multiple nodes which produce flags?");
- FoldedFlag = std::make_pair(getValueName(RootName),
- CInfo.getNumResults() + (unsigned)HasChain);
+void PatternCodeEmitter::EmitChildMatchCode(TreePatternNode *Child,
+ TreePatternNode *Parent,
+ const std::string &RootName,
+ const std::string &ChainSuffix,
+ bool &FoundChain) {
+ if (!Child->isLeaf()) {
+ // If it's not a leaf, recursively match.
+ const SDNodeInfo &CInfo = CGP.getSDNodeInfo(Child->getOperator());
+ emitCheck(getNodeName(RootName) + "->getOpcode() == " +
+ CInfo.getEnumName());
+ EmitMatchCode(Child, Parent, RootName, ChainSuffix, FoundChain);
+ bool HasChain = false;
+ if (Child->NodeHasProperty(SDNPHasChain, CGP)) {
+ HasChain = true;
+ FoldedChains.push_back(std::make_pair(getValueName(RootName),
+ CInfo.getNumResults()));
+ }
+ if (Child->NodeHasProperty(SDNPOutFlag, CGP)) {
+ assert(FoldedFlag.first == "" && FoldedFlag.second == 0 &&
+ "Pattern folded multiple nodes which produce flags?");
+ FoldedFlag = std::make_pair(getValueName(RootName),
+ CInfo.getNumResults() + (unsigned)HasChain);
+ }
+ } else {
+ // If this child has a name associated with it, capture it in VarMap. If
+ // we already saw this in the pattern, emit code to verify dagness.
+ if (!Child->getName().empty()) {
+ std::string &VarMapEntry = VariableMap[Child->getName()];
+ if (VarMapEntry.empty()) {
+ VarMapEntry = getValueName(RootName);
+ } else {
+ // If we get here, this is a second reference to a specific name.
+ // Since we already have checked that the first reference is valid,
+ // we don't have to recursively match it, just check that it's the
+ // same as the previously named thing.
+ emitCheck(VarMapEntry + " == " + getValueName(RootName));
+ Duplicates.insert(getValueName(RootName));
+ return;
}
- } else {
- // If this child has a name associated with it, capture it in VarMap. If
- // we already saw this in the pattern, emit code to verify dagness.
- if (!Child->getName().empty()) {
- std::string &VarMapEntry = VariableMap[Child->getName()];
- if (VarMapEntry.empty()) {
- VarMapEntry = getValueName(RootName);
- } else {
- // If we get here, this is a second reference to a specific name.
- // Since we already have checked that the first reference is valid,
- // we don't have to recursively match it, just check that it's the
- // same as the previously named thing.
- emitCheck(VarMapEntry + " == " + getValueName(RootName));
- Duplicates.insert(getValueName(RootName));
- return;
+ }
+
+ // Handle leaves of various types.
+ if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
+ Record *LeafRec = DI->getDef();
+ if (LeafRec->isSubClassOf("RegisterClass") ||
+ LeafRec->isSubClassOf("PointerLikeRegClass")) {
+ // Handle register references. Nothing to do here.
+ } else if (LeafRec->isSubClassOf("Register")) {
+ // Handle register references.
+ } else if (LeafRec->isSubClassOf("ComplexPattern")) {
+ // Handle complex pattern.
+ const ComplexPattern *CP = Child->getComplexPatternInfo(CGP);
+ std::string Fn = CP->getSelectFunc();
+ unsigned NumOps = CP->getNumOperands();
+ for (unsigned i = 0; i < NumOps; ++i) {
+ emitDecl("CPTmp" + RootName + "_" + utostr(i));
+ emitCode("SDValue CPTmp" + RootName + "_" + utostr(i) + ";");
}
- }
-
- // Handle leaves of various types.
- if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
- Record *LeafRec = DI->getDef();
- if (LeafRec->isSubClassOf("RegisterClass") ||
- LeafRec->isSubClassOf("PointerLikeRegClass")) {
- // Handle register references. Nothing to do here.
- } else if (LeafRec->isSubClassOf("Register")) {
- // Handle register references.
- } else if (LeafRec->isSubClassOf("ComplexPattern")) {
- // Handle complex pattern.
- const ComplexPattern *CP = NodeGetComplexPattern(Child, CGP);
- std::string Fn = CP->getSelectFunc();
- unsigned NumOps = CP->getNumOperands();
- for (unsigned i = 0; i < NumOps; ++i) {
- emitDecl("CPTmp" + RootName + "_" + utostr(i));
- emitCode("SDValue CPTmp" + RootName + "_" + utostr(i) + ";");
- }
- if (CP->hasProperty(SDNPHasChain)) {
- const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Parent->getOperator());
- FoldedChains.push_back(std::make_pair("CPInChain",
- PInfo.getNumResults()));
- ChainName = "Chain" + ChainSuffix;
- emitDecl("CPInChain");
- emitDecl(ChainName);
- emitCode("SDValue CPInChain;");
- emitCode("SDValue " + ChainName + ";");
- }
-
- std::string Code = Fn + "(N, ";
- if (CP->hasProperty(SDNPHasChain)) {
- std::string ParentName(RootName.begin(), RootName.end()-1);
- Code += getValueName(ParentName) + ", ";
- }
- Code += getValueName(RootName);
- for (unsigned i = 0; i < NumOps; i++)
- Code += ", CPTmp" + RootName + "_" + utostr(i);
- if (CP->hasProperty(SDNPHasChain))
- Code += ", CPInChain, Chain" + ChainSuffix;
- emitCheck(Code + ")");
- } else if (LeafRec->getName() == "srcvalue") {
- // Place holder for SRCVALUE nodes. Nothing to do here.
- } else if (LeafRec->isSubClassOf("ValueType")) {
- // Make sure this is the specified value type.
- emitCheck("cast<VTSDNode>(" + getNodeName(RootName) +
- ")->getVT() == MVT::" + LeafRec->getName());
- } else if (LeafRec->isSubClassOf("CondCode")) {
- // Make sure this is the specified cond code.
- emitCheck("cast<CondCodeSDNode>(" + getNodeName(RootName) +
- ")->get() == ISD::" + LeafRec->getName());
- } else {
-#ifndef NDEBUG
- Child->dump();
- errs() << " ";
-#endif
- assert(0 && "Unknown leaf type!");
+ if (CP->hasProperty(SDNPHasChain)) {
+ const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Parent->getOperator());
+ FoldedChains.push_back(std::make_pair("CPInChain",
+ PInfo.getNumResults()));
+ ChainName = "Chain" + ChainSuffix;
+ emitDecl("CPInChain");
+ emitDecl(ChainName);
+ emitCode("SDValue CPInChain;");
+ emitCode("SDValue " + ChainName + ";");
}
- // If there are node predicates for this, emit the calls.
- for (unsigned i = 0, e = Child->getPredicateFns().size(); i != e; ++i)
- emitCheck(Child->getPredicateFns()[i] + "(" + getNodeName(RootName) +
- ")");
- } else if (IntInit *II =
- dynamic_cast<IntInit*>(Child->getLeafValue())) {
- unsigned NTmp = TmpNo++;
- emitCode("ConstantSDNode *Tmp"+ utostr(NTmp) +
- " = dyn_cast<ConstantSDNode>("+
- getNodeName(RootName) + ");");
- emitCheck("Tmp" + utostr(NTmp));
- unsigned CTmp = TmpNo++;
- emitCode("int64_t CN"+ utostr(CTmp) +
- " = Tmp" + utostr(NTmp) + "->getSExtValue();");
- emitCheck("CN" + utostr(CTmp) + " == "
- "INT64_C(" +itostr(II->getValue()) + ")");
+ std::string Code = Fn + "(N, ";
+ if (CP->hasProperty(SDNPHasChain)) {
+ std::string ParentName(RootName.begin(), RootName.end()-1);
+ Code += getValueName(ParentName) + ", ";
+ }
+ Code += getValueName(RootName);
+ for (unsigned i = 0; i < NumOps; i++)
+ Code += ", CPTmp" + RootName + "_" + utostr(i);
+ if (CP->hasProperty(SDNPHasChain))
+ Code += ", CPInChain, Chain" + ChainSuffix;
+ emitCheck(Code + ")");
+ } else if (LeafRec->getName() == "srcvalue") {
+ // Place holder for SRCVALUE nodes. Nothing to do here.
+ } else if (LeafRec->isSubClassOf("ValueType")) {
+ // Make sure this is the specified value type.
+ emitCheck("cast<VTSDNode>(" + getNodeName(RootName) +
+ ")->getVT() == MVT::" + LeafRec->getName());
+ } else if (LeafRec->isSubClassOf("CondCode")) {
+ // Make sure this is the specified cond code.
+ emitCheck("cast<CondCodeSDNode>(" + getNodeName(RootName) +
+ ")->get() == ISD::" + LeafRec->getName());
} else {
#ifndef NDEBUG
Child->dump();
+ errs() << " ";
#endif
assert(0 && "Unknown leaf type!");
}
+
+ // If there are node predicates for this, emit the calls.
+ for (unsigned i = 0, e = Child->getPredicateFns().size(); i != e; ++i)
+ emitCheck(Child->getPredicateFns()[i] + "(" + getNodeName(RootName) +
+ ")");
+ } else if (IntInit *II =
+ dynamic_cast<IntInit*>(Child->getLeafValue())) {
+ unsigned NTmp = TmpNo++;
+ emitCode("ConstantSDNode *Tmp"+ utostr(NTmp) +
+ " = dyn_cast<ConstantSDNode>("+
+ getNodeName(RootName) + ");");
+ emitCheck("Tmp" + utostr(NTmp));
+ unsigned CTmp = TmpNo++;
+ emitCode("int64_t CN"+ utostr(CTmp) +
+ " = Tmp" + utostr(NTmp) + "->getSExtValue();");
+ emitCheck("CN" + utostr(CTmp) + " == "
+ "INT64_C(" +itostr(II->getValue()) + ")");
+ } else {
+#ifndef NDEBUG
+ Child->dump();
+#endif
+ assert(0 && "Unknown leaf type!");
}
}
+}
- /// EmitResultCode - Emit the action for a pattern. Now that it has matched
- /// we actually have to build a DAG!
- std::vector<std::string>
- EmitResultCode(TreePatternNode *N, std::vector<Record*> DstRegs,
- bool InFlagDecled, bool ResNodeDecled,
- bool LikeLeaf = false, bool isRoot = false) {
- // List of arguments of getMachineNode() or SelectNodeTo().
- std::vector<std::string> NodeOps;
- // This is something selected from the pattern we matched.
- if (!N->getName().empty()) {
- const std::string &VarName = N->getName();
- std::string Val = VariableMap[VarName];
- bool ModifiedVal = false;
- if (Val.empty()) {
- errs() << "Variable '" << VarName << " referenced but not defined "
- << "and not caught earlier!\n";
- abort();
- }
- if (Val[0] == 'T' && Val[1] == 'm' && Val[2] == 'p') {
- // Already selected this operand, just return the tmpval.
- NodeOps.push_back(getValueName(Val));
- return NodeOps;
- }
-
- const ComplexPattern *CP;
- unsigned ResNo = TmpNo++;
- if (!N->isLeaf() && N->getOperator()->getName() == "imm") {
- assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
- std::string CastType;
- std::string TmpVar = "Tmp" + utostr(ResNo);
- switch (N->getTypeNum(0)) {
+/// EmitResultCode - Emit the action for a pattern. Now that it has matched
+/// we actually have to build a DAG!
+std::vector<std::string>
+PatternCodeEmitter::EmitResultCode(TreePatternNode *N,
+ std::vector<Record*> DstRegs,
+ bool InFlagDecled, bool ResNodeDecled,
+ bool LikeLeaf, bool isRoot) {
+ // List of arguments of getMachineNode() or SelectNodeTo().
+ std::vector<std::string> NodeOps;
+ // This is something selected from the pattern we matched.
+ if (!N->getName().empty()) {
+ const std::string &VarName = N->getName();
+ std::string Val = VariableMap[VarName];
+ bool ModifiedVal = false;
+ if (Val.empty()) {
+ errs() << "Variable '" << VarName << " referenced but not defined "
+ << "and not caught earlier!\n";
+ abort();
+ }
+ if (Val[0] == 'T' && Val[1] == 'm' && Val[2] == 'p') {
+ // Already selected this operand, just return the tmpval.
+ NodeOps.push_back(getValueName(Val));
+ return NodeOps;
+ }
+
+ const ComplexPattern *CP;
+ unsigned ResNo = TmpNo++;
+ if (!N->isLeaf() && N->getOperator()->getName() == "imm") {
+ assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
+ std::string CastType;
+ std::string TmpVar = "Tmp" + utostr(ResNo);
+ switch (N->getTypeNum(0)) {
default:
errs() << "Cannot handle " << getEnumName(N->getTypeNum(0))
- << " type as an immediate constant. Aborting\n";
+ << " type as an immediate constant. Aborting\n";
abort();
case MVT::i1: CastType = "bool"; break;
case MVT::i8: CastType = "unsigned char"; break;
case MVT::i16: CastType = "unsigned short"; break;
case MVT::i32: CastType = "unsigned"; break;
case MVT::i64: CastType = "uint64_t"; break;
- }
- emitCode("SDValue " + TmpVar +
- " = CurDAG->getTargetConstant(((" + CastType +
- ") cast<ConstantSDNode>(" + Val + ")->getZExtValue()), " +
+ }
+ emitCode("SDValue " + TmpVar +
+ " = CurDAG->getTargetConstant(((" + CastType +
+ ") cast<ConstantSDNode>(" + Val + ")->getZExtValue()), " +
+ getEnumName(N->getTypeNum(0)) + ");");
+ // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
+ // value if used multiple times by this pattern result.
+ Val = TmpVar;
+ ModifiedVal = true;
+ NodeOps.push_back(getValueName(Val));
+ } else if (!N->isLeaf() && N->getOperator()->getName() == "fpimm") {
+ assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
+ std::string TmpVar = "Tmp" + utostr(ResNo);
+ emitCode("SDValue " + TmpVar +
+ " = CurDAG->getTargetConstantFP(*cast<ConstantFPSDNode>(" +
+ Val + ")->getConstantFPValue(), cast<ConstantFPSDNode>(" +
+ Val + ")->getValueType(0));");
+ // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
+ // value if used multiple times by this pattern result.
+ Val = TmpVar;
+ ModifiedVal = true;
+ NodeOps.push_back(getValueName(Val));
+ } else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){
+ Record *Op = OperatorMap[N->getName()];
+ // Transform ExternalSymbol to TargetExternalSymbol
+ if (Op && Op->getName() == "externalsym") {
+ std::string TmpVar = "Tmp"+utostr(ResNo);
+ emitCode("SDValue " + TmpVar + " = CurDAG->getTarget"
+ "ExternalSymbol(cast<ExternalSymbolSDNode>(" +
+ Val + ")->getSymbol(), " +
getEnumName(N->getTypeNum(0)) + ");");
- // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
- // value if used multiple times by this pattern result.
+ // Add Tmp<ResNo> to VariableMap, so that we don't multiply select
+ // this value if used multiple times by this pattern result.
Val = TmpVar;
ModifiedVal = true;
- NodeOps.push_back(getValueName(Val));
- } else if (!N->isLeaf() && N->getOperator()->getName() == "fpimm") {
- assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
- std::string TmpVar = "Tmp" + utostr(ResNo);
- emitCode("SDValue " + TmpVar +
- " = CurDAG->getTargetConstantFP(*cast<ConstantFPSDNode>(" +
- Val + ")->getConstantFPValue(), cast<ConstantFPSDNode>(" +
- Val + ")->getValueType(0));");
- // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
- // value if used multiple times by this pattern result.
+ }
+ NodeOps.push_back(getValueName(Val));
+ } else if (!N->isLeaf() && (N->getOperator()->getName() == "tglobaladdr"
+ || N->getOperator()->getName() == "tglobaltlsaddr")) {
+ Record *Op = OperatorMap[N->getName()];
+ // Transform GlobalAddress to TargetGlobalAddress
+ if (Op && (Op->getName() == "globaladdr" ||
+ Op->getName() == "globaltlsaddr")) {
+ std::string TmpVar = "Tmp" + utostr(ResNo);
+ emitCode("SDValue " + TmpVar + " = CurDAG->getTarget"
+ "GlobalAddress(cast<GlobalAddressSDNode>(" + Val +
+ ")->getGlobal(), " + getEnumName(N->getTypeNum(0)) +
+ ");");
+ // Add Tmp<ResNo> to VariableMap, so that we don't multiply select
+ // this value if used multiple times by this pattern result.
Val = TmpVar;
ModifiedVal = true;
- NodeOps.push_back(getValueName(Val));
- } else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){
- Record *Op = OperatorMap[N->getName()];
- // Transform ExternalSymbol to TargetExternalSymbol
- if (Op && Op->getName() == "externalsym") {
- std::string TmpVar = "Tmp"+utostr(ResNo);
- emitCode("SDValue " + TmpVar + " = CurDAG->getTarget"
- "ExternalSymbol(cast<ExternalSymbolSDNode>(" +
- Val + ")->getSymbol(), " +
- getEnumName(N->getTypeNum(0)) + ");");
- // Add Tmp<ResNo> to VariableMap, so that we don't multiply select
- // this value if used multiple times by this pattern result.
- Val = TmpVar;
- ModifiedVal = true;
- }
- NodeOps.push_back(getValueName(Val));
- } else if (!N->isLeaf() && (N->getOperator()->getName() == "tglobaladdr"
- || N->getOperator()->getName() == "tglobaltlsaddr")) {
- Record *Op = OperatorMap[N->getName()];
- // Transform GlobalAddress to TargetGlobalAddress
- if (Op && (Op->getName() == "globaladdr" ||
- Op->getName() == "globaltlsaddr")) {
- std::string TmpVar = "Tmp" + utostr(ResNo);
- emitCode("SDValue " + TmpVar + " = CurDAG->getTarget"
- "GlobalAddress(cast<GlobalAddressSDNode>(" + Val +
- ")->getGlobal(), " + getEnumName(N->getTypeNum(0)) +
- ");");
- // Add Tmp<ResNo> to VariableMap, so that we don't multiply select
- // this value if used multiple times by this pattern result.
- Val = TmpVar;
- ModifiedVal = true;
- }
- NodeOps.push_back(getValueName(Val));
- } else if (!N->isLeaf()
- && (N->getOperator()->getName() == "texternalsym"
- || N->getOperator()->getName() == "tconstpool")) {
- // Do not rewrite the variable name, since we don't generate a new
- // temporary.
- NodeOps.push_back(getValueName(Val));
- } else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, CGP))) {
- for (unsigned i = 0; i < CP->getNumOperands(); ++i) {
- NodeOps.push_back(getValueName("CPTmp" + Val + "_" + utostr(i)));
- }
- } else {
- // This node, probably wrapped in a SDNodeXForm, behaves like a leaf
- // node even if it isn't one. Don't select it.
- if (!LikeLeaf) {
- if (isRoot && N->isLeaf()) {
- emitCode("ReplaceUses(SDValue(N, 0), " + Val + ");");
- emitCode("return NULL;");
- }
- }
- NodeOps.push_back(getValueName(Val));
}
-
- if (ModifiedVal) {
- VariableMap[VarName] = Val;
+ NodeOps.push_back(getValueName(Val));
+ } else if (!N->isLeaf()
+ && (N->getOperator()->getName() == "texternalsym" ||
+ N->getOperator()->getName() == "tconstpool")) {
+ // Do not rewrite the variable name, since we don't generate a new
+ // temporary.
+ NodeOps.push_back(getValueName(Val));
+ } else if (N->isLeaf() && (CP = N->getComplexPatternInfo(CGP))) {
+ for (unsigned i = 0; i < CP->getNumOperands(); ++i) {
+ NodeOps.push_back(getValueName("CPTmp" + Val + "_" + utostr(i)));
}
- return NodeOps;
- }
- if (N->isLeaf()) {
- // If this is an explicit register reference, handle it.
- if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
- unsigned ResNo = TmpNo++;
- if (DI->getDef()->isSubClassOf("Register")) {
- emitCode("SDValue Tmp" + utostr(ResNo) + " = CurDAG->getRegister(" +
- getQualifiedName(DI->getDef()) + ", " +
- getEnumName(N->getTypeNum(0)) + ");");
- NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
- return NodeOps;
- } else if (DI->getDef()->getName() == "zero_reg") {
- emitCode("SDValue Tmp" + utostr(ResNo) +
- " = CurDAG->getRegister(0, " +
- getEnumName(N->getTypeNum(0)) + ");");
- NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
- return NodeOps;
- } else if (DI->getDef()->isSubClassOf("RegisterClass")) {
- // Handle a reference to a register class. This is used
- // in COPY_TO_SUBREG instructions.
- emitCode("SDValue Tmp" + utostr(ResNo) +
- " = CurDAG->getTargetConstant(" +
- getQualifiedName(DI->getDef()) + "RegClassID, " +
- "MVT::i32);");
- NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
- return NodeOps;
+ } else {
+ // This node, probably wrapped in a SDNodeXForm, behaves like a leaf
+ // node even if it isn't one. Don't select it.
+ if (!LikeLeaf) {
+ if (isRoot && N->isLeaf()) {
+ emitCode("ReplaceUses(SDValue(N, 0), " + Val + ");");
+ emitCode("return NULL;");
}
- } else if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
- unsigned ResNo = TmpNo++;
- assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
- emitCode("SDValue Tmp" + utostr(ResNo) +
- " = CurDAG->getTargetConstant(0x" +
- utohexstr((uint64_t) II->getValue()) +
- "ULL, " + getEnumName(N->getTypeNum(0)) + ");");
+ }
+ NodeOps.push_back(getValueName(Val));
+ }
+
+ if (ModifiedVal)
+ VariableMap[VarName] = Val;
+ return NodeOps;
+ }
+ if (N->isLeaf()) {
+ // If this is an explicit register reference, handle it.
+ if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
+ unsigned ResNo = TmpNo++;
+ if (DI->getDef()->isSubClassOf("Register")) {
+ emitCode("SDValue Tmp" + utostr(ResNo) + " = CurDAG->getRegister(" +
+ getQualifiedName(DI->getDef()) + ", " +
+ getEnumName(N->getTypeNum(0)) + ");");
+ NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
+ return NodeOps;
+ } else if (DI->getDef()->getName() == "zero_reg") {
+ emitCode("SDValue Tmp" + utostr(ResNo) +
+ " = CurDAG->getRegister(0, " +
+ getEnumName(N->getTypeNum(0)) + ");");
+ NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
+ return NodeOps;
+ } else if (DI->getDef()->isSubClassOf("RegisterClass")) {
+ // Handle a reference to a register class. This is used
+ // in COPY_TO_SUBREG instructions.
+ emitCode("SDValue Tmp" + utostr(ResNo) +
+ " = CurDAG->getTargetConstant(" +
+ getQualifiedName(DI->getDef()) + "RegClassID, " +
+ "MVT::i32);");
NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
return NodeOps;
}
+ } else if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
+ unsigned ResNo = TmpNo++;
+ assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
+ emitCode("SDValue Tmp" + utostr(ResNo) +
+ " = CurDAG->getTargetConstant(0x" +
+ utohexstr((uint64_t) II->getValue()) +
+ "ULL, " + getEnumName(N->getTypeNum(0)) + ");");
+ NodeOps.push_back(getValueName("Tmp" + utostr(ResNo)));
+ return NodeOps;
+ }
#ifndef NDEBUG
- N->dump();
+ N->dump();
#endif
- assert(0 && "Unknown leaf type!");
- return NodeOps;
+ assert(0 && "Unknown leaf type!");
+ return NodeOps;
+ }
+
+ Record *Op = N->getOperator();
+ if (Op->isSubClassOf("Instruction")) {
+ const CodeGenTarget &CGT = CGP.getTargetInfo();
+ CodeGenInstruction &II = CGT.getInstruction(Op->getName());
+ const DAGInstruction &Inst = CGP.getInstruction(Op);
+ const TreePattern *InstPat = Inst.getPattern();
+ // FIXME: Assume actual pattern comes before "implicit".
+ TreePatternNode *InstPatNode =
+ isRoot ? (InstPat ? InstPat->getTree(0) : Pattern)
+ : (InstPat ? InstPat->getTree(0) : NULL);
+ if (InstPatNode && !InstPatNode->isLeaf() &&
+ InstPatNode->getOperator()->getName() == "set") {
+ InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1);
}
-
- Record *Op = N->getOperator();
- if (Op->isSubClassOf("Instruction")) {
- const CodeGenTarget &CGT = CGP.getTargetInfo();
- CodeGenInstruction &II = CGT.getInstruction(Op->getName());
- const DAGInstruction &Inst = CGP.getInstruction(Op);
- const TreePattern *InstPat = Inst.getPattern();
- // FIXME: Assume actual pattern comes before "implicit".
- TreePatternNode *InstPatNode =
- isRoot ? (InstPat ? InstPat->getTree(0) : Pattern)
- : (InstPat ? InstPat->getTree(0) : NULL);
- if (InstPatNode && !InstPatNode->isLeaf() &&
- InstPatNode->getOperator()->getName() == "set") {
- InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1);
- }
- bool IsVariadic = isRoot && II.isVariadic;
- // FIXME: fix how we deal with physical register operands.
- bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0;
- bool HasImpResults = isRoot && DstRegs.size() > 0;
- bool NodeHasOptInFlag = isRoot &&
- PatternHasProperty(Pattern, SDNPOptInFlag, CGP);
- bool NodeHasInFlag = isRoot &&
- PatternHasProperty(Pattern, SDNPInFlag, CGP);
- bool NodeHasOutFlag = isRoot &&
- PatternHasProperty(Pattern, SDNPOutFlag, CGP);
- bool NodeHasChain = InstPatNode &&
- PatternHasProperty(InstPatNode, SDNPHasChain, CGP);
- bool InputHasChain = isRoot &&
- NodeHasProperty(Pattern, SDNPHasChain, CGP);
- unsigned NumResults = Inst.getNumResults();
- unsigned NumDstRegs = HasImpResults ? DstRegs.size() : 0;
-
- // Record output varargs info.
- OutputIsVariadic = IsVariadic;
-
- if (NodeHasOptInFlag) {
- emitCode("bool HasInFlag = "
- "(N->getOperand(N->getNumOperands()-1).getValueType() == "
- "MVT::Flag);");
- }
- if (IsVariadic)
- emitCode("SmallVector<SDValue, 8> Ops" + utostr(OpcNo) + ";");
-
- // How many results is this pattern expected to produce?
- unsigned NumPatResults = 0;
- for (unsigned i = 0, e = Pattern->getExtTypes().size(); i != e; i++) {
- MVT::SimpleValueType VT = Pattern->getTypeNum(i);
- if (VT != MVT::isVoid && VT != MVT::Flag)
- NumPatResults++;
+ bool IsVariadic = isRoot && II.isVariadic;
+ // FIXME: fix how we deal with physical register operands.
+ bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0;
+ bool HasImpResults = isRoot && DstRegs.size() > 0;
+ bool NodeHasOptInFlag = isRoot &&
+ Pattern->TreeHasProperty(SDNPOptInFlag, CGP);
+ bool NodeHasInFlag = isRoot &&
+ Pattern->TreeHasProperty(SDNPInFlag, CGP);
+ bool NodeHasOutFlag = isRoot &&
+ Pattern->TreeHasProperty(SDNPOutFlag, CGP);
+ bool NodeHasChain = InstPatNode &&
+ InstPatNode->TreeHasProperty(SDNPHasChain, CGP);
+ bool InputHasChain = isRoot && Pattern->NodeHasProperty(SDNPHasChain, CGP);
+ unsigned NumResults = Inst.getNumResults();
+ unsigned NumDstRegs = HasImpResults ? DstRegs.size() : 0;
+
+ // Record output varargs info.
+ OutputIsVariadic = IsVariadic;
+
+ if (NodeHasOptInFlag) {
+ emitCode("bool HasInFlag = "
+ "(N->getOperand(N->getNumOperands()-1).getValueType() == "
+ "MVT::Flag);");
+ }
+ if (IsVariadic)
+ emitCode("SmallVector<SDValue, 8> Ops" + utostr(OpcNo) + ";");
+
+ // How many results is this pattern expected to produce?
+ unsigned NumPatResults = 0;
+ for (unsigned i = 0, e = Pattern->getExtTypes().size(); i != e; i++) {
+ MVT::SimpleValueType VT = Pattern->getTypeNum(i);
+ if (VT != MVT::isVoid && VT != MVT::Flag)
+ NumPatResults++;
+ }
+
+ if (OrigChains.size() > 0) {
+ // The original input chain is being ignored. If it is not just
+ // pointing to the op that's being folded, we should create a
+ // TokenFactor with it and the chain of the folded op as the new chain.
+ // We could potentially be doing multiple levels of folding, in that
+ // case, the TokenFactor can have more operands.
+ emitCode("SmallVector<SDValue, 8> InChains;");
+ for (unsigned i = 0, e = OrigChains.size(); i < e; ++i) {
+ emitCode("if (" + OrigChains[i].first + ".getNode() != " +
+ OrigChains[i].second + ".getNode()) {");
+ emitCode(" InChains.push_back(" + OrigChains[i].first + ");");
+ emitCode("}");
}
-
- if (OrigChains.size() > 0) {
- // The original input chain is being ignored. If it is not just
- // pointing to the op that's being folded, we should create a
- // TokenFactor with it and the chain of the folded op as the new chain.
- // We could potentially be doing multiple levels of folding, in that
- // case, the TokenFactor can have more operands.
- emitCode("SmallVector<SDValue, 8> InChains;");
- for (unsigned i = 0, e = OrigChains.size(); i < e; ++i) {
- emitCode("if (" + OrigChains[i].first + ".getNode() != " +
- OrigChains[i].second + ".getNode()) {");
- emitCode(" InChains.push_back(" + OrigChains[i].first + ");");
- emitCode("}");
- }
- emitCode("InChains.push_back(" + ChainName + ");");
- emitCode(ChainName + " = CurDAG->getNode(ISD::TokenFactor, "
- "N->getDebugLoc(), MVT::Other, "
- "&InChains[0], InChains.size());");
- if (GenDebug) {
- emitCode("CurDAG->setSubgraphColor(" + ChainName +".getNode(), \"yellow\");");
- emitCode("CurDAG->setSubgraphColor(" + ChainName +".getNode(), \"black\");");
- }
+ emitCode("InChains.push_back(" + ChainName + ");");
+ emitCode(ChainName + " = CurDAG->getNode(ISD::TokenFactor, "
+ "N->getDebugLoc(), MVT::Other, "
+ "&InChains[0], InChains.size());");
+ if (GenDebug) {
+ emitCode("CurDAG->setSubgraphColor(" + ChainName +".getNode(), \"yellow\");");
+ emitCode("CurDAG->setSubgraphColor(" + ChainName +".getNode(), \"black\");");
}
-
- // Loop over all of the operands of the instruction pattern, emitting code
- // to fill them all in. The node 'N' usually has number children equal to
- // the number of input operands of the instruction. However, in cases
- // where there are predicate operands for an instruction, we need to fill
- // in the 'execute always' values. Match up the node operands to the
- // instruction operands to do this.
- std::vector<std::string> AllOps;
- for (unsigned ChildNo = 0, InstOpNo = NumResults;
- InstOpNo != II.OperandList.size(); ++InstOpNo) {
- std::vector<std::string> Ops;
-
- // Determine what to emit for this operand.
- Record *OperandNode = II.OperandList[InstOpNo].Rec;
- if ((OperandNode->isSubClassOf("PredicateOperand") ||
- OperandNode->isSubClassOf("OptionalDefOperand")) &&
- !CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
- // This is a predicate or optional def operand; emit the
- // 'default ops' operands.
- const DAGDefaultOperand &DefaultOp =
- CGP.getDefaultOperand(II.OperandList[InstOpNo].Rec);
- for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i) {
- Ops = EmitResultCode(DefaultOp.DefaultOps[i], DstRegs,
- InFlagDecled, ResNodeDecled);
- AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
- }
- } else {
- // Otherwise this is a normal operand or a predicate operand without
- // 'execute always'; emit it.
- Ops = EmitResultCode(N->getChild(ChildNo), DstRegs,
+ }
+
+ // Loop over all of the operands of the instruction pattern, emitting code
+ // to fill them all in. The node 'N' usually has number children equal to
+ // the number of input operands of the instruction. However, in cases
+ // where there are predicate operands for an instruction, we need to fill
+ // in the 'execute always' values. Match up the node operands to the
+ // instruction operands to do this.
+ std::vector<std::string> AllOps;
+ for (unsigned ChildNo = 0, InstOpNo = NumResults;
+ InstOpNo != II.OperandList.size(); ++InstOpNo) {
+ std::vector<std::string> Ops;
+
+ // Determine what to emit for this operand.
+ Record *OperandNode = II.OperandList[InstOpNo].Rec;
+ if ((OperandNode->isSubClassOf("PredicateOperand") ||
+ OperandNode->isSubClassOf("OptionalDefOperand")) &&
+ !CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
+ // This is a predicate or optional def operand; emit the
+ // 'default ops' operands.
+ const DAGDefaultOperand &DefaultOp =
+ CGP.getDefaultOperand(II.OperandList[InstOpNo].Rec);
+ for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i) {
+ Ops = EmitResultCode(DefaultOp.DefaultOps[i], DstRegs,
InFlagDecled, ResNodeDecled);
AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
- ++ChildNo;
}
- }
-
- // Emit all the chain and CopyToReg stuff.
- bool ChainEmitted = NodeHasChain;
- if (NodeHasInFlag || HasImpInputs)
- EmitInFlagSelectCode(Pattern, "N", ChainEmitted,
- InFlagDecled, ResNodeDecled, true);
- if (NodeHasOptInFlag || NodeHasInFlag || HasImpInputs) {
- if (!InFlagDecled) {
- emitCode("SDValue InFlag(0, 0);");
- InFlagDecled = true;
- }
- if (NodeHasOptInFlag) {
- emitCode("if (HasInFlag) {");
- emitCode(" InFlag = N->getOperand(N->getNumOperands()-1);");
- emitCode("}");
- }
- }
-
- unsigned ResNo = TmpNo++;
-
- unsigned OpsNo = OpcNo;
- std::string CodePrefix;
- bool ChainAssignmentNeeded = NodeHasChain && !isRoot;
- std::deque<std::string> After;
- std::string NodeName;
- if (!isRoot) {
- NodeName = "Tmp" + utostr(ResNo);
- CodePrefix = "SDValue " + NodeName + "(";
} else {
- NodeName = "ResNode";
- if (!ResNodeDecled) {
- CodePrefix = "SDNode *" + NodeName + " = ";
- ResNodeDecled = true;
- } else
- CodePrefix = NodeName + " = ";
- }
-
- std::string Code = "Opc" + utostr(OpcNo);
-
- if (!isRoot || (InputHasChain && !NodeHasChain))
- // For call to "getMachineNode()".
- Code += ", N->getDebugLoc()";
-
- emitOpcode(II.Namespace + "::" + II.TheDef->getName());
-
- // Output order: results, chain, flags
- // Result types.
- if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid) {
- Code += ", VT" + utostr(VTNo);
- emitVT(getEnumName(N->getTypeNum(0)));
+ // Otherwise this is a normal operand or a predicate operand without
+ // 'execute always'; emit it.
+ Ops = EmitResultCode(N->getChild(ChildNo), DstRegs,
+ InFlagDecled, ResNodeDecled);
+ AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
+ ++ChildNo;
}
- // Add types for implicit results in physical registers, scheduler will
- // care of adding copyfromreg nodes.
- for (unsigned i = 0; i < NumDstRegs; i++) {
- Record *RR = DstRegs[i];
- if (RR->isSubClassOf("Register")) {
- MVT::SimpleValueType RVT = getRegisterValueType(RR, CGT);
- Code += ", " + getEnumName(RVT);
- }
+ }
+
+ // Emit all the chain and CopyToReg stuff.
+ bool ChainEmitted = NodeHasChain;
+ if (NodeHasInFlag || HasImpInputs)
+ EmitInFlagSelectCode(Pattern, "N", ChainEmitted,
+ InFlagDecled, ResNodeDecled, true);
+ if (NodeHasOptInFlag || NodeHasInFlag || HasImpInputs) {
+ if (!InFlagDecled) {
+ emitCode("SDValue InFlag(0, 0);");
+ InFlagDecled = true;
}
- if (NodeHasChain)
- Code += ", MVT::Other";
- if (NodeHasOutFlag)
- Code += ", MVT::Flag";
-
- // Inputs.
- if (IsVariadic) {
- for (unsigned i = 0, e = AllOps.size(); i != e; ++i)
- emitCode("Ops" + utostr(OpsNo) + ".push_back(" + AllOps[i] + ");");
- AllOps.clear();
-
- // Figure out whether any operands at the end of the op list are not
- // part of the variable section.
- std::string EndAdjust;
- if (NodeHasInFlag || HasImpInputs)
- EndAdjust = "-1"; // Always has one flag.
- else if (NodeHasOptInFlag)
- EndAdjust = "-(HasInFlag?1:0)"; // May have a flag.
-
- emitCode("for (unsigned i = NumInputRootOps + " + utostr(NodeHasChain) +
- ", e = N->getNumOperands()" + EndAdjust + "; i != e; ++i) {");
-
- emitCode(" Ops" + utostr(OpsNo) + ".push_back(N->getOperand(i));");
+ if (NodeHasOptInFlag) {
+ emitCode("if (HasInFlag) {");
+ emitCode(" InFlag = N->getOperand(N->getNumOperands()-1);");
emitCode("}");
}
-
- // Populate MemRefs with entries for each memory accesses covered by
- // this pattern.
- if (isRoot && !LSI.empty()) {
- std::string MemRefs = "MemRefs" + utostr(OpsNo);
- emitCode("MachineSDNode::mmo_iterator " + MemRefs + " = "
- "MF->allocateMemRefsArray(" + utostr(LSI.size()) + ");");
- for (unsigned i = 0, e = LSI.size(); i != e; ++i)
- emitCode(MemRefs + "[" + utostr(i) + "] = "
- "cast<MemSDNode>(" + LSI[i] + ")->getMemOperand();");
- After.push_back("cast<MachineSDNode>(ResNode)->setMemRefs(" +
- MemRefs + ", " + MemRefs + " + " + utostr(LSI.size()) +
- ");");
+ }
+
+ unsigned ResNo = TmpNo++;
+
+ unsigned OpsNo = OpcNo;
+ std::string CodePrefix;
+ bool ChainAssignmentNeeded = NodeHasChain && !isRoot;
+ std::deque<std::string> After;
+ std::string NodeName;
+ if (!isRoot) {
+ NodeName = "Tmp" + utostr(ResNo);
+ CodePrefix = "SDValue " + NodeName + "(";
+ } else {
+ NodeName = "ResNode";
+ if (!ResNodeDecled) {
+ CodePrefix = "SDNode *" + NodeName + " = ";
+ ResNodeDecled = true;
+ } else
+ CodePrefix = NodeName + " = ";
+ }
+
+ std::string Code = "Opc" + utostr(OpcNo);
+
+ if (!isRoot || (InputHasChain && !NodeHasChain))
+ // For call to "getMachineNode()".
+ Code += ", N->getDebugLoc()";
+
+ emitOpcode(II.Namespace + "::" + II.TheDef->getName());
+
+ // Output order: results, chain, flags
+ // Result types.
+ if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid) {
+ Code += ", VT" + utostr(VTNo);
+ emitVT(getEnumName(N->getTypeNum(0)));
+ }
+ // Add types for implicit results in physical registers, scheduler will
+ // care of adding copyfromreg nodes.
+ for (unsigned i = 0; i < NumDstRegs; i++) {
+ Record *RR = DstRegs[i];
+ if (RR->isSubClassOf("Register")) {
+ MVT::SimpleValueType RVT = getRegisterValueType(RR, CGT);
+ Code += ", " + getEnumName(RVT);
}
-
- if (NodeHasChain) {
- if (IsVariadic)
- emitCode("Ops" + utostr(OpsNo) + ".push_back(" + ChainName + ");");
- else
- AllOps.push_back(ChainName);
+ }
+ if (NodeHasChain)
+ Code += ", MVT::Other";
+ if (NodeHasOutFlag)
+ Code += ", MVT::Flag";
+
+ // Inputs.
+ if (IsVariadic) {
+ for (unsigned i = 0, e = AllOps.size(); i != e; ++i)
+ emitCode("Ops" + utostr(OpsNo) + ".push_back(" + AllOps[i] + ");");
+ AllOps.clear();
+
+ // Figure out whether any operands at the end of the op list are not
+ // part of the variable section.
+ std::string EndAdjust;
+ if (NodeHasInFlag || HasImpInputs)
+ EndAdjust = "-1"; // Always has one flag.
+ else if (NodeHasOptInFlag)
+ EndAdjust = "-(HasInFlag?1:0)"; // May have a flag.
+
+ emitCode("for (unsigned i = NumInputRootOps + " + utostr(NodeHasChain) +
+ ", e = N->getNumOperands()" + EndAdjust + "; i != e; ++i) {");
+
+ emitCode(" Ops" + utostr(OpsNo) + ".push_back(N->getOperand(i));");
+ emitCode("}");
+ }
+
+ // Populate MemRefs with entries for each memory accesses covered by
+ // this pattern.
+ if (isRoot && !LSI.empty()) {
+ std::string MemRefs = "MemRefs" + utostr(OpsNo);
+ emitCode("MachineSDNode::mmo_iterator " + MemRefs + " = "
+ "MF->allocateMemRefsArray(" + utostr(LSI.size()) + ");");
+ for (unsigned i = 0, e = LSI.size(); i != e; ++i)
+ emitCode(MemRefs + "[" + utostr(i) + "] = "
+ "cast<MemSDNode>(" + LSI[i] + ")->getMemOperand();");
+ After.push_back("cast<MachineSDNode>(ResNode)->setMemRefs(" +
+ MemRefs + ", " + MemRefs + " + " + utostr(LSI.size()) +
+ ");");
+ }
+
+ if (NodeHasChain) {
+ if (IsVariadic)
+ emitCode("Ops" + utostr(OpsNo) + ".push_back(" + ChainName + ");");
+ else
+ AllOps.push_back(ChainName);
+ }
+
+ if (IsVariadic) {
+ if (NodeHasInFlag || HasImpInputs)
+ emitCode("Ops" + utostr(OpsNo) + ".push_back(InFlag);");
+ else if (NodeHasOptInFlag) {
+ emitCode("if (HasInFlag)");
+ emitCode(" Ops" + utostr(OpsNo) + ".push_back(InFlag);");
}
-
- if (IsVariadic) {
- if (NodeHasInFlag || HasImpInputs)
- emitCode("Ops" + utostr(OpsNo) + ".push_back(InFlag);");
- else if (NodeHasOptInFlag) {
- emitCode("if (HasInFlag)");
- emitCode(" Ops" + utostr(OpsNo) + ".push_back(InFlag);");
- }
- Code += ", &Ops" + utostr(OpsNo) + "[0], Ops" + utostr(OpsNo) +
- ".size()";
- } else if (NodeHasInFlag || NodeHasOptInFlag || HasImpInputs)
- AllOps.push_back("InFlag");
-
- unsigned NumOps = AllOps.size();
- if (NumOps) {
- if (!NodeHasOptInFlag && NumOps < 4) {
- for (unsigned i = 0; i != NumOps; ++i)
- Code += ", " + AllOps[i];
- } else {
- std::string OpsCode = "SDValue Ops" + utostr(OpsNo) + "[] = { ";
- for (unsigned i = 0; i != NumOps; ++i) {
- OpsCode += AllOps[i];
- if (i != NumOps-1)
- OpsCode += ", ";
- }
- emitCode(OpsCode + " };");
- Code += ", Ops" + utostr(OpsNo) + ", ";
- if (NodeHasOptInFlag) {
- Code += "HasInFlag ? ";
- Code += utostr(NumOps) + " : " + utostr(NumOps-1);
- } else
- Code += utostr(NumOps);
+ Code += ", &Ops" + utostr(OpsNo) + "[0], Ops" + utostr(OpsNo) +
+ ".size()";
+ } else if (NodeHasInFlag || NodeHasOptInFlag || HasImpInputs)
+ AllOps.push_back("InFlag");
+
+ unsigned NumOps = AllOps.size();
+ if (NumOps) {
+ if (!NodeHasOptInFlag && NumOps < 4) {
+ for (unsigned i = 0; i != NumOps; ++i)
+ Code += ", " + AllOps[i];
+ } else {
+ std::string OpsCode = "SDValue Ops" + utostr(OpsNo) + "[] = { ";
+ for (unsigned i = 0; i != NumOps; ++i) {
+ OpsCode += AllOps[i];
+ if (i != NumOps-1)
+ OpsCode += ", ";
}
+ emitCode(OpsCode + " };");
+ Code += ", Ops" + utostr(OpsNo) + ", ";
+ if (NodeHasOptInFlag) {
+ Code += "HasInFlag ? ";
+ Code += utostr(NumOps) + " : " + utostr(NumOps-1);
+ } else
+ Code += utostr(NumOps);
}
-
- if (!isRoot)
- Code += "), 0";
-
- std::vector<std::string> ReplaceFroms;
- std::vector<std::string> ReplaceTos;
- if (!isRoot) {
- NodeOps.push_back("Tmp" + utostr(ResNo));
- } else {
-
+ }
+
+ if (!isRoot)
+ Code += "), 0";
+
+ std::vector<std::string> ReplaceFroms;
+ std::vector<std::string> ReplaceTos;
+ if (!isRoot) {
+ NodeOps.push_back("Tmp" + utostr(ResNo));
+ } else {
+
if (NodeHasOutFlag) {
if (!InFlagDecled) {
After.push_back("SDValue InFlag(ResNode, " +
@@ -1228,7 +1258,7 @@ public:
utostr(NumResults+NumDstRegs+(unsigned)NodeHasChain) +
");");
}
-
+
for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) {
ReplaceFroms.push_back("SDValue(" +
FoldedChains[j].first + ".getNode(), " +
@@ -1237,21 +1267,21 @@ public:
ReplaceTos.push_back("SDValue(ResNode, " +
utostr(NumResults+NumDstRegs) + ")");
}
-
+
if (NodeHasOutFlag) {
if (FoldedFlag.first != "") {
ReplaceFroms.push_back("SDValue(" + FoldedFlag.first + ".getNode(), " +
utostr(FoldedFlag.second) + ")");
ReplaceTos.push_back("InFlag");
} else {
- assert(NodeHasProperty(Pattern, SDNPOutFlag, CGP));
+ assert(Pattern->NodeHasProperty(SDNPOutFlag, CGP));
ReplaceFroms.push_back("SDValue(N, " +
utostr(NumPatResults + (unsigned)InputHasChain)
+ ")");
ReplaceTos.push_back("InFlag");
}
}
-
+
if (!ReplaceFroms.empty() && InputHasChain) {
ReplaceFroms.push_back("SDValue(N, " +
utostr(NumPatResults) + ")");
@@ -1259,7 +1289,7 @@ public:
ChainName + ".getResNo()" + ")");
ChainAssignmentNeeded |= NodeHasChain;
}
-
+
// User does not expect the instruction would produce a chain!
if ((!InputHasChain && NodeHasChain) && NodeHasOutFlag) {
;
@@ -1270,193 +1300,97 @@ public:
utostr(NumPatResults) + ")");
ReplaceTos.push_back(ChainName);
}
- }
-
- if (ChainAssignmentNeeded) {
- // Remember which op produces the chain.
- std::string ChainAssign;
- if (!isRoot)
- ChainAssign = ChainName + " = SDValue(" + NodeName +
- ".getNode(), " + utostr(NumResults+NumDstRegs) + ");";
- else
- ChainAssign = ChainName + " = SDValue(" + NodeName +
- ", " + utostr(NumResults+NumDstRegs) + ");";
-
- After.push_front(ChainAssign);
- }
-
- if (ReplaceFroms.size() == 1) {
- After.push_back("ReplaceUses(" + ReplaceFroms[0] + ", " +
- ReplaceTos[0] + ");");
- } else if (!ReplaceFroms.empty()) {
- After.push_back("const SDValue Froms[] = {");
- for (unsigned i = 0, e = ReplaceFroms.size(); i != e; ++i)
- After.push_back(" " + ReplaceFroms[i] + (i + 1 != e ? "," : ""));
- After.push_back("};");
- After.push_back("const SDValue Tos[] = {");
- for (unsigned i = 0, e = ReplaceFroms.size(); i != e; ++i)
- After.push_back(" " + ReplaceTos[i] + (i + 1 != e ? "," : ""));
- After.push_back("};");
- After.push_back("ReplaceUses(Froms, Tos, " +
- itostr(ReplaceFroms.size()) + ");");
- }
-
- // We prefer to use SelectNodeTo since it avoids allocation when
- // possible and it avoids CSE map recalculation for the node's
- // users, however it's tricky to use in a non-root context.
- //
- // We also don't use SelectNodeTo if the pattern replacement is being
- // used to jettison a chain result, since morphing the node in place
- // would leave users of the chain dangling.
- //
- if (!isRoot || (InputHasChain && !NodeHasChain)) {
- Code = "CurDAG->getMachineNode(" + Code;
- } else {
- Code = "CurDAG->SelectNodeTo(N, " + Code;
- }
- if (isRoot) {
- if (After.empty())
- CodePrefix = "return ";
- else
- After.push_back("return ResNode;");
- }
-
- emitCode(CodePrefix + Code + ");");
-
- if (GenDebug) {
- if (!isRoot) {
- emitCode("CurDAG->setSubgraphColor(" + NodeName +".getNode(), \"yellow\");");
- emitCode("CurDAG->setSubgraphColor(" + NodeName +".getNode(), \"black\");");
- }
- else {
- emitCode("CurDAG->setSubgraphColor(" + NodeName +", \"yellow\");");
- emitCode("CurDAG->setSubgraphColor(" + NodeName +", \"black\");");
- }
- }
-
- for (unsigned i = 0, e = After.size(); i != e; ++i)
- emitCode(After[i]);
-
- return NodeOps;
}
- if (Op->isSubClassOf("SDNodeXForm")) {
- assert(N->getNumChildren() == 1 && "node xform should have one child!");
- // PatLeaf node - the operand may or may not be a leaf node. But it should
- // behave like one.
- std::vector<std::string> Ops =
- EmitResultCode(N->getChild(0), DstRegs, InFlagDecled,
- ResNodeDecled, true);
- unsigned ResNo = TmpNo++;
- emitCode("SDValue Tmp" + utostr(ResNo) + " = Transform_" + Op->getName()
- + "(" + Ops.back() + ".getNode());");
- NodeOps.push_back("Tmp" + utostr(ResNo));
- if (isRoot)
- emitCode("return Tmp" + utostr(ResNo) + ".getNode();");
- return NodeOps;
- }
-
- N->dump();
- errs() << "\n";
- throw std::string("Unknown node in result pattern!");
- }
-
- /// InsertOneTypeCheck - Insert a type-check for an unresolved type in 'Pat'
- /// and add it to the tree. 'Pat' and 'Other' are isomorphic trees except that
- /// 'Pat' may be missing types. If we find an unresolved type to add a check
- /// for, this returns true otherwise false if Pat has all types.
- bool InsertOneTypeCheck(TreePatternNode *Pat, TreePatternNode *Other,
- const std::string &Prefix, bool isRoot = false) {
- // Did we find one?
- if (Pat->getExtTypes() != Other->getExtTypes()) {
- // Move a type over from 'other' to 'pat'.
- Pat->setTypes(Other->getExtTypes());
- // The top level node type is checked outside of the select function.
+
+ if (ChainAssignmentNeeded) {
+ // Remember which op produces the chain.
+ std::string ChainAssign;
if (!isRoot)
- emitCheck(Prefix + ".getValueType() == " +
- getName(Pat->getTypeNum(0)));
- return true;
+ ChainAssign = ChainName + " = SDValue(" + NodeName +
+ ".getNode(), " + utostr(NumResults+NumDstRegs) + ");";
+ else
+ ChainAssign = ChainName + " = SDValue(" + NodeName +
+ ", " + utostr(NumResults+NumDstRegs) + ");";
+
+ After.push_front(ChainAssign);
}
-
- unsigned OpNo =
- (unsigned) NodeHasProperty(Pat, SDNPHasChain, CGP);
- for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i, ++OpNo)
- if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i),
- Prefix + utostr(OpNo)))
- return true;
- return false;
- }
-
-private:
- /// EmitInFlagSelectCode - Emit the flag operands for the DAG that is
- /// being built.
- void EmitInFlagSelectCode(TreePatternNode *N, const std::string &RootName,
- bool &ChainEmitted, bool &InFlagDecled,
- bool &ResNodeDecled, bool isRoot = false) {
- const CodeGenTarget &T = CGP.getTargetInfo();
- unsigned OpNo =
- (unsigned) NodeHasProperty(N, SDNPHasChain, CGP);
- bool HasInFlag = NodeHasProperty(N, SDNPInFlag, CGP);
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
- TreePatternNode *Child = N->getChild(i);
- if (!Child->isLeaf()) {
- EmitInFlagSelectCode(Child, RootName + utostr(OpNo), ChainEmitted,
- InFlagDecled, ResNodeDecled);
+
+ if (ReplaceFroms.size() == 1) {
+ After.push_back("ReplaceUses(" + ReplaceFroms[0] + ", " +
+ ReplaceTos[0] + ");");
+ } else if (!ReplaceFroms.empty()) {
+ After.push_back("const SDValue Froms[] = {");
+ for (unsigned i = 0, e = ReplaceFroms.size(); i != e; ++i)
+ After.push_back(" " + ReplaceFroms[i] + (i + 1 != e ? "," : ""));
+ After.push_back("};");
+ After.push_back("const SDValue Tos[] = {");
+ for (unsigned i = 0, e = ReplaceFroms.size(); i != e; ++i)
+ After.push_back(" " + ReplaceTos[i] + (i + 1 != e ? "," : ""));
+ After.push_back("};");
+ After.push_back("ReplaceUses(Froms, Tos, " +
+ itostr(ReplaceFroms.size()) + ");");
+ }
+
+ // We prefer to use SelectNodeTo since it avoids allocation when
+ // possible and it avoids CSE map recalculation for the node's
+ // users, however it's tricky to use in a non-root context.
+ //
+ // We also don't use SelectNodeTo if the pattern replacement is being
+ // used to jettison a chain result, since morphing the node in place
+ // would leave users of the chain dangling.
+ //
+ if (!isRoot || (InputHasChain && !NodeHasChain)) {
+ Code = "CurDAG->getMachineNode(" + Code;
+ } else {
+ Code = "CurDAG->SelectNodeTo(N, " + Code;
+ }
+ if (isRoot) {
+ if (After.empty())
+ CodePrefix = "return ";
+ else
+ After.push_back("return ResNode;");
+ }
+
+ emitCode(CodePrefix + Code + ");");
+
+ if (GenDebug) {
+ if (!isRoot) {
+ emitCode("CurDAG->setSubgraphColor(" +
+ NodeName +".getNode(), \"yellow\");");
+ emitCode("CurDAG->setSubgraphColor(" +
+ NodeName +".getNode(), \"black\");");
} else {
- if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
- if (!Child->getName().empty()) {
- std::string Name = RootName + utostr(OpNo);
- if (Duplicates.find(Name) != Duplicates.end())
- // A duplicate! Do not emit a copy for this node.
- continue;
- }
-
- Record *RR = DI->getDef();
- if (RR->isSubClassOf("Register")) {
- MVT::SimpleValueType RVT = getRegisterValueType(RR, T);
- if (RVT == MVT::Flag) {
- if (!InFlagDecled) {
- emitCode("SDValue InFlag = " +
- getValueName(RootName + utostr(OpNo)) + ";");
- InFlagDecled = true;
- } else
- emitCode("InFlag = " +
- getValueName(RootName + utostr(OpNo)) + ";");
- } else {
- if (!ChainEmitted) {
- emitCode("SDValue Chain = CurDAG->getEntryNode();");
- ChainName = "Chain";
- ChainEmitted = true;
- }
- if (!InFlagDecled) {
- emitCode("SDValue InFlag(0, 0);");
- InFlagDecled = true;
- }
- std::string Decl = (!ResNodeDecled) ? "SDNode *" : "";
- emitCode(Decl + "ResNode = CurDAG->getCopyToReg(" + ChainName +
- ", " + getNodeName(RootName) + "->getDebugLoc()" +
- ", " + getQualifiedName(RR) +
- ", " + getValueName(RootName + utostr(OpNo)) +
- ", InFlag).getNode();");
- ResNodeDecled = true;
- emitCode(ChainName + " = SDValue(ResNode, 0);");
- emitCode("InFlag = SDValue(ResNode, 1);");
- }
- }
- }
+ emitCode("CurDAG->setSubgraphColor(" + NodeName +", \"yellow\");");
+ emitCode("CurDAG->setSubgraphColor(" + NodeName +", \"black\");");
}
}
-
- if (HasInFlag) {
- if (!InFlagDecled) {
- emitCode("SDValue InFlag = " + getNodeName(RootName) +
- "->getOperand(" + utostr(OpNo) + ");");
- InFlagDecled = true;
- } else
- emitCode("InFlag = " + getNodeName(RootName) +
- "->getOperand(" + utostr(OpNo) + ");");
- }
+
+ for (unsigned i = 0, e = After.size(); i != e; ++i)
+ emitCode(After[i]);
+
+ return NodeOps;
}
-};
+ if (Op->isSubClassOf("SDNodeXForm")) {
+ assert(N->getNumChildren() == 1 && "node xform should have one child!");
+ // PatLeaf node - the operand may or may not be a leaf node. But it should
+ // behave like one.
+ std::vector<std::string> Ops =
+ EmitResultCode(N->getChild(0), DstRegs, InFlagDecled,
+ ResNodeDecled, true);
+ unsigned ResNo = TmpNo++;
+ emitCode("SDValue Tmp" + utostr(ResNo) + " = Transform_" + Op->getName()
+ + "(" + Ops.back() + ".getNode());");
+ NodeOps.push_back("Tmp" + utostr(ResNo));
+ if (isRoot)
+ emitCode("return Tmp" + utostr(ResNo) + ".getNode();");
+ return NodeOps;
+ }
+
+ N->dump();
+ errs() << "\n";
+ throw std::string("Unknown node in result pattern!");
+}
+
/// EmitCodeForPattern - Given a pattern to match, emit code to the specified
/// stream to match the pattern, and generate the code for the match if it
@@ -1481,7 +1415,8 @@ void DAGISelEmitter::GenerateCodeForPattern(const PatternToMatch &Pattern,
bool FoundChain = false;
Emitter.EmitMatchCode(Pattern.getSrcPattern(), NULL, "N", "", FoundChain);
- // TP - Get *SOME* tree pattern, we don't care which.
+ // TP - Get *SOME* tree pattern, we don't care which. It is only used for
+ // diagnostics, which we know are impossible at this point.
TreePattern &TP = *CGP.pf_begin()->second;
// At this point, we know that we structurally match the pattern, but the
@@ -1497,7 +1432,7 @@ void DAGISelEmitter::GenerateCodeForPattern(const PatternToMatch &Pattern,
// types are resolved.
//
TreePatternNode *Pat = Pattern.getSrcPattern()->clone();
- RemoveAllTypes(Pat);
+ Pat->RemoveAllTypes();
do {
// Resolve/propagate as many types as possible.
@@ -1662,7 +1597,7 @@ static std::string getLegalCName(std::string OpName) {
void DAGISelEmitter::EmitInstructionSelector(raw_ostream &OS) {
const CodeGenTarget &Target = CGP.getTargetInfo();
-
+
// Get the namespace to insert instructions into.
std::string InstNS = Target.getInstNamespace();
if (!InstNS.empty()) InstNS += "::";
@@ -1674,7 +1609,6 @@ void DAGISelEmitter::EmitInstructionSelector(raw_ostream &OS) {
for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
E = CGP.ptm_end(); I != E; ++I) {
const PatternToMatch &Pattern = *I;
-
TreePatternNode *Node = Pattern.getSrcPattern();
if (!Node->isLeaf()) {
PatternsByOpcode[getOpcodeName(Node->getOperator(), CGP)].
@@ -1684,7 +1618,7 @@ void DAGISelEmitter::EmitInstructionSelector(raw_ostream &OS) {
if (dynamic_cast<IntInit*>(Node->getLeafValue())) {
PatternsByOpcode[getOpcodeName(CGP.getSDNodeNamed("imm"), CGP)].
push_back(&Pattern);
- } else if ((CP = NodeGetComplexPattern(Node, CGP))) {
+ } else if ((CP = Node->getComplexPatternInfo(CGP))) {
std::vector<Record*> OpNodes = CP->getRootNodes();
for (unsigned j = 0, e = OpNodes.size(); j != e; j++) {
PatternsByOpcode[getOpcodeName(OpNodes[j], CGP)]
@@ -1831,9 +1765,8 @@ void DAGISelEmitter::EmitInstructionSelector(raw_ostream &OS) {
// Replace the emission code within selection routines with calls to the
// emission functions.
- if (GenDebug) {
+ if (GenDebug)
GeneratedCode.push_back(std::make_pair(0, "CurDAG->setSubgraphColor(N, \"red\");"));
- }
CallerCode = "SDNode *Result = Emit_" + utostr(EmitFuncNum) + CallerCode;
GeneratedCode.push_back(std::make_pair(3, CallerCode));
if (GenDebug) {
@@ -2065,4 +1998,26 @@ void DAGISelEmitter::run(raw_ostream &OS) {
// definitions. Emit the resultant instruction selector.
EmitInstructionSelector(OS);
+#if 0
+ MatcherNode *Matcher = 0;
+ // Walk the patterns backwards, building a matcher for each and adding it to
+ // the matcher for the whole target.
+ for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
+ E = CGP.ptm_end(); I != E;) {
+ const PatternToMatch &Pattern = *--E;
+ MatcherNode *N = ConvertPatternToMatcher(Pattern, CGP);
+
+ if (Matcher == 0)
+ Matcher = N;
+ else
+ Matcher = new PushMatcherNode(N, Matcher);
+ }
+
+
+ EmitMatcherTable(Matcher, OS);
+
+
+ //Matcher->dump();
+ delete Matcher;
+#endif
}
diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp
new file mode 100644
index 0000000..3f75558
--- /dev/null
+++ b/utils/TableGen/DAGISelMatcher.cpp
@@ -0,0 +1,118 @@
+//===- DAGISelMatcher.cpp - Representation of DAG pattern matcher ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "CodeGenTarget.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+void MatcherNode::dump() const {
+ print(errs());
+}
+
+void EmitNodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "EmitNode: Src = " << *Pattern.getSrcPattern() << "\n";
+ OS.indent(indent) << "EmitNode: Dst = " << *Pattern.getDstPattern() << "\n";
+}
+
+void MatcherNodeWithChild::printChild(raw_ostream &OS, unsigned indent) const {
+ if (Child)
+ return Child->print(OS, indent);
+ OS.indent(indent) << "<null child>\n";
+}
+
+
+void PushMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "Push\n";
+ printChild(OS, indent+2);
+ Failure->print(OS, indent);
+}
+
+void RecordMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "Record\n";
+ printChild(OS, indent);
+}
+
+void MoveChildMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "MoveChild " << ChildNo << '\n';
+ printChild(OS, indent);
+}
+
+void MoveParentMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "MoveParent\n";
+ printChild(OS, indent);
+}
+
+void CheckSameMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckSame " << MatchNumber << '\n';
+ printChild(OS, indent);
+}
+
+void CheckPatternPredicateMatcherNode::
+print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckPatternPredicate " << Predicate << '\n';
+ printChild(OS, indent);
+}
+
+void CheckPredicateMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckPredicate " << PredName << '\n';
+ printChild(OS, indent);
+}
+
+void CheckOpcodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckOpcode " << OpcodeName << '\n';
+ printChild(OS, indent);
+}
+
+void CheckTypeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n';
+ printChild(OS, indent);
+}
+
+void CheckIntegerMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckInteger " << Value << '\n';
+ printChild(OS, indent);
+}
+
+void CheckCondCodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckCondCode ISD::" << CondCodeName << '\n';
+ printChild(OS, indent);
+}
+
+void CheckValueTypeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckValueType MVT::" << TypeName << '\n';
+ printChild(OS, indent);
+}
+
+void CheckComplexPatMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckComplexPat " << Pattern.getSelectFunc() << '\n';
+ printChild(OS, indent);
+}
+
+void CheckAndImmMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckAndImm " << Value << '\n';
+ printChild(OS, indent);
+}
+
+void CheckOrImmMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CheckOrImm " << Value << '\n';
+ printChild(OS, indent);
+}
+
+void CheckProfitableToFoldMatcherNode::print(raw_ostream &OS,
+ unsigned indent) const {
+ OS.indent(indent) << "CheckProfitableToFold\n";
+ printChild(OS, indent);
+}
+
+void CheckLegalToFoldMatcherNode::print(raw_ostream &OS, unsigned indent) const{
+ OS.indent(indent) << "CheckLegalToFold\n";
+ printChild(OS, indent);
+}
diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h
new file mode 100644
index 0000000..b40fbf9
--- /dev/null
+++ b/utils/TableGen/DAGISelMatcher.h
@@ -0,0 +1,391 @@
+//===- DAGISelMatcher.h - Representation of DAG pattern matcher -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TBLGEN_DAGISELMATCHER_H
+#define TBLGEN_DAGISELMATCHER_H
+
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+ class CodeGenDAGPatterns;
+ class MatcherNode;
+ class PatternToMatch;
+ class raw_ostream;
+ class ComplexPattern;
+
+MatcherNode *ConvertPatternToMatcher(const PatternToMatch &Pattern,
+ const CodeGenDAGPatterns &CGP);
+
+void EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &OS);
+
+
+/// MatcherNode - Base class for all the the DAG ISel Matcher representation
+/// nodes.
+class MatcherNode {
+public:
+ enum KindTy {
+ EmitNode,
+ Push, // [Push, Dest0, Dest1, Dest2, Dest3]
+ Record, // [Record]
+ MoveChild, // [MoveChild, Child#]
+ MoveParent, // [MoveParent]
+
+ CheckSame, // [CheckSame, N] Fail if not same as prev match.
+ CheckPatternPredicate,
+ CheckPredicate, // [CheckPredicate, P] Fail if predicate fails.
+ CheckOpcode, // [CheckOpcode, Opcode] Fail if not opcode.
+ CheckType, // [CheckType, MVT] Fail if not correct type.
+ CheckInteger, // [CheckInteger, int0,int1,int2,...int7] Fail if wrong val.
+ CheckCondCode, // [CheckCondCode, CondCode] Fail if not condcode.
+ CheckValueType,
+ CheckComplexPat,
+ CheckAndImm,
+ CheckOrImm,
+ CheckProfitableToFold,
+ CheckLegalToFold
+ };
+ const KindTy Kind;
+
+protected:
+ MatcherNode(KindTy K) : Kind(K) {}
+public:
+ virtual ~MatcherNode() {}
+
+ KindTy getKind() const { return Kind; }
+
+
+ static inline bool classof(const MatcherNode *) { return true; }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const = 0;
+ void dump() const;
+};
+
+/// EmitNodeMatcherNode - This signals a successful match and generates a node.
+class EmitNodeMatcherNode : public MatcherNode {
+ const PatternToMatch &Pattern;
+public:
+ EmitNodeMatcherNode(const PatternToMatch &pattern)
+ : MatcherNode(EmitNode), Pattern(pattern) {}
+
+ const PatternToMatch &getPattern() const { return Pattern; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == EmitNode;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// MatcherNodeWithChild - Every node accept the final accept state has a child
+/// that is executed after the node runs. This class captures this commonality.
+class MatcherNodeWithChild : public MatcherNode {
+ OwningPtr<MatcherNode> Child;
+public:
+ MatcherNodeWithChild(KindTy K) : MatcherNode(K) {}
+
+ MatcherNode *getChild() { return Child.get(); }
+ const MatcherNode *getChild() const { return Child.get(); }
+ void setChild(MatcherNode *C) { Child.reset(C); }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() != EmitNode;
+ }
+
+protected:
+ void printChild(raw_ostream &OS, unsigned indent) const;
+};
+
+/// PushMatcherNode - This pushes a failure scope on the stack and evaluates
+/// 'child'. If 'child' fails to match, it pops its scope and attempts to
+/// match 'Failure'.
+class PushMatcherNode : public MatcherNodeWithChild {
+ OwningPtr<MatcherNode> Failure;
+public:
+ PushMatcherNode(MatcherNode *child = 0, MatcherNode *failure = 0)
+ : MatcherNodeWithChild(Push), Failure(failure) {
+ setChild(child);
+ }
+
+ MatcherNode *getFailure() { return Failure.get(); }
+ const MatcherNode *getFailure() const { return Failure.get(); }
+ void setFailure(MatcherNode *N) { Failure.reset(N); }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == Push;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// RecordMatcherNode - Save the current node in the operand list.
+class RecordMatcherNode : public MatcherNodeWithChild {
+public:
+ RecordMatcherNode() : MatcherNodeWithChild(Record) {}
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == Record;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// MoveChildMatcherNode - This tells the interpreter to move into the
+/// specified child node.
+class MoveChildMatcherNode : public MatcherNodeWithChild {
+ unsigned ChildNo;
+public:
+ MoveChildMatcherNode(unsigned childNo)
+ : MatcherNodeWithChild(MoveChild), ChildNo(childNo) {}
+
+ unsigned getChildNo() const { return ChildNo; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == MoveChild;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// MoveParentMatcherNode - This tells the interpreter to move to the parent
+/// of the current node.
+class MoveParentMatcherNode : public MatcherNodeWithChild {
+public:
+ MoveParentMatcherNode()
+ : MatcherNodeWithChild(MoveParent) {}
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == MoveParent;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckSameMatcherNode - This checks to see if this node is exactly the same
+/// node as the specified match that was recorded with 'Record'. This is used
+/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
+class CheckSameMatcherNode : public MatcherNodeWithChild {
+ unsigned MatchNumber;
+public:
+ CheckSameMatcherNode(unsigned matchnumber)
+ : MatcherNodeWithChild(CheckSame), MatchNumber(matchnumber) {}
+
+ unsigned getMatchNumber() const { return MatchNumber; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckSame;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckPatternPredicateMatcherNode - This checks the target-specific predicate
+/// to see if the entire pattern is capable of matching. This predicate does
+/// not take a node as input. This is used for subtarget feature checks etc.
+class CheckPatternPredicateMatcherNode : public MatcherNodeWithChild {
+ std::string Predicate;
+public:
+ CheckPatternPredicateMatcherNode(StringRef predicate)
+ : MatcherNodeWithChild(CheckPatternPredicate), Predicate(predicate) {}
+
+ StringRef getPredicate() const { return Predicate; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckPatternPredicate;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckPredicateMatcherNode - This checks the target-specific predicate to
+/// see if the node is acceptable.
+class CheckPredicateMatcherNode : public MatcherNodeWithChild {
+ StringRef PredName;
+public:
+ CheckPredicateMatcherNode(StringRef predname)
+ : MatcherNodeWithChild(CheckPredicate), PredName(predname) {}
+
+ StringRef getPredicateName() const { return PredName; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckPredicate;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+
+/// CheckOpcodeMatcherNode - This checks to see if the current node has the
+/// specified opcode, if not it fails to match.
+class CheckOpcodeMatcherNode : public MatcherNodeWithChild {
+ StringRef OpcodeName;
+public:
+ CheckOpcodeMatcherNode(StringRef opcodename)
+ : MatcherNodeWithChild(CheckOpcode), OpcodeName(opcodename) {}
+
+ StringRef getOpcodeName() const { return OpcodeName; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckOpcode;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckTypeMatcherNode - This checks to see if the current node has the
+/// specified type, if not it fails to match.
+class CheckTypeMatcherNode : public MatcherNodeWithChild {
+ MVT::SimpleValueType Type;
+public:
+ CheckTypeMatcherNode(MVT::SimpleValueType type)
+ : MatcherNodeWithChild(CheckType), Type(type) {}
+
+ MVT::SimpleValueType getType() const { return Type; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckType;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckIntegerMatcherNode - This checks to see if the current node is a
+/// ConstantSDNode with the specified integer value, if not it fails to match.
+class CheckIntegerMatcherNode : public MatcherNodeWithChild {
+ int64_t Value;
+public:
+ CheckIntegerMatcherNode(int64_t value)
+ : MatcherNodeWithChild(CheckInteger), Value(value) {}
+
+ int64_t getValue() const { return Value; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckInteger;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckCondCodeMatcherNode - This checks to see if the current node is a
+/// CondCodeSDNode with the specified condition, if not it fails to match.
+class CheckCondCodeMatcherNode : public MatcherNodeWithChild {
+ StringRef CondCodeName;
+public:
+ CheckCondCodeMatcherNode(StringRef condcodename)
+ : MatcherNodeWithChild(CheckCondCode), CondCodeName(condcodename) {}
+
+ StringRef getCondCodeName() const { return CondCodeName; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckCondCode;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckValueTypeMatcherNode - This checks to see if the current node is a
+/// VTSDNode with the specified type, if not it fails to match.
+class CheckValueTypeMatcherNode : public MatcherNodeWithChild {
+ StringRef TypeName;
+public:
+ CheckValueTypeMatcherNode(StringRef type_name)
+ : MatcherNodeWithChild(CheckValueType), TypeName(type_name) {}
+
+ StringRef getTypeName() const { return TypeName; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckValueType;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+
+
+/// CheckComplexPatMatcherNode - This node runs the specified ComplexPattern on
+/// the current node.
+class CheckComplexPatMatcherNode : public MatcherNodeWithChild {
+ const ComplexPattern &Pattern;
+public:
+ CheckComplexPatMatcherNode(const ComplexPattern &pattern)
+ : MatcherNodeWithChild(CheckComplexPat), Pattern(pattern) {}
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckComplexPat;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckAndImmMatcherNode - This checks to see if the current node is an 'and'
+/// with something equivalent to the specified immediate.
+class CheckAndImmMatcherNode : public MatcherNodeWithChild {
+ int64_t Value;
+public:
+ CheckAndImmMatcherNode(int64_t value)
+ : MatcherNodeWithChild(CheckAndImm), Value(value) {}
+
+ int64_t getValue() const { return Value; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckAndImm;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckOrImmMatcherNode - This checks to see if the current node is an 'and'
+/// with something equivalent to the specified immediate.
+class CheckOrImmMatcherNode : public MatcherNodeWithChild {
+ int64_t Value;
+public:
+ CheckOrImmMatcherNode(int64_t value)
+ : MatcherNodeWithChild(CheckOrImm), Value(value) {}
+
+ int64_t getValue() const { return Value; }
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckOrImm;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckProfitableToFoldMatcherNode - This checks to see if the current node is
+/// worthwhile to try to fold into a large pattern.
+class CheckProfitableToFoldMatcherNode : public MatcherNodeWithChild {
+public:
+ CheckProfitableToFoldMatcherNode()
+ : MatcherNodeWithChild(CheckProfitableToFold) {}
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckProfitableToFold;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckLegalToFoldMatcherNode - This checks to see if the current node is
+/// legal to try to fold into a large pattern.
+class CheckLegalToFoldMatcherNode : public MatcherNodeWithChild {
+public:
+ CheckLegalToFoldMatcherNode()
+ : MatcherNodeWithChild(CheckLegalToFold) {}
+
+ static inline bool classof(const MatcherNode *N) {
+ return N->getKind() == CheckLegalToFold;
+ }
+
+ virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+} // end namespace llvm
+
+#endif
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
new file mode 100644
index 0000000..c0ad169
--- /dev/null
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -0,0 +1,278 @@
+//===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains code to generate C++ code a matcher.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/FormattedStream.h"
+using namespace llvm;
+
+namespace {
+enum {
+ CommentIndent = 25
+};
+}
+
+/// ClassifyInt - Classify an integer by size, return '1','2','4','8' if this
+/// fits in 1, 2, 4, or 8 sign extended bytes.
+static char ClassifyInt(int64_t Val) {
+ if (Val == int8_t(Val)) return '1';
+ if (Val == int16_t(Val)) return '2';
+ if (Val == int32_t(Val)) return '4';
+ return '8';
+}
+
+/// EmitInt - Emit the specified integer, returning the number of bytes emitted.
+static unsigned EmitInt(int64_t Val, formatted_raw_ostream &OS) {
+ unsigned BytesEmitted = 1;
+ OS << (int)(unsigned char)Val << ", ";
+ if (Val == int8_t(Val)) {
+ OS << "\n";
+ return BytesEmitted;
+ }
+
+ OS << (int)(unsigned char)(Val >> 8) << ", ";
+ ++BytesEmitted;
+
+ if (Val != int16_t(Val)) {
+ OS << (int)(unsigned char)(Val >> 16) << ','
+ << (int)(unsigned char)(Val >> 24) << ',';
+ BytesEmitted += 2;
+
+ if (Val != int32_t(Val)) {
+ OS << (int)(unsigned char)(Val >> 32) << ','
+ << (int)(unsigned char)(Val >> 40) << ','
+ << (int)(unsigned char)(Val >> 48) << ','
+ << (int)(unsigned char)(Val >> 56) << ',';
+ BytesEmitted += 4;
+ }
+ }
+
+ OS.PadToColumn(CommentIndent) << "// " << Val << '\n';
+ return BytesEmitted;
+}
+
+namespace {
+class MatcherTableEmitter {
+ formatted_raw_ostream &OS;
+
+ StringMap<unsigned> NodePredicateMap, PatternPredicateMap;
+ std::vector<std::string> NodePredicates, PatternPredicates;
+
+public:
+ MatcherTableEmitter(formatted_raw_ostream &os) : OS(os) {}
+
+ unsigned EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent);
+
+ void EmitPredicateFunctions();
+private:
+ unsigned EmitMatcher(const MatcherNode *N, unsigned Indent);
+
+ unsigned getNodePredicate(StringRef PredName) {
+ unsigned &Entry = NodePredicateMap[PredName];
+ if (Entry == 0) {
+ NodePredicates.push_back(PredName.str());
+ Entry = NodePredicates.size();
+ }
+ return Entry-1;
+ }
+ unsigned getPatternPredicate(StringRef PredName) {
+ unsigned &Entry = PatternPredicateMap[PredName];
+ if (Entry == 0) {
+ PatternPredicates.push_back(PredName.str());
+ Entry = PatternPredicates.size();
+ }
+ return Entry-1;
+ }
+};
+} // end anonymous namespace.
+
+/// EmitMatcherOpcodes - Emit bytes for the specified matcher and return
+/// the number of bytes emitted.
+unsigned MatcherTableEmitter::
+EmitMatcher(const MatcherNode *N, unsigned Indent) {
+ OS.PadToColumn(Indent*2);
+
+ switch (N->getKind()) {
+ case MatcherNode::Push: assert(0 && "Should be handled by caller");
+ case MatcherNode::EmitNode:
+ OS << "OPC_Emit, /*XXX*/";
+ OS.PadToColumn(CommentIndent) << "// Src: "
+ << *cast<EmitNodeMatcherNode>(N)->getPattern().getSrcPattern() << '\n';
+ OS.PadToColumn(CommentIndent) << "// Dst: "
+ << *cast<EmitNodeMatcherNode>(N)->getPattern().getDstPattern() << '\n';
+ return 1;
+ case MatcherNode::Record:
+ OS << "OPC_Record,\n";
+ return 1;
+ case MatcherNode::MoveChild:
+ OS << "OPC_MoveChild, "
+ << cast<MoveChildMatcherNode>(N)->getChildNo() << ",\n";
+ return 2;
+
+ case MatcherNode::MoveParent:
+ OS << "OPC_MoveParent,\n";
+ return 1;
+
+ case MatcherNode::CheckSame:
+ OS << "OPC_CheckSame, "
+ << cast<CheckSameMatcherNode>(N)->getMatchNumber() << ",\n";
+ return 2;
+
+ case MatcherNode::CheckPatternPredicate: {
+ StringRef Pred = cast<CheckPatternPredicateMatcherNode>(N)->getPredicate();
+ OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
+ OS.PadToColumn(CommentIndent) << "// " << Pred << '\n';
+ return 2;
+ }
+ case MatcherNode::CheckPredicate: {
+ StringRef Pred = cast<CheckPredicateMatcherNode>(N)->getPredicateName();
+ OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ',';
+ OS.PadToColumn(CommentIndent) << "// " << Pred << '\n';
+ return 2;
+ }
+
+ case MatcherNode::CheckOpcode:
+ OS << "OPC_CheckOpcode, "
+ << cast<CheckOpcodeMatcherNode>(N)->getOpcodeName() << ",\n";
+ return 2;
+
+ case MatcherNode::CheckType:
+ OS << "OPC_CheckType, "
+ << getEnumName(cast<CheckTypeMatcherNode>(N)->getType()) << ",\n";
+ return 2;
+
+ case MatcherNode::CheckInteger: {
+ int64_t Val = cast<CheckIntegerMatcherNode>(N)->getValue();
+ OS << "OPC_CheckInteger" << ClassifyInt(Val) << ", ";
+ return EmitInt(Val, OS)+1;
+ }
+ case MatcherNode::CheckCondCode:
+ OS << "OPC_CheckCondCode, ISD::"
+ << cast<CheckCondCodeMatcherNode>(N)->getCondCodeName() << ",\n";
+ return 2;
+
+ case MatcherNode::CheckValueType:
+ OS << "OPC_CheckValueType, MVT::"
+ << cast<CheckValueTypeMatcherNode>(N)->getTypeName() << ",\n";
+ return 2;
+
+ case MatcherNode::CheckComplexPat:
+ OS << "OPC_CheckComplexPat, 0/*XXX*/,\n";
+ return 2;
+
+ case MatcherNode::CheckAndImm: {
+ int64_t Val = cast<CheckAndImmMatcherNode>(N)->getValue();
+ OS << "OPC_CheckAndImm" << ClassifyInt(Val) << ", ";
+ return EmitInt(Val, OS)+1;
+ }
+
+ case MatcherNode::CheckOrImm: {
+ int64_t Val = cast<CheckOrImmMatcherNode>(N)->getValue();
+ OS << "OPC_CheckOrImm" << ClassifyInt(Val) << ", ";
+ return EmitInt(Val, OS)+1;
+ }
+ case MatcherNode::CheckProfitableToFold:
+ OS << "OPC_IsProfitableToFold,\n";
+ return 1;
+ case MatcherNode::CheckLegalToFold:
+ OS << "OPC_IsLegalToFold,\n";
+ return 1;
+ }
+ assert(0 && "Unreachable");
+ return 0;
+}
+
+/// EmitMatcherAndChildren - Emit the bytes for the specified matcher subtree.
+unsigned MatcherTableEmitter::
+EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent) {
+ unsigned Size = 0;
+ while (1) {
+ // Push is a special case since it is binary.
+ if (const PushMatcherNode *PMN = dyn_cast<PushMatcherNode>(N)) {
+ // We need to encode the child and the offset of the failure code before
+ // emitting either of them. Handle this by buffering the output into a
+ // string while we get the size.
+ SmallString<128> TmpBuf;
+ unsigned ChildSize;
+ {
+ raw_svector_ostream OS(TmpBuf);
+ formatted_raw_ostream FOS(OS);
+ ChildSize =
+ EmitMatcherAndChildren(cast<PushMatcherNode>(N)->getChild(),Indent+1);
+ }
+
+ if (ChildSize > 255) {
+ errs() <<
+ "Tblgen internal error: can't handle predicate this complex yet\n";
+ exit(1);
+ }
+
+ OS.PadToColumn(Indent*2);
+ OS << "OPC_Push, " << ChildSize << ",\n";
+ OS << TmpBuf.str();
+
+ Size += 2 + ChildSize;
+
+ N = PMN->getFailure();
+ continue;
+ }
+
+ Size += EmitMatcher(N, Indent);
+
+ // If there are children of this node, iterate to them, otherwise we're
+ // done.
+ if (const MatcherNodeWithChild *MNWC = dyn_cast<MatcherNodeWithChild>(N))
+ N = MNWC->getChild();
+ else
+ return Size;
+ }
+}
+
+void MatcherTableEmitter::EmitPredicateFunctions() {
+ OS << "bool CheckPatternPredicate(unsigned PredNo) const {\n";
+ OS << " switch (PredNo) {\n";
+ OS << " default: assert(0 && \"Invalid predicate in table?\");\n";
+ for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)
+ OS << " case " << i << ": return " << PatternPredicates[i] << ";\n";
+ OS << " }\n";
+ OS << "}\n\n";
+
+ OS << "bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {\n";
+ OS << " switch (PredNo) {\n";
+ OS << " default: assert(0 && \"Invalid predicate in table?\");\n";
+ for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i)
+ OS << " case " << i << ": return " << NodePredicates[i] << "(N);\n";
+ OS << " }\n";
+ OS << "}\n\n";
+}
+
+
+void llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) {
+ formatted_raw_ostream OS(O);
+
+ OS << "// The main instruction selector code.\n";
+ OS << "SDNode *SelectCode2(SDNode *N) {\n";
+
+ MatcherTableEmitter MatcherEmitter(OS);
+
+ OS << " static const unsigned char MatcherTable[] = {\n";
+ unsigned TotalSize = MatcherEmitter.EmitMatcherAndChildren(Matcher, 2);
+ OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
+ OS << " return SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n}\n";
+ OS << "\n";
+
+ // Next up, emit the function for node and pattern predicates:
+ MatcherEmitter.EmitPredicateFunctions();
+}
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
new file mode 100644
index 0000000..07ab472
--- /dev/null
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -0,0 +1,328 @@
+//===- DAGISelMatcherGen.cpp - Matcher generator --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DAGISelMatcher.h"
+#include "CodeGenDAGPatterns.h"
+#include "Record.h"
+#include "llvm/ADT/StringMap.h"
+using namespace llvm;
+
+namespace {
+ class MatcherGen {
+ const PatternToMatch &Pattern;
+ const CodeGenDAGPatterns &CGP;
+
+ /// PatWithNoTypes - This is a clone of Pattern.getSrcPattern() that starts
+ /// out with all of the types removed. This allows us to insert type checks
+ /// as we scan the tree.
+ TreePatternNode *PatWithNoTypes;
+
+ /// VariableMap - A map from variable names ('$dst') to the recorded operand
+ /// number that they were captured as. These are biased by 1 to make
+ /// insertion easier.
+ StringMap<unsigned> VariableMap;
+ unsigned NextRecordedOperandNo;
+
+ MatcherNodeWithChild *Matcher;
+ MatcherNodeWithChild *CurPredicate;
+ public:
+ MatcherGen(const PatternToMatch &pattern, const CodeGenDAGPatterns &cgp);
+
+ ~MatcherGen() {
+ delete PatWithNoTypes;
+ }
+
+ void EmitMatcherCode();
+
+ MatcherNodeWithChild *GetMatcher() const { return Matcher; }
+ MatcherNodeWithChild *GetCurPredicate() const { return CurPredicate; }
+ private:
+ void AddMatcherNode(MatcherNodeWithChild *NewNode);
+ void InferPossibleTypes();
+ void EmitMatchCode(const TreePatternNode *N, TreePatternNode *NodeNoTypes);
+ void EmitLeafMatchCode(const TreePatternNode *N);
+ void EmitOperatorMatchCode(const TreePatternNode *N,
+ TreePatternNode *NodeNoTypes);
+ };
+
+} // end anon namespace.
+
+MatcherGen::MatcherGen(const PatternToMatch &pattern,
+ const CodeGenDAGPatterns &cgp)
+: Pattern(pattern), CGP(cgp), NextRecordedOperandNo(0),
+ Matcher(0), CurPredicate(0) {
+ // We need to produce the matcher tree for the patterns source pattern. To do
+ // this we need to match the structure as well as the types. To do the type
+ // matching, we want to figure out the fewest number of type checks we need to
+ // emit. For example, if there is only one integer type supported by a
+ // target, there should be no type comparisons at all for integer patterns!
+ //
+ // To figure out the fewest number of type checks needed, clone the pattern,
+ // remove the types, then perform type inference on the pattern as a whole.
+ // If there are unresolved types, emit an explicit check for those types,
+ // apply the type to the tree, then rerun type inference. Iterate until all
+ // types are resolved.
+ //
+ PatWithNoTypes = Pattern.getSrcPattern()->clone();
+ PatWithNoTypes->RemoveAllTypes();
+
+ // If there are types that are manifestly known, infer them.
+ InferPossibleTypes();
+}
+
+/// InferPossibleTypes - As we emit the pattern, we end up generating type
+/// checks and applying them to the 'PatWithNoTypes' tree. As we do this, we
+/// want to propagate implied types as far throughout the tree as possible so
+/// that we avoid doing redundant type checks. This does the type propagation.
+void MatcherGen::InferPossibleTypes() {
+ // TP - Get *SOME* tree pattern, we don't care which. It is only used for
+ // diagnostics, which we know are impossible at this point.
+ TreePattern &TP = *CGP.pf_begin()->second;
+
+ try {
+ bool MadeChange = true;
+ while (MadeChange)
+ MadeChange = PatWithNoTypes->ApplyTypeConstraints(TP,
+ true/*Ignore reg constraints*/);
+ } catch (...) {
+ errs() << "Type constraint application shouldn't fail!";
+ abort();
+ }
+}
+
+
+/// AddMatcherNode - Add a matcher node to the current graph we're building.
+void MatcherGen::AddMatcherNode(MatcherNodeWithChild *NewNode) {
+ if (CurPredicate != 0)
+ CurPredicate->setChild(NewNode);
+ else
+ Matcher = NewNode;
+ CurPredicate = NewNode;
+}
+
+
+
+/// EmitLeafMatchCode - Generate matching code for leaf nodes.
+void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
+ assert(N->isLeaf() && "Not a leaf?");
+ // Direct match against an integer constant.
+ if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue()))
+ return AddMatcherNode(new CheckIntegerMatcherNode(II->getValue()));
+
+ DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue());
+ if (DI == 0) {
+ errs() << "Unknown leaf kind: " << *DI << "\n";
+ abort();
+ }
+
+ Record *LeafRec = DI->getDef();
+ if (// Handle register references. Nothing to do here, they always match.
+ LeafRec->isSubClassOf("RegisterClass") ||
+ LeafRec->isSubClassOf("PointerLikeRegClass") ||
+ LeafRec->isSubClassOf("Register") ||
+ // Place holder for SRCVALUE nodes. Nothing to do here.
+ LeafRec->getName() == "srcvalue")
+ return;
+
+ if (LeafRec->isSubClassOf("ValueType"))
+ return AddMatcherNode(new CheckValueTypeMatcherNode(LeafRec->getName()));
+
+ if (LeafRec->isSubClassOf("CondCode"))
+ return AddMatcherNode(new CheckCondCodeMatcherNode(LeafRec->getName()));
+
+ if (LeafRec->isSubClassOf("ComplexPattern")) {
+ // Handle complex pattern.
+ const ComplexPattern &CP = CGP.getComplexPattern(LeafRec);
+ return AddMatcherNode(new CheckComplexPatMatcherNode(CP));
+ }
+
+ errs() << "Unknown leaf kind: " << *N << "\n";
+ abort();
+}
+
+void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
+ TreePatternNode *NodeNoTypes) {
+ assert(!N->isLeaf() && "Not an operator?");
+ const SDNodeInfo &CInfo = CGP.getSDNodeInfo(N->getOperator());
+
+ // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
+ // a constant without a predicate fn that has more that one bit set, handle
+ // this as a special case. This is usually for targets that have special
+ // handling of certain large constants (e.g. alpha with it's 8/16/32-bit
+ // handling stuff). Using these instructions is often far more efficient
+ // than materializing the constant. Unfortunately, both the instcombiner
+ // and the dag combiner can often infer that bits are dead, and thus drop
+ // them from the mask in the dag. For example, it might turn 'AND X, 255'
+ // into 'AND X, 254' if it knows the low bit is set. Emit code that checks
+ // to handle this.
+ if ((N->getOperator()->getName() == "and" ||
+ N->getOperator()->getName() == "or") &&
+ N->getChild(1)->isLeaf() && N->getChild(1)->getPredicateFns().empty()) {
+ if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
+ if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits.
+ if (N->getOperator()->getName() == "and")
+ AddMatcherNode(new CheckAndImmMatcherNode(II->getValue()));
+ else
+ AddMatcherNode(new CheckOrImmMatcherNode(II->getValue()));
+
+ // Match the LHS of the AND as appropriate.
+ AddMatcherNode(new MoveChildMatcherNode(0));
+ EmitMatchCode(N->getChild(0), NodeNoTypes->getChild(0));
+ AddMatcherNode(new MoveParentMatcherNode());
+ return;
+ }
+ }
+ }
+
+ // Check that the current opcode lines up.
+ AddMatcherNode(new CheckOpcodeMatcherNode(CInfo.getEnumName()));
+
+ // If this node has a chain, then the chain is operand #0 is the SDNode, and
+ // the child numbers of the node are all offset by one.
+ unsigned OpNo = 0;
+ if (N->NodeHasProperty(SDNPHasChain, CGP))
+ OpNo = 1;
+
+ // If this node is not the root and the subtree underneath it produces a
+ // chain, then the result of matching the node is also produce a chain.
+ // Beyond that, this means that we're also folding (at least) the root node
+ // into the node that produce the chain (for example, matching
+ // "(add reg, (load ptr))" as a add_with_memory on X86). This is problematic,
+ // if the 'reg' node also uses the load (say, its chain). Graphically:
+ //
+ // [LD]
+ // ^ ^
+ // | \ DAG's like cheese.
+ // / |
+ // / [YY]
+ // | ^
+ // [XX]--/
+ //
+ // It would be invalid to fold XX and LD. In this case, folding the two
+ // nodes together would induce a cycle in the DAG, making it a cyclic DAG (!).
+ // To prevent this, we emit a dynamic check for legality before allowing this
+ // to be folded.
+ //
+ const TreePatternNode *Root = Pattern.getSrcPattern();
+ if (N != Root && // Not the root of the pattern.
+ N->TreeHasProperty(SDNPHasChain, CGP)) { // Has a chain somewhere in tree.
+
+ AddMatcherNode(new CheckProfitableToFoldMatcherNode());
+
+ // If this non-root node produces a chain, we may need to emit a validity
+ // check.
+ if (OpNo != 0) {
+ // If there is a node between the root and this node, then we definitely
+ // need to emit the check.
+ bool NeedCheck = !Root->hasChild(N);
+
+ // If it *is* an immediate child of the root, we can still need a check if
+ // the root SDNode has multiple inputs. For us, this means that it is an
+ // intrinsic, has multiple operands, or has other inputs like chain or
+ // flag).
+ if (!NeedCheck) {
+ const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Root->getOperator());
+ NeedCheck =
+ Root->getOperator() == CGP.get_intrinsic_void_sdnode() ||
+ Root->getOperator() == CGP.get_intrinsic_w_chain_sdnode() ||
+ Root->getOperator() == CGP.get_intrinsic_wo_chain_sdnode() ||
+ PInfo.getNumOperands() > 1 ||
+ PInfo.hasProperty(SDNPHasChain) ||
+ PInfo.hasProperty(SDNPInFlag) ||
+ PInfo.hasProperty(SDNPOptInFlag);
+ }
+
+ if (NeedCheck)
+ AddMatcherNode(new CheckLegalToFoldMatcherNode());
+ }
+ }
+
+ for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
+ // Get the code suitable for matching this child. Move to the child, check
+ // it then move back to the parent.
+ AddMatcherNode(new MoveChildMatcherNode(i));
+ EmitMatchCode(N->getChild(i), NodeNoTypes->getChild(i));
+ AddMatcherNode(new MoveParentMatcherNode());
+ }
+}
+
+
+void MatcherGen::EmitMatchCode(const TreePatternNode *N,
+ TreePatternNode *NodeNoTypes) {
+ // If N and NodeNoTypes don't agree on a type, then this is a case where we
+ // need to do a type check. Emit the check, apply the tyep to NodeNoTypes and
+ // reinfer any correlated types.
+ if (NodeNoTypes->getExtTypes() != N->getExtTypes()) {
+ AddMatcherNode(new CheckTypeMatcherNode(N->getTypeNum(0)));
+ NodeNoTypes->setTypes(N->getExtTypes());
+ InferPossibleTypes();
+ }
+
+
+ // If this node has a name associated with it, capture it in VariableMap. If
+ // we already saw this in the pattern, emit code to verify dagness.
+ if (!N->getName().empty()) {
+ unsigned &VarMapEntry = VariableMap[N->getName()];
+ if (VarMapEntry == 0) {
+ VarMapEntry = ++NextRecordedOperandNo;
+ AddMatcherNode(new RecordMatcherNode());
+ } else {
+ // If we get here, this is a second reference to a specific name. Since
+ // we already have checked that the first reference is valid, we don't
+ // have to recursively match it, just check that it's the same as the
+ // previously named thing.
+ AddMatcherNode(new CheckSameMatcherNode(VarMapEntry-1));
+ return;
+ }
+ }
+
+ // If there are node predicates for this node, generate their checks.
+ for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
+ AddMatcherNode(new CheckPredicateMatcherNode(N->getPredicateFns()[i]));
+
+ if (N->isLeaf())
+ EmitLeafMatchCode(N);
+ else
+ EmitOperatorMatchCode(N, NodeNoTypes);
+}
+
+void MatcherGen::EmitMatcherCode() {
+ // If the pattern has a predicate on it (e.g. only enabled when a subtarget
+ // feature is around, do the check).
+ if (!Pattern.getPredicateCheck().empty())
+ AddMatcherNode(new
+ CheckPatternPredicateMatcherNode(Pattern.getPredicateCheck()));
+
+ // Emit the matcher for the pattern structure and types.
+ EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes);
+}
+
+
+MatcherNode *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
+ const CodeGenDAGPatterns &CGP) {
+ MatcherGen Gen(Pattern, CGP);
+
+ // Generate the code for the matcher.
+ Gen.EmitMatcherCode();
+
+ // If the match succeeds, then we generate Pattern.
+ EmitNodeMatcherNode *Result = new EmitNodeMatcherNode(Pattern);
+
+ // Link it into the pattern.
+ if (MatcherNodeWithChild *Pred = Gen.GetCurPredicate()) {
+ Pred->setChild(Result);
+ return Gen.GetMatcher();
+ }
+
+ // Unconditional match.
+ return Result;
+}
+
+
+
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
new file mode 100644
index 0000000..9aad2f6
--- /dev/null
+++ b/utils/TableGen/EDEmitter.cpp
@@ -0,0 +1,665 @@
+//===- EDEmitter.cpp - Generate instruction descriptions for ED -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting a description of each
+// instruction in a format that the enhanced disassembler can use to tokenize
+// and parse instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EDEmitter.h"
+
+#include "AsmWriterInst.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <vector>
+#include <string>
+
+#define MAX_OPERANDS 5
+#define MAX_SYNTAXES 2
+
+using namespace llvm;
+
+///////////////////////////////////////////////////////////
+// Support classes for emitting nested C data structures //
+///////////////////////////////////////////////////////////
+
+namespace {
+
+ class EnumEmitter {
+ private:
+ std::string Name;
+ std::vector<std::string> Entries;
+ public:
+ EnumEmitter(const char *N) : Name(N) {
+ }
+ int addEntry(const char *e) {
+ Entries.push_back(std::string(e));
+ return Entries.size() - 1;
+ }
+ void emit(raw_ostream &o, unsigned int &i) {
+ o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
+ i += 2;
+
+ unsigned int index = 0;
+ unsigned int numEntries = Entries.size();
+ for(index = 0; index < numEntries; ++index) {
+ o.indent(i) << Entries[index];
+ if(index < (numEntries - 1))
+ o << ",";
+ o << "\n";
+ }
+
+ i -= 2;
+ o.indent(i) << "};" << "\n";
+ }
+
+ void emitAsFlags(raw_ostream &o, unsigned int &i) {
+ o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
+ i += 2;
+
+ unsigned int index = 0;
+ unsigned int numEntries = Entries.size();
+ unsigned int flag = 1;
+ for (index = 0; index < numEntries; ++index) {
+ o.indent(i) << Entries[index] << " = " << format("0x%x", flag);
+ if (index < (numEntries - 1))
+ o << ",";
+ o << "\n";
+ flag <<= 1;
+ }
+
+ i -= 2;
+ o.indent(i) << "};" << "\n";
+ }
+ };
+
+ class StructEmitter {
+ private:
+ std::string Name;
+ std::vector<std::string> MemberTypes;
+ std::vector<std::string> MemberNames;
+ public:
+ StructEmitter(const char *N) : Name(N) {
+ }
+ void addMember(const char *t, const char *n) {
+ MemberTypes.push_back(std::string(t));
+ MemberNames.push_back(std::string(n));
+ }
+ void emit(raw_ostream &o, unsigned int &i) {
+ o.indent(i) << "struct " << Name.c_str() << " {" << "\n";
+ i += 2;
+
+ unsigned int index = 0;
+ unsigned int numMembers = MemberTypes.size();
+ for (index = 0; index < numMembers; ++index) {
+ o.indent(i) << MemberTypes[index] << " " << MemberNames[index] << ";";
+ o << "\n";
+ }
+
+ i -= 2;
+ o.indent(i) << "};" << "\n";
+ }
+ };
+
+ class ConstantEmitter {
+ public:
+ virtual ~ConstantEmitter() { }
+ virtual void emit(raw_ostream &o, unsigned int &i) = 0;
+ };
+
+ class LiteralConstantEmitter : public ConstantEmitter {
+ private:
+ std::string Literal;
+ public:
+ LiteralConstantEmitter(const char *literal) : Literal(literal) {
+ }
+ LiteralConstantEmitter(int literal) {
+ char buf[256];
+ snprintf(buf, 256, "%d", literal);
+ Literal = buf;
+ }
+ void emit(raw_ostream &o, unsigned int &i) {
+ o << Literal;
+ }
+ };
+
+ class CompoundConstantEmitter : public ConstantEmitter {
+ private:
+ std::vector<ConstantEmitter*> Entries;
+ public:
+ CompoundConstantEmitter() {
+ }
+ ~CompoundConstantEmitter() {
+ unsigned int index;
+ unsigned int numEntries = Entries.size();
+ for (index = 0; index < numEntries; ++index) {
+ delete Entries[index];
+ }
+ }
+ CompoundConstantEmitter &addEntry(ConstantEmitter *e) {
+ Entries.push_back(e);
+ return *this;
+ }
+ void emit(raw_ostream &o, unsigned int &i) {
+ o << "{" << "\n";
+ i += 2;
+
+ unsigned int index;
+ unsigned int numEntries = Entries.size();
+ for (index = 0; index < numEntries; ++index) {
+ o.indent(i);
+ Entries[index]->emit(o, i);
+ if (index < (numEntries - 1))
+ o << ",";
+ o << "\n";
+ }
+
+ i -= 2;
+ o.indent(i) << "}";
+ }
+ };
+
+ class FlagsConstantEmitter : public ConstantEmitter {
+ private:
+ std::vector<std::string> Flags;
+ public:
+ FlagsConstantEmitter() {
+ }
+ FlagsConstantEmitter &addEntry(const char *f) {
+ Flags.push_back(std::string(f));
+ return *this;
+ }
+ void emit(raw_ostream &o, unsigned int &i) {
+ unsigned int index;
+ unsigned int numFlags = Flags.size();
+ if (numFlags == 0)
+ o << "0";
+
+ for (index = 0; index < numFlags; ++index) {
+ o << Flags[index].c_str();
+ if (index < (numFlags - 1))
+ o << " | ";
+ }
+ }
+ };
+}
+
+EDEmitter::EDEmitter(RecordKeeper &R) : Records(R) {
+}
+
+/// populateOperandOrder - Accepts a CodeGenInstruction and generates its
+/// AsmWriterInst for the desired assembly syntax, giving an ordered list of
+/// operands in the order they appear in the printed instruction. Then, for
+/// each entry in that list, determines the index of the same operand in the
+/// CodeGenInstruction, and emits the resulting mapping into an array, filling
+/// in unused slots with -1.
+///
+/// @arg operandOrder - The array that will be populated with the operand
+/// mapping. Each entry will contain -1 (invalid index
+/// into the operands present in the AsmString) or a number
+/// representing an index in the operand descriptor array.
+/// @arg inst - The instruction to use when looking up the operands
+/// @arg syntax - The syntax to use, according to LLVM's enumeration
+void populateOperandOrder(CompoundConstantEmitter *operandOrder,
+ const CodeGenInstruction &inst,
+ unsigned syntax) {
+ unsigned int numArgs = 0;
+
+ AsmWriterInst awInst(inst, syntax, -1, -1);
+
+ std::vector<AsmWriterOperand>::iterator operandIterator;
+
+ for (operandIterator = awInst.Operands.begin();
+ operandIterator != awInst.Operands.end();
+ ++operandIterator) {
+ if (operandIterator->OperandType ==
+ AsmWriterOperand::isMachineInstrOperand) {
+ char buf[2];
+ snprintf(buf, sizeof(buf), "%u", operandIterator->CGIOpNo);
+ operandOrder->addEntry(new LiteralConstantEmitter(buf));
+ numArgs++;
+ }
+ }
+
+ for(; numArgs < MAX_OPERANDS; numArgs++) {
+ operandOrder->addEntry(new LiteralConstantEmitter("-1"));
+ }
+}
+
+/////////////////////////////////////////////////////
+// Support functions for handling X86 instructions //
+/////////////////////////////////////////////////////
+
+#define ADDFLAG(flag) flags->addEntry(flag)
+
+#define REG(str) if (name == str) { ADDFLAG("kOperandFlagRegister"); return 0; }
+#define MEM(str) if (name == str) { ADDFLAG("kOperandFlagMemory"); return 0; }
+#define LEA(str) if (name == str) { ADDFLAG("kOperandFlagEffectiveAddress"); \
+ return 0; }
+#define IMM(str) if (name == str) { ADDFLAG("kOperandFlagImmediate"); \
+ return 0; }
+#define PCR(str) if (name == str) { ADDFLAG("kOperandFlagMemory"); \
+ ADDFLAG("kOperandFlagPCRelative"); \
+ return 0; }
+
+/// X86FlagFromOpName - Processes the name of a single X86 operand (which is
+/// actually its type) and translates it into an operand flag
+///
+/// @arg flags - The flags object to add the flag to
+/// @arg name - The name of the operand
+static int X86FlagFromOpName(FlagsConstantEmitter *flags,
+ const std::string &name) {
+ REG("GR8");
+ REG("GR8_NOREX");
+ REG("GR16");
+ REG("GR32");
+ REG("GR32_NOREX");
+ REG("FR32");
+ REG("RFP32");
+ REG("GR64");
+ REG("FR64");
+ REG("VR64");
+ REG("RFP64");
+ REG("RFP80");
+ REG("VR128");
+ REG("RST");
+ REG("SEGMENT_REG");
+ REG("DEBUG_REG");
+ REG("CONTROL_REG_32");
+ REG("CONTROL_REG_64");
+
+ MEM("i8mem");
+ MEM("i8mem_NOREX");
+ MEM("i16mem");
+ MEM("i32mem");
+ MEM("f32mem");
+ MEM("ssmem");
+ MEM("opaque32mem");
+ MEM("opaque48mem");
+ MEM("i64mem");
+ MEM("f64mem");
+ MEM("sdmem");
+ MEM("f80mem");
+ MEM("opaque80mem");
+ MEM("i128mem");
+ MEM("f128mem");
+ MEM("opaque512mem");
+
+ LEA("lea32mem");
+ LEA("lea64_32mem");
+ LEA("lea64mem");
+
+ IMM("i8imm");
+ IMM("i16imm");
+ IMM("i16i8imm");
+ IMM("i32imm");
+ IMM("i32imm_pcrel");
+ IMM("i32i8imm");
+ IMM("i64imm");
+ IMM("i64i8imm");
+ IMM("i64i32imm");
+ IMM("i64i32imm_pcrel");
+ IMM("SSECC");
+
+ PCR("brtarget8");
+ PCR("offset8");
+ PCR("offset16");
+ PCR("offset32");
+ PCR("offset64");
+ PCR("brtarget");
+
+ return 1;
+}
+
+#undef REG
+#undef MEM
+#undef LEA
+#undef IMM
+#undef PCR
+#undef ADDFLAG
+
+/// X86PopulateOperands - Handles all the operands in an X86 instruction, adding
+/// the appropriate flags to their descriptors
+///
+/// @operandFlags - A reference the array of operand flag objects
+/// @inst - The instruction to use as a source of information
+static void X86PopulateOperands(
+ FlagsConstantEmitter *(&operandFlags)[MAX_OPERANDS],
+ const CodeGenInstruction &inst) {
+ if (!inst.TheDef->isSubClassOf("X86Inst"))
+ return;
+
+ unsigned int index;
+ unsigned int numOperands = inst.OperandList.size();
+
+ for (index = 0; index < numOperands; ++index) {
+ const CodeGenInstruction::OperandInfo &operandInfo =
+ inst.OperandList[index];
+ Record &rec = *operandInfo.Rec;
+
+ if (X86FlagFromOpName(operandFlags[index], rec.getName())) {
+ errs() << "Operand type: " << rec.getName().c_str() << "\n";
+ errs() << "Operand name: " << operandInfo.Name.c_str() << "\n";
+ errs() << "Instruction mame: " << inst.TheDef->getName().c_str() << "\n";
+ llvm_unreachable("Unhandled type");
+ }
+ }
+}
+
+/// decorate1 - Decorates a named operand with a new flag
+///
+/// @operandFlags - The array of operand flag objects, which don't have names
+/// @inst - The CodeGenInstruction, which provides a way to translate
+/// between names and operand indices
+/// @opName - The name of the operand
+/// @flag - The name of the flag to add
+static inline void decorate1(FlagsConstantEmitter *(&operandFlags)[MAX_OPERANDS],
+ const CodeGenInstruction &inst,
+ const char *opName,
+ const char *opFlag) {
+ unsigned opIndex;
+
+ opIndex = inst.getOperandNamed(std::string(opName));
+
+ operandFlags[opIndex]->addEntry(opFlag);
+}
+
+#define DECORATE1(opName, opFlag) decorate1(operandFlags, inst, opName, opFlag)
+
+#define MOV(source, target) { \
+ instFlags.addEntry("kInstructionFlagMove"); \
+ DECORATE1(source, "kOperandFlagSource"); \
+ DECORATE1(target, "kOperandFlagTarget"); \
+}
+
+#define BRANCH(target) { \
+ instFlags.addEntry("kInstructionFlagBranch"); \
+ DECORATE1(target, "kOperandFlagTarget"); \
+}
+
+#define PUSH(source) { \
+ instFlags.addEntry("kInstructionFlagPush"); \
+ DECORATE1(source, "kOperandFlagSource"); \
+}
+
+#define POP(target) { \
+ instFlags.addEntry("kInstructionFlagPop"); \
+ DECORATE1(target, "kOperandFlagTarget"); \
+}
+
+#define CALL(target) { \
+ instFlags.addEntry("kInstructionFlagCall"); \
+ DECORATE1(target, "kOperandFlagTarget"); \
+}
+
+#define RETURN() { \
+ instFlags.addEntry("kInstructionFlagReturn"); \
+}
+
+/// X86ExtractSemantics - Performs various checks on the name of an X86
+/// instruction to determine what sort of an instruction it is and then adds
+/// the appropriate flags to the instruction and its operands
+///
+/// @arg instFlags - A reference to the flags for the instruction as a whole
+/// @arg operandFlags - A reference to the array of operand flag object pointers
+/// @arg inst - A reference to the original instruction
+static void X86ExtractSemantics(FlagsConstantEmitter &instFlags,
+ FlagsConstantEmitter *(&operandFlags)[MAX_OPERANDS],
+ const CodeGenInstruction &inst) {
+ const std::string &name = inst.TheDef->getName();
+
+ if (name.find("MOV") != name.npos) {
+ if (name.find("MOV_V") != name.npos) {
+ // ignore (this is a pseudoinstruction)
+ }
+ else if (name.find("MASK") != name.npos) {
+ // ignore (this is a masking move)
+ }
+ else if (name.find("r0") != name.npos) {
+ // ignore (this is a pseudoinstruction)
+ }
+ else if (name.find("PS") != name.npos ||
+ name.find("PD") != name.npos) {
+ // ignore (this is a shuffling move)
+ }
+ else if (name.find("MOVS") != name.npos) {
+ // ignore (this is a string move)
+ }
+ else if (name.find("_F") != name.npos) {
+ // TODO handle _F moves to ST(0)
+ }
+ else if (name.find("a") != name.npos) {
+ // TODO handle moves to/from %ax
+ }
+ else if (name.find("CMOV") != name.npos) {
+ MOV("src2", "dst");
+ }
+ else if (name.find("PC") != name.npos) {
+ MOV("label", "reg")
+ }
+ else {
+ MOV("src", "dst");
+ }
+ }
+
+ if (name.find("JMP") != name.npos ||
+ name.find("J") == 0) {
+ if (name.find("FAR") != name.npos && name.find("i") != name.npos) {
+ BRANCH("off");
+ }
+ else {
+ BRANCH("dst");
+ }
+ }
+
+ if (name.find("PUSH") != name.npos) {
+ if (name.find("FS") != name.npos ||
+ name.find("GS") != name.npos) {
+ instFlags.addEntry("kInstructionFlagPush");
+ // TODO add support for fixed operands
+ }
+ else if (name.find("F") != name.npos) {
+ // ignore (this pushes onto the FP stack)
+ }
+ else if (name[name.length() - 1] == 'm') {
+ PUSH("src");
+ }
+ else if (name.find("i") != name.npos) {
+ PUSH("imm");
+ }
+ else {
+ PUSH("reg");
+ }
+ }
+
+ if (name.find("POP") != name.npos) {
+ if (name.find("POPCNT") != name.npos) {
+ // ignore (not a real pop)
+ }
+ else if (name.find("FS") != name.npos ||
+ name.find("GS") != name.npos) {
+ instFlags.addEntry("kInstructionFlagPop");
+ // TODO add support for fixed operands
+ }
+ else if (name.find("F") != name.npos) {
+ // ignore (this pops from the FP stack)
+ }
+ else if (name[name.length() - 1] == 'm') {
+ POP("dst");
+ }
+ else {
+ POP("reg");
+ }
+ }
+
+ if (name.find("CALL") != name.npos) {
+ if (name.find("ADJ") != name.npos) {
+ // ignore (not a call)
+ }
+ else if (name.find("SYSCALL") != name.npos) {
+ // ignore (doesn't go anywhere we know about)
+ }
+ else if (name.find("VMCALL") != name.npos) {
+ // ignore (rather different semantics than a regular call)
+ }
+ else if (name.find("FAR") != name.npos && name.find("i") != name.npos) {
+ CALL("off");
+ }
+ else {
+ CALL("dst");
+ }
+ }
+
+ if (name.find("RET") != name.npos) {
+ RETURN();
+ }
+}
+
+#undef MOV
+#undef BRANCH
+#undef PUSH
+#undef POP
+#undef CALL
+#undef RETURN
+
+#undef COND_DECORATE_2
+#undef COND_DECORATE_1
+#undef DECORATE1
+
+/// populateInstInfo - Fills an array of InstInfos with information about each
+/// instruction in a target
+///
+/// @arg infoArray - The array of InstInfo objects to populate
+/// @arg target - The CodeGenTarget to use as a source of instructions
+static void populateInstInfo(CompoundConstantEmitter &infoArray,
+ CodeGenTarget &target) {
+ std::vector<const CodeGenInstruction*> numberedInstructions;
+ target.getInstructionsByEnumValue(numberedInstructions);
+
+ unsigned int index;
+ unsigned int numInstructions = numberedInstructions.size();
+
+ for (index = 0; index < numInstructions; ++index) {
+ const CodeGenInstruction& inst = *numberedInstructions[index];
+
+ CompoundConstantEmitter *infoStruct = new CompoundConstantEmitter;
+ infoArray.addEntry(infoStruct);
+
+ FlagsConstantEmitter *instFlags = new FlagsConstantEmitter;
+ infoStruct->addEntry(instFlags);
+
+ LiteralConstantEmitter *numOperandsEmitter =
+ new LiteralConstantEmitter(inst.OperandList.size());
+ infoStruct->addEntry(numOperandsEmitter);
+
+ CompoundConstantEmitter *operandFlagArray = new CompoundConstantEmitter;
+ infoStruct->addEntry(operandFlagArray);
+
+ FlagsConstantEmitter *operandFlags[MAX_OPERANDS];
+
+ for (unsigned operandIndex = 0; operandIndex < MAX_OPERANDS; ++operandIndex) {
+ operandFlags[operandIndex] = new FlagsConstantEmitter;
+ operandFlagArray->addEntry(operandFlags[operandIndex]);
+ }
+
+ unsigned numSyntaxes = 0;
+
+ if (target.getName() == "X86") {
+ X86PopulateOperands(operandFlags, inst);
+ X86ExtractSemantics(*instFlags, operandFlags, inst);
+ numSyntaxes = 2;
+ }
+
+ CompoundConstantEmitter *operandOrderArray = new CompoundConstantEmitter;
+ infoStruct->addEntry(operandOrderArray);
+
+ for (unsigned syntaxIndex = 0; syntaxIndex < MAX_SYNTAXES; ++syntaxIndex) {
+ CompoundConstantEmitter *operandOrder = new CompoundConstantEmitter;
+ operandOrderArray->addEntry(operandOrder);
+
+ if (syntaxIndex < numSyntaxes) {
+ populateOperandOrder(operandOrder, inst, syntaxIndex);
+ }
+ else {
+ for (unsigned operandIndex = 0;
+ operandIndex < MAX_OPERANDS;
+ ++operandIndex) {
+ operandOrder->addEntry(new LiteralConstantEmitter("-1"));
+ }
+ }
+ }
+ }
+}
+
+void EDEmitter::run(raw_ostream &o) {
+ unsigned int i = 0;
+
+ CompoundConstantEmitter infoArray;
+ CodeGenTarget target;
+
+ populateInstInfo(infoArray, target);
+
+ o << "InstInfo instInfo" << target.getName().c_str() << "[] = ";
+ infoArray.emit(o, i);
+ o << ";" << "\n";
+}
+
+void EDEmitter::runHeader(raw_ostream &o) {
+ EmitSourceFileHeader("Enhanced Disassembly Info Header", o);
+
+ o << "#ifndef EDInfo_" << "\n";
+ o << "#define EDInfo_" << "\n";
+ o << "\n";
+ o << "#include <inttypes.h>" << "\n";
+ o << "\n";
+ o << "#define MAX_OPERANDS " << format("%d", MAX_OPERANDS) << "\n";
+ o << "#define MAX_SYNTAXES " << format("%d", MAX_SYNTAXES) << "\n";
+ o << "\n";
+
+ unsigned int i = 0;
+
+ EnumEmitter operandFlags("OperandFlags");
+ operandFlags.addEntry("kOperandFlagImmediate");
+ operandFlags.addEntry("kOperandFlagRegister");
+ operandFlags.addEntry("kOperandFlagMemory");
+ operandFlags.addEntry("kOperandFlagEffectiveAddress");
+ operandFlags.addEntry("kOperandFlagPCRelative");
+ operandFlags.addEntry("kOperandFlagSource");
+ operandFlags.addEntry("kOperandFlagTarget");
+ operandFlags.emitAsFlags(o, i);
+
+ o << "\n";
+
+ EnumEmitter instructionFlags("InstructionFlags");
+ instructionFlags.addEntry("kInstructionFlagMove");
+ instructionFlags.addEntry("kInstructionFlagBranch");
+ instructionFlags.addEntry("kInstructionFlagPush");
+ instructionFlags.addEntry("kInstructionFlagPop");
+ instructionFlags.addEntry("kInstructionFlagCall");
+ instructionFlags.addEntry("kInstructionFlagReturn");
+ instructionFlags.emitAsFlags(o, i);
+
+ o << "\n";
+
+ StructEmitter instInfo("InstInfo");
+ instInfo.addMember("uint32_t", "instructionFlags");
+ instInfo.addMember("uint8_t", "numOperands");
+ instInfo.addMember("uint8_t", "operandFlags[MAX_OPERANDS]");
+ instInfo.addMember("const char", "operandOrders[MAX_SYNTAXES][MAX_OPERANDS]");
+ instInfo.emit(o, i);
+
+ o << "\n";
+ o << "#endif" << "\n";
+}
diff --git a/utils/TableGen/EDEmitter.h b/utils/TableGen/EDEmitter.h
new file mode 100644
index 0000000..9e40a8b
--- /dev/null
+++ b/utils/TableGen/EDEmitter.h
@@ -0,0 +1,37 @@
+//===- EDEmitter.h - Generate instruction descriptions for ED ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting a description of each
+// instruction in a format that the semantic disassembler can use to tokenize
+// and parse instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SEMANTIC_INFO_EMITTER_H
+#define SEMANTIC_INFO_EMITTER_H
+
+#include "TableGenBackend.h"
+
+namespace llvm {
+
+ class EDEmitter : public TableGenBackend {
+ RecordKeeper &Records;
+ public:
+ EDEmitter(RecordKeeper &R);
+
+ // run - Output the instruction table.
+ void run(raw_ostream &o);
+
+ // runHeader - Emit a header file that allows use of the instruction table.
+ void runHeader(raw_ostream &o);
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index cf40c78..898c92a 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -118,7 +118,20 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
Res += "|(1<<TOI::OptionalDef)";
// Fill in constraint info.
- Res += ", " + Inst.OperandList[i].Constraints[j];
+ Res += ", ";
+
+ const CodeGenInstruction::ConstraintInfo &Constraint =
+ Inst.OperandList[i].Constraints[j];
+ if (Constraint.isNone())
+ Res += "0";
+ else if (Constraint.isEarlyClobber())
+ Res += "(1 << TOI::EARLY_CLOBBER)";
+ else {
+ assert(Constraint.isTied());
+ Res += "((" + utostr(Constraint.getTiedOperand()) +
+ " << 16) | (1 << TOI::TIED_TO))";
+ }
+
Result.push_back(Res);
}
}
@@ -346,7 +359,7 @@ void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val,
R->getName() != "IMPLICIT_DEF" &&
R->getName() != "SUBREG_TO_REG" &&
R->getName() != "COPY_TO_REGCLASS" &&
- R->getName() != "DEBUG_VALUE")
+ R->getName() != "DBG_VALUE")
throw R->getName() + " doesn't have a field named '" +
Val->getValue() + "'!";
return;
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index 88fb6c3..2abc94b 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -116,7 +116,7 @@ bool IsDagEmpty (const DagInit& d) {
// EscapeVariableName - Escape commas and other symbols not allowed
// in the C++ variable names. Makes it possible to use options named
// like "Wa," (useful for prefix options).
-std::string EscapeVariableName(const std::string& Var) {
+std::string EscapeVariableName (const std::string& Var) {
std::string ret;
for (unsigned i = 0; i != Var.size(); ++i) {
char cur_char = Var[i];
@@ -136,6 +136,21 @@ std::string EscapeVariableName(const std::string& Var) {
return ret;
}
+/// EscapeQuotes - Replace '"' with '\"'.
+std::string EscapeQuotes (const std::string& Var) {
+ std::string ret;
+ for (unsigned i = 0; i != Var.size(); ++i) {
+ char cur_char = Var[i];
+ if (cur_char == '"') {
+ ret += "\\\"";
+ }
+ else {
+ ret.push_back(cur_char);
+ }
+ }
+ return ret;
+}
+
/// OneOf - Does the input string contain this character?
bool OneOf(const char* lst, char c) {
while (*lst) {
@@ -594,7 +609,7 @@ private:
void onHelp (const DagInit& d) {
CheckNumberOfArguments(d, 1);
- optDesc_.Help = InitPtrToString(d.getArg(0));
+ optDesc_.Help = EscapeQuotes(InitPtrToString(d.getArg(0)));
}
void onHidden (const DagInit& d) {
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index 7c8d288..f20ec00 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -22,6 +22,7 @@
#include "CodeEmitterGen.h"
#include "DAGISelEmitter.h"
#include "DisassemblerEmitter.h"
+#include "EDEmitter.h"
#include "FastISelEmitter.h"
#include "InstrEnumEmitter.h"
#include "InstrInfoEmitter.h"
@@ -58,6 +59,7 @@ enum ActionType {
GenIntrinsic,
GenTgtIntrinsic,
GenLLVMCConf,
+ GenEDHeader, GenEDInfo,
PrintEnums
};
@@ -106,6 +108,10 @@ namespace {
"Generate Clang diagnostic groups"),
clEnumValN(GenLLVMCConf, "gen-llvmc",
"Generate LLVMC configuration library"),
+ clEnumValN(GenEDHeader, "gen-enhanced-disassembly-header",
+ "Generate enhanced disassembly info header"),
+ clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info",
+ "Generate enhanced disassembly info"),
clEnumValN(PrintEnums, "print-enums",
"Print enum values for a class"),
clEnumValEnd));
@@ -259,6 +265,12 @@ int main(int argc, char **argv) {
case GenLLVMCConf:
LLVMCConfigurationEmitter(Records).run(*Out);
break;
+ case GenEDHeader:
+ EDEmitter(Records).runHeader(*Out);
+ break;
+ case GenEDInfo:
+ EDEmitter(Records).run(*Out);
+ break;
case PrintEnums:
{
std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp
index 2b6e30d..3843e56 100644
--- a/utils/TableGen/X86RecognizableInstr.cpp
+++ b/utils/TableGen/X86RecognizableInstr.cpp
@@ -24,6 +24,18 @@
using namespace llvm;
+#define MRM_MAPPING \
+ MAP(C1, 33) \
+ MAP(C2, 34) \
+ MAP(C3, 35) \
+ MAP(C4, 36) \
+ MAP(C8, 37) \
+ MAP(C9, 38) \
+ MAP(E8, 39) \
+ MAP(F0, 40) \
+ MAP(F8, 41) \
+ MAP(F9, 42)
+
// A clone of X86 since we can't depend on something that is generated.
namespace X86Local {
enum {
@@ -38,7 +50,12 @@ namespace X86Local {
MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31,
- MRMInitReg = 32
+ MRMInitReg = 32,
+
+#define MAP(from, to) MRM_##from = to,
+ MRM_MAPPING
+#undef MAP
+ lastMRM
};
enum {
@@ -47,10 +64,28 @@ namespace X86Local {
D8 = 3, D9 = 4, DA = 5, DB = 6,
DC = 7, DD = 8, DE = 9, DF = 10,
XD = 11, XS = 12,
- T8 = 13, TA = 14
+ T8 = 13, P_TA = 14,
+ P_0F_AE = 16, P_0F_01 = 17
};
}
-
+
+// If rows are added to the opcode extension tables, then corresponding entries
+// must be added here.
+//
+// If the row corresponds to a single byte (i.e., 8f), then add an entry for
+// that byte to ONE_BYTE_EXTENSION_TABLES.
+//
+// If the row corresponds to two bytes where the first is 0f, add an entry for
+// the second byte to TWO_BYTE_EXTENSION_TABLES.
+//
+// If the row corresponds to some other set of bytes, you will need to modify
+// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes
+// to the X86 TD files, except in two cases: if the first two bytes of such a
+// new combination are 0f 38 or 0f 3a, you just have to add maps called
+// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a
+// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line
+// in RecognizableInstr::emitDecodePath().
+
#define ONE_BYTE_EXTENSION_TABLES \
EXTENSION_TABLE(80) \
EXTENSION_TABLE(81) \
@@ -81,10 +116,6 @@ namespace X86Local {
EXTENSION_TABLE(b9) \
EXTENSION_TABLE(ba) \
EXTENSION_TABLE(c7)
-
-#define TWO_BYTE_FULL_EXTENSION_TABLES \
- EXTENSION_TABLE(01)
-
using namespace X86Disassembler;
@@ -402,13 +433,10 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
if (OperandList[operandIndex].Constraints.size()) {
- const std::string &constraint = OperandList[operandIndex].Constraints[0];
- std::string::size_type tiedToPos;
-
- if ((tiedToPos = constraint.find(" << 16) | (1 << TOI::TIED_TO))")) !=
- constraint.npos) {
- tiedToPos--;
- operandMapping[operandIndex] = constraint[tiedToPos] - '0';
+ const CodeGenInstruction::ConstraintInfo &Constraint =
+ OperandList[operandIndex].Constraints[0];
+ if (Constraint.isTied()) {
+ operandMapping[operandIndex] = Constraint.getTiedOperand();
} else {
++numPhysicalOperands;
operandMapping[operandIndex] = operandIndex;
@@ -552,36 +580,10 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
// Special cases where the LLVM tables are not complete
-#define EXACTCASE(class, name, lastbyte) \
- if (Name == name) { \
- tables.setTableFields(class, \
- insnContext(), \
- Opcode, \
- ExactFilter(lastbyte), \
- UID); \
- Spec->modifierBase = Opcode; \
- return; \
- }
-
- EXACTCASE(TWOBYTE, "MONITOR", 0xc8)
- EXACTCASE(TWOBYTE, "MWAIT", 0xc9)
- EXACTCASE(TWOBYTE, "SWPGS", 0xf8)
- EXACTCASE(TWOBYTE, "INVEPT", 0x80)
- EXACTCASE(TWOBYTE, "INVVPID", 0x81)
- EXACTCASE(TWOBYTE, "VMCALL", 0xc1)
- EXACTCASE(TWOBYTE, "VMLAUNCH", 0xc2)
- EXACTCASE(TWOBYTE, "VMRESUME", 0xc3)
- EXACTCASE(TWOBYTE, "VMXOFF", 0xc4)
-
- if (Name == "INVLPG") {
- tables.setTableFields(TWOBYTE,
- insnContext(),
- Opcode,
- ExtendedFilter(false, 7),
- UID);
- Spec->modifierBase = Opcode;
- return;
- }
+#define MAP(from, to) \
+ case X86Local::MRM_##from: \
+ filter = new ExactFilter(0x##from); \
+ break;
OpcodeType opcodeType = (OpcodeType)-1;
@@ -596,6 +598,12 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
opcodeType = TWOBYTE;
switch (Opcode) {
+ default:
+ if (needsModRMForDecode(Form))
+ filter = new ModFilter(isRegFormat(Form));
+ else
+ filter = new DumbFilter();
+ break;
#define EXTENSION_TABLE(n) case 0x##n:
TWO_BYTE_EXTENSION_TABLES
#undef EXTENSION_TABLE
@@ -622,16 +630,10 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
case X86Local::MRM7m:
filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
break;
+ MRM_MAPPING
} // switch (Form)
break;
- default:
- if (needsModRMForDecode(Form))
- filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
-
- break;
- } // switch (opcode)
+ } // switch (Opcode)
opcodeToSet = Opcode;
break;
case X86Local::T8:
@@ -642,7 +644,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
filter = new DumbFilter();
opcodeToSet = Opcode;
break;
- case X86Local::TA:
+ case X86Local::P_TA:
opcodeType = THREEBYTE_3A;
if (needsModRMForDecode(Form))
filter = new ModFilter(isRegFormat(Form));
@@ -699,6 +701,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
case X86Local::MRM7m:
filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
break;
+ MRM_MAPPING
} // switch (Form)
break;
case 0xd8:
@@ -763,6 +766,8 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
}
delete filter;
+
+#undef MAP
}
#define TYPE(str, type) if (s == str) return type;
diff --git a/utils/UpdateCMakeLists.pl b/utils/UpdateCMakeLists.pl
index 6d24d90..8f535145 100755
--- a/utils/UpdateCMakeLists.pl
+++ b/utils/UpdateCMakeLists.pl
@@ -68,7 +68,8 @@ sub UpdateCMake {
while(<IN>) {
if (!$foundLibrary) {
print OUT $_;
- if (/^add_clang_library\(/ || /^add_llvm_library\(/ || /^add_llvm_target\(/) {
+ if (/^add_clang_library\(/ || /^add_llvm_library\(/ || /^add_llvm_target\(/
+ || /^add_executable\(/) {
$foundLibrary = 1;
EmitCMakeList($dir);
}
diff --git a/utils/lit/lit/ShUtil.py b/utils/lit/lit/ShUtil.py
index c4bbb3d..c8f9332 100644
--- a/utils/lit/lit/ShUtil.py
+++ b/utils/lit/lit/ShUtil.py
@@ -66,7 +66,7 @@ class ShLexer:
return (tok[0], num)
elif c == '"':
self.eat()
- str += self.lex_arg_quoted('"')
+ str += self.lex_arg_quoted('"')
elif not self.win32Escapes and c == '\\':
# Outside of a string, '\\' escapes everything.
self.eat()
diff --git a/utils/lit/lit/TestFormats.py b/utils/lit/lit/TestFormats.py
index 5dfd54a..d87a467 100644
--- a/utils/lit/lit/TestFormats.py
+++ b/utils/lit/lit/TestFormats.py
@@ -9,13 +9,19 @@ class GoogleTest(object):
self.test_sub_dir = str(test_sub_dir)
self.test_suffix = str(test_suffix)
- def getGTestTests(self, path, litConfig):
+ def getGTestTests(self, path, litConfig, localConfig):
"""getGTestTests(path) - [name]
-
- Return the tests available in gtest executable."""
+
+ Return the tests available in gtest executable.
+
+ Args:
+ path: String path to a gtest executable
+ litConfig: LitConfig instance
+ localConfig: TestingConfig instance"""
try:
- lines = Util.capture([path, '--gtest_list_tests']).split('\n')
+ lines = Util.capture([path, '--gtest_list_tests'],
+ env=localConfig.environment).split('\n')
except:
litConfig.error("unable to discover google-tests in %r" % path)
raise StopIteration
@@ -52,7 +58,8 @@ class GoogleTest(object):
execpath = os.path.join(filepath, subfilename)
# Discover the tests in this executable.
- for name in self.getGTestTests(execpath, litConfig):
+ for name in self.getGTestTests(execpath, litConfig,
+ localConfig):
testPath = path_in_suite + (filename, subfilename, name)
yield Test.Test(testSuite, testPath, localConfig)
@@ -65,7 +72,8 @@ class GoogleTest(object):
testName = os.path.join(namePrefix, testName)
cmd = [testPath, '--gtest_filter=' + testName]
- out, err, exitCode = TestRunner.executeCommand(cmd)
+ out, err, exitCode = TestRunner.executeCommand(
+ cmd, env=test.config.environment)
if not exitCode:
return Test.PASS,''
@@ -79,6 +87,10 @@ class FileBasedTest(object):
litConfig, localConfig):
source_path = testSuite.getSourcePath(path_in_suite)
for filename in os.listdir(source_path):
+ # Ignore dot files.
+ if filename.startswith('.'):
+ continue
+
filepath = os.path.join(source_path, filename)
if not os.path.isdir(filepath):
base,ext = os.path.splitext(filename)
@@ -129,7 +141,8 @@ class OneCommandPerFileTest:
d not in localConfig.excludes)]
for filename in filenames:
- if (not self.pattern.match(filename) or
+ if (filename.startswith('.') or
+ not self.pattern.match(filename) or
filename in localConfig.excludes):
continue
diff --git a/utils/lit/lit/Util.py b/utils/lit/lit/Util.py
index 66c5e46..414b714 100644
--- a/utils/lit/lit/Util.py
+++ b/utils/lit/lit/Util.py
@@ -39,11 +39,12 @@ def mkdir_p(path):
if e.errno != errno.EEXIST:
raise
-def capture(args):
+def capture(args, env=None):
import subprocess
"""capture(command) - Run the given command (or argv list) in a shell and
return the standard output."""
- p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ env=env)
out,_ = p.communicate()
return out
diff --git a/utils/llvm.grm b/utils/llvm.grm
index 4499d4b..86a707a 100644
--- a/utils/llvm.grm
+++ b/utils/llvm.grm
@@ -161,6 +161,7 @@ FuncAttr ::= noreturn
| signext
| readnone
| readonly
+ | inlinehint
| noinline
| alwaysinline
| optsize
diff --git a/utils/unittest/UnitTestMain/Makefile b/utils/unittest/UnitTestMain/Makefile
index 7b49191..328d5e2 100644
--- a/utils/unittest/UnitTestMain/Makefile
+++ b/utils/unittest/UnitTestMain/Makefile
@@ -13,6 +13,7 @@ include $(LEVEL)/Makefile.config
LIBRARYNAME = UnitTestMain
BUILD_ARCHIVE = 1
+REQUIRES_RTTI = 1
CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include
CPP.Flags += $(NO_MISSING_FIELD_INITIALIZERS) $(NO_VARIADIC_MACROS)
diff --git a/utils/unittest/googletest/Makefile b/utils/unittest/googletest/Makefile
index 2d2c282..15bbf4e 100644
--- a/utils/unittest/googletest/Makefile
+++ b/utils/unittest/googletest/Makefile
@@ -13,6 +13,7 @@ include $(LEVEL)/Makefile.config
LIBRARYNAME = GoogleTest
BUILD_ARCHIVE = 1
+REQUIRES_RTTI = 1
CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include
CPP.Flags += $(NO_MISSING_FIELD_INITIALIZERS) $(NO_VARIADIC_MACROS)
diff --git a/utils/vim/llvm.vim b/utils/vim/llvm.vim
index 48a4c68..6e4a207 100644
--- a/utils/vim/llvm.vim
+++ b/utils/vim/llvm.vim
@@ -51,7 +51,7 @@ syn keyword llvmKeyword volatile fastcc coldcc cc ccc
syn keyword llvmKeyword x86_stdcallcc x86_fastcallcc
syn keyword llvmKeyword signext zeroext inreg sret nounwind noreturn
syn keyword llvmKeyword nocapture byval nest readnone readonly noalias
-syn keyword llvmKeyword noinline alwaysinline optsize ssp sspreq
+syn keyword llvmKeyword inlinehint noinline alwaysinline optsize ssp sspreq
syn keyword llvmKeyword noredzone noimplicitfloat naked
syn keyword llvmKeyword module asm align tail to
syn keyword llvmKeyword addrspace section alias sideeffect c gc
OpenPOWER on IntegriCloud